about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig3
-rw-r--r--.github/ISSUE_TEMPLATE/library_tracking_issue.md4
-rw-r--r--RELEASES.md10
-rw-r--r--compiler/rustc_ast/src/ast.rs4
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs6
-rw-r--r--compiler/rustc_ast/src/util/parser.rs4
-rw-r--r--compiler/rustc_ast/src/visit.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs7
-rw-r--r--compiler/rustc_ast_lowering/src/format.rs14
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs20
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs1
-rw-r--r--compiler/rustc_borrowck/src/consumers.rs9
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs171
-rw-r--r--compiler/rustc_borrowck/src/lib.rs30
-rw-r--r--compiler/rustc_borrowck/src/nll.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs7
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs48
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl3
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/offset_of.rs99
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs5
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs11
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs12
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/meth.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs77
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs6
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs12
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs9
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs5
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs5
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs53
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/memmap.rs3
-rw-r--r--compiler/rustc_data_structures/src/sip128.rs196
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr.rs10
-rw-r--r--compiler/rustc_driver_impl/src/pretty.rs14
-rw-r--r--compiler/rustc_errors/src/emitter.rs1
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs11
-rw-r--r--compiler/rustc_hir/src/hir.rs46
-rw-r--r--compiler/rustc_hir/src/intravisit.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs41
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs253
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs17
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl15
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs106
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs25
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs17
-rw-r--r--compiler/rustc_hir_typeck/src/mem_categorization.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs25
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs11
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs6
-rw-r--r--compiler/rustc_infer/src/infer/outlives/components.rs40
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs29
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs9
-rw-r--r--compiler/rustc_interface/src/passes.rs11
-rw-r--r--compiler/rustc_interface/src/tests.rs2
-rw-r--r--compiler/rustc_lint/src/builtin.rs6
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs21
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs34
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs10
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs21
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs3
-rw-r--r--compiler/rustc_middle/src/mir/graphviz.rs23
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs16
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs68
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs2
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs11
-rw-r--r--compiler/rustc_middle/src/mir/query.rs43
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs8
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs4
-rw-r--r--compiler/rustc_middle/src/mir/type_foldable.rs2
-rw-r--r--compiler/rustc_middle/src/query/keys.rs10
-rw-r--r--compiler/rustc_middle/src/query/mod.rs143
-rw-r--r--compiler/rustc_middle/src/thir.rs11
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs1
-rw-r--r--compiler/rustc_middle/src/ty/abstract_const.rs11
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs11
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs22
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs11
-rw-r--r--compiler/rustc_middle/src/ty/context.rs45
-rw-r--r--compiler/rustc_middle/src/ty/impls_ty.rs28
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs102
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs140
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs24
-rw-r--r--compiler/rustc_middle/src/ty/query.rs26
-rw-r--r--compiler/rustc_middle/src/ty/subst.rs85
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs12
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/expr/category.rs3
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs3
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs74
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs41
-rw-r--r--compiler/rustc_mir_build/src/lib.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs8
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs25
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/print.rs17
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs2
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs32
-rw-r--r--compiler/rustc_mir_transform/src/coverage/query.rs3
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs2
-rw-r--r--compiler/rustc_mir_transform/src/function_item_references.rs48
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs2
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs3
-rw-r--r--compiler/rustc_mir_transform/src/instcombine.rs21
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs118
-rw-r--r--compiler/rustc_mir_transform/src/separate_const_switch.rs3
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs14
-rw-r--r--compiler/rustc_mir_transform/src/simplify_branches.rs10
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/default.rs5
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs10
-rw-r--r--compiler/rustc_passes/src/dead.rs34
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs5
-rw-r--r--compiler/rustc_passes/src/liveness.rs5
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs1
-rw-r--r--compiler/rustc_query_impl/src/on_disk_cache.rs2
-rw-r--r--compiler/rustc_query_impl/src/profiling_support.rs33
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs25
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs9
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs1
-rw-r--r--compiler/rustc_session/src/options.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs22
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/body.rs10
-rw-r--r--compiler/rustc_span/src/lib.rs31
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs14
-rw-r--r--compiler/rustc_target/src/abi/mod.rs15
-rw-r--r--compiler/rustc_target/src/spec/apple_base.rs21
-rw-r--r--compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs1
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
-rw-r--r--compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs44
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs15
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs7
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs2
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs68
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs49
-rw-r--r--compiler/rustc_type_ir/src/sty.rs10
-rw-r--r--library/alloc/src/boxed/thin.rs10
-rw-r--r--library/alloc/src/fmt.rs2
-rw-r--r--library/alloc/src/vec/drain.rs6
-rw-r--r--library/alloc/src/vec/drain_filter.rs6
-rw-r--r--library/core/src/cmp.rs91
-rw-r--r--library/core/src/fmt/mod.rs77
-rw-r--r--library/core/src/fmt/rt.rs (renamed from library/core/src/fmt/rt/v1.rs)20
-rw-r--r--library/core/src/mem/mod.rs42
-rw-r--r--library/core/src/num/nonzero.rs19
-rw-r--r--library/core/src/slice/iter.rs8
-rw-r--r--library/core/src/slice/iter/macros.rs2
-rw-r--r--library/core/src/time.rs2
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/mem.rs190
-rw-r--r--library/core/tests/nonzero.rs18
-rw-r--r--library/proc_macro/src/bridge/mod.rs6
-rw-r--r--library/proc_macro/src/lib.rs8
-rw-r--r--library/std/src/io/impls.rs56
-rw-r--r--library/std/src/io/mod.rs6
-rw-r--r--library/std/src/sys/unsupported/io.rs2
-rw-r--r--src/bootstrap/Cargo.lock4
-rw-r--r--src/bootstrap/builder.rs4
-rw-r--r--src/bootstrap/compile.rs1
-rw-r--r--src/bootstrap/tool.rs33
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/rustc/src/platform-support/loongarch-linux.md2
-rw-r--r--src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md57
-rw-r--r--src/etc/installer/pkg/Distribution.xml2
-rw-r--r--src/etc/lldb_lookup.py2
-rw-r--r--src/etc/lldb_providers.py4
-rw-r--r--src/librustdoc/clean/utils.rs4
-rw-r--r--src/librustdoc/html/render/mod.rs1
-rw-r--r--src/librustdoc/html/render/print_item.rs118
-rw-r--r--src/librustdoc/html/render/type_layout.rs86
-rw-r--r--src/librustdoc/html/static/js/main.js11
-rw-r--r--src/librustdoc/html/static/js/search.js4
-rw-r--r--src/librustdoc/html/static/js/source-script.js2
-rw-r--r--src/librustdoc/html/templates/type_layout.html53
-rw-r--r--src/librustdoc/html/templates/type_layout_size.html12
m---------src/llvm-project0
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/eager_or_lazy.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs9
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs1
-rw-r--r--src/tools/clippy/src/driver.rs3
-rw-r--r--src/tools/compiletest/src/header.rs10
-rw-r--r--src/tools/compiletest/src/runtest.rs73
-rwxr-xr-xsrc/tools/linkchecker/linkcheck.sh26
-rw-r--r--src/tools/miri/tests/fail/const-ub-checks.stderr6
-rw-r--r--src/tools/miri/tests/fail/erroneous_const2.stderr14
-rw-r--r--src/tools/miri/tests/pass/track-alloc-1.rs6
-rw-r--r--src/tools/miri/tests/pass/track-alloc-1.stderr5
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs6
-rw-r--r--src/tools/rustfmt/src/expr.rs4
-rw-r--r--src/tools/rustfmt/src/utils.rs1
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
-rw-r--r--tests/codegen/intrinsics/transmute-niched.rs184
-rw-r--r--tests/codegen/intrinsics/transmute.rs8
-rw-r--r--tests/codegen/transmute-optimized.rs109
-rw-r--r--tests/codegen/transmute-scalar.rs14
-rw-r--r--tests/incremental/const-generics/change-const-param-gat.rs29
-rw-r--r--tests/incremental/const-generics/change-const-param-type.rs68
-rw-r--r--tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff43
-rw-r--r--tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff39
-rw-r--r--tests/mir-opt/const_prop/offset_of.rs49
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff2
-rw-r--r--tests/mir-opt/instcombine_duplicate_switch_targets_e2e.rs16
-rw-r--r--tests/mir-opt/instcombine_duplicate_switch_targets_e2e.ub_if_b.PreCodegen.after.mir27
-rw-r--r--tests/mir-opt/issue_99325.main.built.after.mir2
-rw-r--r--tests/run-make-fulldeps/obtain-borrowck/driver.rs9
-rw-r--r--tests/run-make/const-prop-lint/Makefile9
-rw-r--r--tests/run-make/const-prop-lint/input.rs5
-rw-r--r--tests/run-make/coverage-reports/expected_show_coverage.generics.txt10
-rw-r--r--tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs6
-rw-r--r--tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr54
-rw-r--r--tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs24
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs10
-rw-r--r--tests/ui/associated-types/issue-27901.rs (renamed from tests/ui/issues/issue-27901.rs)0
-rw-r--r--tests/ui/async-await/feature-self-return-type.stderr1
-rw-r--r--tests/ui/async-await/issue-61949-self-return-type.stderr1
-rw-r--r--tests/ui/async-await/issue-74047.stderr4
-rw-r--r--tests/ui/borrowck/issue-109271-pass-self-into-closure.fixed39
-rw-r--r--tests/ui/borrowck/issue-109271-pass-self-into-closure.rs39
-rw-r--r--tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr85
-rw-r--r--tests/ui/borrowck/issue-47646.rs (renamed from tests/ui/issues/issue-47646.rs)0
-rw-r--r--tests/ui/borrowck/issue-47646.stderr (renamed from tests/ui/issues/issue-47646.stderr)0
-rw-r--r--tests/ui/chalkify/bugs/async.stderr2
-rw-r--r--tests/ui/consts/auxiliary/foreign-generic-mismatch-with-const-arg.rs1
-rw-r--r--tests/ui/consts/const-eval/generic-slice.stderr4
-rw-r--r--tests/ui/consts/const-eval/issue-100878.rs2
-rw-r--r--tests/ui/consts/foreign-generic-mismatch-with-const-arg.rs8
-rw-r--r--tests/ui/consts/foreign-generic-mismatch-with-const-arg.stderr21
-rw-r--r--tests/ui/enum-discriminant/auxiliary/issue-41394.rs (renamed from tests/ui/issues/auxiliary/issue-41394.rs)0
-rw-r--r--tests/ui/enum-discriminant/issue-41394-rpass.rs (renamed from tests/ui/issues/issue-41394-rpass.rs)0
-rw-r--r--tests/ui/enum-discriminant/issue-41394.rs (renamed from tests/ui/issues/issue-41394.rs)0
-rw-r--r--tests/ui/enum-discriminant/issue-41394.stderr (renamed from tests/ui/issues/issue-41394.stderr)0
-rw-r--r--tests/ui/extenv/issue-110547.rs7
-rw-r--r--tests/ui/extenv/issue-110547.stderr29
-rw-r--r--tests/ui/generator/auto-trait-regions.drop_tracking.stderr12
-rw-r--r--tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr12
-rw-r--r--tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr12
-rw-r--r--tests/ui/generator/auto-trait-regions.stderr47
-rw-r--r--tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs5
-rw-r--r--tests/ui/generic-associated-types/missing-item-sugg.rs11
-rw-r--r--tests/ui/generic-associated-types/missing-item-sugg.stderr11
-rw-r--r--tests/ui/generics/auxiliary/foreign-generic-mismatch.rs3
-rw-r--r--tests/ui/generics/foreign-generic-mismatch.rs10
-rw-r--r--tests/ui/generics/foreign-generic-mismatch.stderr35
-rw-r--r--tests/ui/impl-trait/auto-trait-leak.stderr4
-rw-r--r--tests/ui/impl-trait/issue-108591.rs30
-rw-r--r--tests/ui/impl-trait/issue-108592.rs21
-rw-r--r--tests/ui/impl-trait/issue-36792.rs (renamed from tests/ui/issues/issue-36792.rs)0
-rw-r--r--tests/ui/issues/issue-33287.rs1
-rw-r--r--tests/ui/issues/issue-3344.stderr2
-rw-r--r--tests/ui/issues/issue-6458-1.rs8
-rw-r--r--tests/ui/issues/issue-6458-2.rs5
-rw-r--r--tests/ui/issues/issue-6458-2.stderr14
-rw-r--r--tests/ui/issues/issue-6458-3.rs6
-rw-r--r--tests/ui/issues/issue-6458-3.stderr14
-rw-r--r--tests/ui/issues/issue-6458-4.rs7
-rw-r--r--tests/ui/issues/issue-6458-4.stderr16
-rw-r--r--tests/ui/issues/issue-6458.rs14
-rw-r--r--tests/ui/issues/issue-6458.stderr14
-rw-r--r--tests/ui/lifetimes/issue-36744-without-calls.rs (renamed from tests/ui/issues/issue-36744-without-calls.rs)0
-rw-r--r--tests/ui/lifetimes/issue-69314.stderr2
-rw-r--r--tests/ui/lint/dead-code/offset-of-correct-param-env.rs42
-rw-r--r--tests/ui/lint/dead-code/offset-of.rs44
-rw-r--r--tests/ui/lint/dead-code/offset-of.stderr50
-rw-r--r--tests/ui/lint/issue-110573.rs12
-rw-r--r--tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs (renamed from tests/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs)0
-rw-r--r--tests/ui/macros/issue-26094.rs (renamed from tests/ui/issues/issue-26094.rs)0
-rw-r--r--tests/ui/macros/issue-26094.stderr (renamed from tests/ui/issues/issue-26094.stderr)0
-rw-r--r--tests/ui/macros/issue-69396-const-no-type-in-macro.rs (renamed from tests/ui/issues/issue-69396-const-no-type-in-macro.rs)0
-rw-r--r--tests/ui/macros/issue-69396-const-no-type-in-macro.stderr (renamed from tests/ui/issues/issue-69396-const-no-type-in-macro.stderr)0
-rw-r--r--tests/ui/macros/user-defined-macro-rules.rs (renamed from tests/ui/user-defined-macro-rules.rs)0
-rw-r--r--tests/ui/mir/validate/storage-live.stderr4
-rw-r--r--tests/ui/missing/missing-items/m2.stderr2
-rw-r--r--tests/ui/nll/user-annotations/adt-brace-enums.stderr4
-rw-r--r--tests/ui/nll/user-annotations/adt-brace-structs.stderr4
-rw-r--r--tests/ui/nll/user-annotations/adt-nullary-enums.stderr5
-rw-r--r--tests/ui/nll/user-annotations/adt-tuple-enums.stderr4
-rw-r--r--tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr9
-rw-r--r--tests/ui/nll/user-annotations/adt-tuple-struct.stderr4
-rw-r--r--tests/ui/nll/user-annotations/fns.stderr4
-rw-r--r--tests/ui/nll/user-annotations/method-call.stderr2
-rw-r--r--tests/ui/nll/user-annotations/method-ufcs-3.stderr2
-rw-r--r--tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs12
-rw-r--r--tests/ui/offset-of/auxiliary/offset-of-staged-api.rs33
-rw-r--r--tests/ui/offset-of/offset-of-arg-count.rs9
-rw-r--r--tests/ui/offset-of/offset-of-arg-count.stderr20
-rw-r--r--tests/ui/offset-of/offset-of-dst-field.rs33
-rw-r--r--tests/ui/offset-of/offset-of-dst-field.stderr27
-rw-r--r--tests/ui/offset-of/offset-of-enum.rs13
-rw-r--r--tests/ui/offset-of/offset-of-enum.stderr19
-rw-r--r--tests/ui/offset-of/offset-of-private.rs16
-rw-r--r--tests/ui/offset-of/offset-of-private.stderr9
-rw-r--r--tests/ui/offset-of/offset-of-unstable-with-feature.rs20
-rw-r--r--tests/ui/offset-of/offset-of-unstable.rs31
-rw-r--r--tests/ui/offset-of/offset-of-unstable.stderr79
-rw-r--r--tests/ui/polymorphization/generators.stderr12
-rw-r--r--tests/ui/polymorphization/predicates.stderr18
-rw-r--r--tests/ui/polymorphization/type_parameters/closures.stderr30
-rw-r--r--tests/ui/span/issue-23729.stderr2
-rw-r--r--tests/ui/span/issue-23827.stderr2
-rw-r--r--tests/ui/span/issue-24356.stderr2
-rw-r--r--tests/ui/static/issue-18118.stderr2
-rw-r--r--tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs16
-rw-r--r--tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed21
-rw-r--r--tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs21
-rw-r--r--tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr18
-rw-r--r--tests/ui/suggestions/missing-assoc-fn.stderr2
-rw-r--r--tests/ui/traits/issue-22384.rs (renamed from tests/ui/issues/issue-22384.rs)0
-rw-r--r--tests/ui/traits/issue-22384.stderr (renamed from tests/ui/issues/issue-22384.stderr)0
-rw-r--r--tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr2
342 files changed, 4290 insertions, 2274 deletions
diff --git a/.editorconfig b/.editorconfig
index 03aab32bfc6..d065fa46469 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -20,3 +20,6 @@ trim_trailing_whitespace = false
 
 [*.yml]
 indent_size = 2
+
+[Makefile]
+indent_style = tab
diff --git a/.github/ISSUE_TEMPLATE/library_tracking_issue.md b/.github/ISSUE_TEMPLATE/library_tracking_issue.md
index 91c06402ca1..934312662be 100644
--- a/.github/ISSUE_TEMPLATE/library_tracking_issue.md
+++ b/.github/ISSUE_TEMPLATE/library_tracking_issue.md
@@ -12,7 +12,7 @@ Tracking issues are for tracking a feature from implementation to stabilization.
 Make sure to include the relevant RFC for the feature if it has one.
 
 If the new feature is small, it may be fine to skip the RFC process. In that
-case, you can use use `issue = "none"` in your initial implementation PR. The
+case, you can use `issue = "none"` in your initial implementation PR. The
 reviewer will ask you to open a tracking issue if they agree your feature can be
 added without an RFC.
 -->
@@ -65,7 +65,7 @@ the rfcbot will ask all the team members to verify they agree with
 stabilization. Once enough members agree and there are no concerns, the final
 comment period begins: this issue will be marked as such and will be listed
 in the next This Week in Rust newsletter. If no blocking concerns are raised in
-that period of 10 days, a stabilzation PR can be opened by anyone.
+that period of 10 days, a stabilization PR can be opened by anyone.
 -->
 
 ### Unresolved Questions
diff --git a/RELEASES.md b/RELEASES.md
index b89178a6f68..699735de6fb 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -963,7 +963,7 @@ Compatibility Notes
 - [rustdoc: doctests are now run on unexported `macro_rules!` macros, matching other private items][96630]
 - [rustdoc: Remove .woff font files][96279]
 - [Enforce Copy bounds for repeat elements while considering lifetimes][95819]
-- [Windows: Fix potentinal unsoundness by aborting if `File` reads or writes cannot
+- [Windows: Fix potential unsoundness by aborting if `File` reads or writes cannot
   complete synchronously][95469].
 
 Internal Changes
@@ -1794,10 +1794,10 @@ Libraries
 - [impl Default, Copy, Clone for std::io::Sink and std::io::Empty][rust#86744]
 - [`impl From<[(K, V); N]>` for all collections.][rust#84111]
 - [Remove `P: Unpin` bound on impl Future for Pin.][rust#81363]
-- [Treat invalid environment variable names as non-existent.][rust#86183]
+- [Treat invalid environment variable names as nonexistent.][rust#86183]
   Previously, the environment functions would panic if given a variable name
   with an internal null character or equal sign (`=`). Now, these functions will
-  just treat such names as non-existent variables, since the OS cannot represent
+  just treat such names as nonexistent variables, since the OS cannot represent
   the existence of a variable with such a name.
 
 Stabilised APIs
@@ -1990,7 +1990,7 @@ Compatibility Notes
   kinds of errors could be categorised [into newer more specific `ErrorKind`
   variants][79965], and that they do not represent a user error.
 - [Using environment variable names with `process::Command` on Windows now
-  behaves as expected.][85270] Previously using envionment variables with
+  behaves as expected.][85270] Previously using environment variables with
   `Command` would cause them to be ASCII-uppercased.
 - [Rustdoc will now warn on using rustdoc lints that aren't prefixed
   with `rustdoc::`][86849]
@@ -6367,7 +6367,7 @@ eg. `static MINUTE: Duration = Duration::from_secs(60);`
 
 Cargo
 -----
-- [`cargo new` no longer removes `rust` or `rs` prefixs/suffixs.][cargo/5013]
+- [`cargo new` no longer removes `rust` or `rs` prefixes/suffixes.][cargo/5013]
 - [`cargo new` now defaults to creating a binary crate, instead of a
   library crate.][cargo/5029]
 
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index ab0409efb3b..1e4d3ba47f4 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1271,6 +1271,7 @@ impl Expr {
             ExprKind::Continue(..) => ExprPrecedence::Continue,
             ExprKind::Ret(..) => ExprPrecedence::Ret,
             ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
+            ExprKind::OffsetOf(..) => ExprPrecedence::OffsetOf,
             ExprKind::MacCall(..) => ExprPrecedence::Mac,
             ExprKind::Struct(..) => ExprPrecedence::Struct,
             ExprKind::Repeat(..) => ExprPrecedence::Repeat,
@@ -1469,6 +1470,9 @@ pub enum ExprKind {
     /// Output of the `asm!()` macro.
     InlineAsm(P<InlineAsm>),
 
+    /// Output of the `offset_of!()` macro.
+    OffsetOf(P<Ty>, P<[Ident]>),
+
     /// A macro invocation; pre-expansion.
     MacCall(P<MacCall>),
 
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 694d31d8f1f..99f1f4bd968 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1456,6 +1456,12 @@ pub fn noop_visit_expr<T: MutVisitor>(
         }
         ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm),
         ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt),
+        ExprKind::OffsetOf(container, fields) => {
+            vis.visit_ty(container);
+            for field in fields.iter_mut() {
+                vis.visit_ident(field);
+            }
+        }
         ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
         ExprKind::Struct(se) => {
             let StructExpr { qself, path, fields, rest } = se.deref_mut();
diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index 3893875e9a4..24b4bd8623f 100644
--- a/compiler/rustc_ast/src/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
@@ -269,6 +269,7 @@ pub enum ExprPrecedence {
     Index,
     Try,
     InlineAsm,
+    OffsetOf,
     Mac,
     FormatArgs,
 
@@ -335,7 +336,8 @@ impl ExprPrecedence {
             | ExprPrecedence::Try
             | ExprPrecedence::InlineAsm
             | ExprPrecedence::Mac
-            | ExprPrecedence::FormatArgs => PREC_POSTFIX,
+            | ExprPrecedence::FormatArgs
+            | ExprPrecedence::OffsetOf => PREC_POSTFIX,
 
             // Never need parens
             ExprPrecedence::Array
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index ac9b321b71c..8a6b5d5c905 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -909,6 +909,12 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
         ExprKind::Paren(subexpression) => visitor.visit_expr(subexpression),
         ExprKind::InlineAsm(asm) => visitor.visit_inline_asm(asm),
         ExprKind::FormatArgs(f) => visitor.visit_format_args(f),
+        ExprKind::OffsetOf(container, fields) => {
+            visitor.visit_ty(container);
+            for &field in fields {
+                visitor.visit_ident(field);
+            }
+        }
         ExprKind::Yield(optional_expression) => {
             walk_list!(visitor, visit_expr, optional_expression);
         }
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 0d212b3e130..6863100d9ba 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -289,6 +289,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm))
                 }
                 ExprKind::FormatArgs(fmt) => self.lower_format_args(e.span, fmt),
+                ExprKind::OffsetOf(container, fields) => hir::ExprKind::OffsetOf(
+                    self.lower_ty(
+                        container,
+                        &mut ImplTraitContext::Disallowed(ImplTraitPosition::OffsetOf),
+                    ),
+                    self.arena.alloc_from_iter(fields.iter().map(|&ident| self.lower_ident(ident))),
+                ),
                 ExprKind::Struct(se) => {
                     let rest = match &se.rest {
                         StructRest::Base(e) => Some(self.lower_expr(e)),
diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs
index c41bdc44093..ccf481cb9b3 100644
--- a/compiler/rustc_ast_lowering/src/format.rs
+++ b/compiler/rustc_ast_lowering/src/format.rs
@@ -220,19 +220,19 @@ fn make_argument<'hir>(
 /// Generates:
 ///
 /// ```text
-///     <core::fmt::rt::v1::Count>::Is(…)
+///     <core::fmt::rt::Count>::Is(…)
 /// ```
 ///
 /// or
 ///
 /// ```text
-///     <core::fmt::rt::v1::Count>::Param(…)
+///     <core::fmt::rt::Count>::Param(…)
 /// ```
 ///
 /// or
 ///
 /// ```text
-///     <core::fmt::rt::v1::Count>::Implied
+///     <core::fmt::rt::Count>::Implied
 /// ```
 fn make_count<'hir>(
     ctx: &mut LoweringContext<'_, 'hir>,
@@ -278,13 +278,13 @@ fn make_count<'hir>(
 /// Generates
 ///
 /// ```text
-///     <core::fmt::rt::v1::Argument::new(
+///     <core::fmt::rt::Placeholder::new(
 ///         …usize, // position
 ///         '…', // fill
-///         <core::fmt::rt::v1::Alignment>::…, // alignment
+///         <core::fmt::rt::Alignment>::…, // alignment
 ///         …u32, // flags
-///         <core::fmt::rt::v1::Count::…>, // width
-///         <core::fmt::rt::v1::Count::…>, // precision
+///         <core::fmt::rt::Count::…>, // width
+///         <core::fmt::rt::Count::…>, // precision
 ///     )
 /// ```
 fn make_format_spec<'hir>(
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index bfd9956b004..c969d709608 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -283,6 +283,7 @@ enum ImplTraitPosition {
     FieldTy,
     Cast,
     ImplSelf,
+    OffsetOf,
 }
 
 impl std::fmt::Display for ImplTraitPosition {
@@ -313,6 +314,7 @@ impl std::fmt::Display for ImplTraitPosition {
             ImplTraitPosition::FieldTy => "field types",
             ImplTraitPosition::Cast => "cast types",
             ImplTraitPosition::ImplSelf => "impl headers",
+            ImplTraitPosition::OffsetOf => "`offset_of!` params",
         };
 
         write!(f, "{name}")
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 776bf54244e..aeb0c762020 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -549,6 +549,26 @@ impl<'a> State<'a> {
                 self.end();
                 self.pclose();
             }
+            ast::ExprKind::OffsetOf(container, fields) => {
+                // FIXME: This should have its own syntax, distinct from a macro invocation.
+                self.word("offset_of!");
+                self.popen();
+                self.rbox(0, Inconsistent);
+                self.print_type(container);
+                self.word(",");
+                self.space();
+
+                if let Some((&first, rest)) = fields.split_first() {
+                    self.print_ident(first);
+
+                    for &field in rest {
+                        self.word(".");
+                        self.print_ident(field);
+                    }
+                }
+
+                self.end();
+            }
             ast::ExprKind::MacCall(m) => self.print_mac(m),
             ast::ExprKind::Paren(e) => {
                 self.popen();
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index 2bbb9618dbf..acca1a1477f 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -469,6 +469,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
     }
 
     #[rustc_lint_diagnostics]
+    #[track_caller]
     pub(crate) fn struct_span_err_with_code<S: Into<MultiSpan>>(
         &self,
         sp: S,
diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs
index cb1a6522223..cd200aaa277 100644
--- a/compiler/rustc_borrowck/src/consumers.rs
+++ b/compiler/rustc_borrowck/src/consumers.rs
@@ -6,7 +6,7 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_index::vec::IndexSlice;
 use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
 use rustc_middle::mir::Body;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::TyCtxt;
 
 pub use super::{
     facts::{AllFacts as PoloniusInput, RustcFacts},
@@ -28,12 +28,9 @@ pub use super::{
 ///     that shows how to do this at `tests/run-make/obtain-borrowck/`.
 ///
 /// *   Polonius is highly unstable, so expect regular changes in its signature or other details.
-pub fn get_body_with_borrowck_facts(
-    tcx: TyCtxt<'_>,
-    def: ty::WithOptConstParam<LocalDefId>,
-) -> BodyWithBorrowckFacts<'_> {
+pub fn get_body_with_borrowck_facts(tcx: TyCtxt<'_>, def: LocalDefId) -> BodyWithBorrowckFacts<'_> {
     let (input_body, promoted) = tcx.mir_promoted(def);
-    let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).build();
+    let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def)).build();
     let input_body: &Body<'_> = &input_body.borrow();
     let promoted: &IndexSlice<_, _> = &promoted.borrow();
     *super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap()
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index a4a3c738f47..2320901a053 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1,3 +1,5 @@
+use std::iter;
+
 use either::Either;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxIndexSet;
@@ -10,6 +12,7 @@ use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
 use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::ObligationCause;
+use rustc_middle::hir::nested_filter::OnlyBodies;
 use rustc_middle::mir::tcx::PlaceTy;
 use rustc_middle::mir::{
     self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
@@ -21,16 +24,14 @@ use rustc_middle::util::CallKind;
 use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::hygiene::DesugaringKind;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::{BytePos, Span, Symbol};
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::ObligationCtxt;
 
 use crate::borrow_set::TwoPhaseActivation;
 use crate::borrowck_errors;
-
 use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
-use crate::diagnostics::mutability_errors::mut_borrow_of_mutable_ref;
 use crate::diagnostics::{find_all_local_uses, CapturedMessageOpt};
 use crate::{
     borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
@@ -959,7 +960,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     &msg_borrow,
                     None,
                 );
-                self.suggest_binding_for_closure_capture_self(
+                self.suggest_binding_for_closure_capture_self(&mut err, &issued_spans);
+                self.suggest_using_closure_argument_instead_of_capture(
                     &mut err,
                     issued_borrow.borrowed_place,
                     &issued_spans,
@@ -982,6 +984,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     place,
                     issued_borrow.borrowed_place,
                 );
+                self.suggest_using_closure_argument_instead_of_capture(
+                    &mut err,
+                    issued_borrow.borrowed_place,
+                    &issued_spans,
+                );
                 err
             }
 
@@ -1268,22 +1275,160 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         }
     }
 
-    fn suggest_binding_for_closure_capture_self(
+    /// Suggest using closure argument instead of capture.
+    ///
+    /// For example:
+    /// ```ignore (illustrative)
+    /// struct S;
+    ///
+    /// impl S {
+    ///     fn call(&mut self, f: impl Fn(&mut Self)) { /* ... */ }
+    ///     fn x(&self) {}
+    /// }
+    ///
+    ///     let mut v = S;
+    ///     v.call(|this: &mut S| v.x());
+    /// //  ^\                    ^-- help: try using the closure argument: `this`
+    /// //    *-- error: cannot borrow `v` as mutable because it is also borrowed as immutable
+    /// ```
+    fn suggest_using_closure_argument_instead_of_capture(
         &self,
         err: &mut Diagnostic,
         borrowed_place: Place<'tcx>,
         issued_spans: &UseSpans<'tcx>,
     ) {
-        let UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return };
-        let hir = self.infcx.tcx.hir();
+        let &UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return };
+        let tcx = self.infcx.tcx;
+        let hir = tcx.hir();
 
-        // check whether the borrowed place is capturing `self` by mut reference
+        // Get the type of the local that we are trying to borrow
         let local = borrowed_place.local;
-        let Some(_) = self
-            .body
-            .local_decls
-            .get(local)
-            .map(|l| mut_borrow_of_mutable_ref(l, self.local_names[local])) else { return };
+        let local_ty = self.body.local_decls[local].ty;
+
+        // Get the body the error happens in
+        let Some(body_id) = hir.get(self.mir_hir_id()).body_id() else { return };
+
+        let body_expr = hir.body(body_id).value;
+
+        struct ClosureFinder<'hir> {
+            hir: rustc_middle::hir::map::Map<'hir>,
+            borrow_span: Span,
+            res: Option<(&'hir hir::Expr<'hir>, &'hir hir::Closure<'hir>)>,
+            /// The path expression with the `borrow_span` span
+            error_path: Option<(&'hir hir::Expr<'hir>, &'hir hir::QPath<'hir>)>,
+        }
+        impl<'hir> Visitor<'hir> for ClosureFinder<'hir> {
+            type NestedFilter = OnlyBodies;
+
+            fn nested_visit_map(&mut self) -> Self::Map {
+                self.hir
+            }
+
+            fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) {
+                if let hir::ExprKind::Path(qpath) = &ex.kind
+                    && ex.span == self.borrow_span
+                {
+                    self.error_path = Some((ex, qpath));
+                }
+
+                if let hir::ExprKind::Closure(closure) = ex.kind
+                    && ex.span.contains(self.borrow_span)
+                    // To support cases like `|| { v.call(|this| v.get()) }`
+                    // FIXME: actually support such cases (need to figure out how to move from the capture place to original local)
+                    && self.res.as_ref().map_or(true, |(prev_res, _)| prev_res.span.contains(ex.span))
+                {
+                    self.res = Some((ex, closure));
+                }
+
+                hir::intravisit::walk_expr(self, ex);
+            }
+        }
+
+        // Find the closure that most tightly wraps `capture_kind_span`
+        let mut finder =
+            ClosureFinder { hir, borrow_span: capture_kind_span, res: None, error_path: None };
+        finder.visit_expr(body_expr);
+        let Some((closure_expr, closure)) = finder.res else { return };
+
+        let typeck_results = tcx.typeck(self.mir_def_id());
+
+        // Check that the parent of the closure is a method call,
+        // with receiver matching with local's type (modulo refs)
+        let parent = hir.parent_id(closure_expr.hir_id);
+        if let hir::Node::Expr(parent) = hir.get(parent) {
+            if let hir::ExprKind::MethodCall(_, recv, ..) = parent.kind {
+                let recv_ty = typeck_results.expr_ty(recv);
+
+                if recv_ty.peel_refs() != local_ty {
+                    return;
+                }
+            }
+        }
+
+        // Get closure's arguments
+        let ty::Closure(_, substs) = typeck_results.expr_ty(closure_expr).kind() else { unreachable!() };
+        let sig = substs.as_closure().sig();
+        let tupled_params =
+            tcx.erase_late_bound_regions(sig.inputs().iter().next().unwrap().map_bound(|&b| b));
+        let ty::Tuple(params) = tupled_params.kind() else { return };
+
+        // Find the first argument with a matching type, get its name
+        let Some((_, this_name)) = params
+            .iter()
+            .zip(hir.body_param_names(closure.body))
+            .find(|(param_ty, name)|{
+                // FIXME: also support deref for stuff like `Rc` arguments
+                param_ty.peel_refs() == local_ty && name != &Ident::empty()
+            })
+            else { return };
+
+        let spans;
+        if let Some((_path_expr, qpath)) = finder.error_path
+            && let hir::QPath::Resolved(_, path) = qpath
+            && let hir::def::Res::Local(local_id) = path.res
+        {
+            // Find all references to the problematic variable in this closure body
+
+            struct VariableUseFinder {
+                local_id: hir::HirId,
+                spans: Vec<Span>,
+            }
+            impl<'hir> Visitor<'hir> for VariableUseFinder {
+                fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) {
+                    if let hir::ExprKind::Path(qpath) = &ex.kind
+                        && let hir::QPath::Resolved(_, path) = qpath
+                        && let hir::def::Res::Local(local_id) = path.res
+                        && local_id == self.local_id
+                    {
+                        self.spans.push(ex.span);
+                    }
+
+                    hir::intravisit::walk_expr(self, ex);
+                }
+            }
+
+            let mut finder = VariableUseFinder { local_id, spans: Vec::new() };
+            finder.visit_expr(hir.body(closure.body).value);
+
+            spans = finder.spans;
+        } else {
+            spans = vec![capture_kind_span];
+        }
+
+        err.multipart_suggestion(
+            "try using the closure argument",
+            iter::zip(spans, iter::repeat(this_name.to_string())).collect(),
+            Applicability::MaybeIncorrect,
+        );
+    }
+
+    fn suggest_binding_for_closure_capture_self(
+        &self,
+        err: &mut Diagnostic,
+        issued_spans: &UseSpans<'tcx>,
+    ) {
+        let UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return };
+        let hir = self.infcx.tcx.hir();
 
         struct ExpressionFinder<'hir> {
             capture_span: Span,
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index c67ad97c4ff..6a5a7e08d38 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -119,24 +119,12 @@ impl<'tcx> TyCtxtConsts<'tcx> {
 }
 
 pub fn provide(providers: &mut Providers) {
-    *providers = Providers {
-        mir_borrowck: |tcx, did| {
-            if let Some(def) = ty::WithOptConstParam::try_lookup(did, tcx) {
-                tcx.mir_borrowck_const_arg(def)
-            } else {
-                mir_borrowck(tcx, ty::WithOptConstParam::unknown(did))
-            }
-        },
-        mir_borrowck_const_arg: |tcx, (did, param_did)| {
-            mir_borrowck(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
-        },
-        ..*providers
-    };
+    *providers = Providers { mir_borrowck, ..*providers };
 }
 
-fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &BorrowCheckResult<'_> {
+fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
     let (input_body, promoted) = tcx.mir_promoted(def);
-    debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
+    debug!("run query mir_borrowck: {}", tcx.def_path_str(def.to_def_id()));
 
     if input_body.borrow().should_skip() {
         debug!("Skipping borrowck because of injected body");
@@ -150,7 +138,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor
         return tcx.arena.alloc(result);
     }
 
-    let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
+    let hir_owner = tcx.hir().local_def_id_to_hir_id(def).owner;
 
     let infcx =
         tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build();
@@ -167,19 +155,19 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor
 /// If `return_body_with_facts` is true, then return the body with non-erased
 /// region ids on which the borrow checking was performed together with Polonius
 /// facts.
-#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.with_opt_param().as_local().unwrap()), level = "debug")]
+#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")]
 fn do_mir_borrowck<'tcx>(
     infcx: &InferCtxt<'tcx>,
     input_body: &Body<'tcx>,
     input_promoted: &IndexSlice<Promoted, Body<'tcx>>,
     return_body_with_facts: bool,
 ) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
-    let def = input_body.source.with_opt_param().as_local().unwrap();
+    let def = input_body.source.def_id().expect_local();
     debug!(?def);
 
     let tcx = infcx.tcx;
     let infcx = BorrowckInferCtxt::new(infcx);
-    let param_env = tcx.param_env(def.did);
+    let param_env = tcx.param_env(def);
 
     let mut local_names = IndexVec::from_elem(None, &input_body.local_decls);
     for var_debug_info in &input_body.var_debug_info {
@@ -207,7 +195,7 @@ fn do_mir_borrowck<'tcx>(
         errors.set_tainted_by_errors(e);
     }
     let upvars: Vec<_> = tcx
-        .closure_captures(def.did)
+        .closure_captures(def)
         .iter()
         .map(|&captured_place| {
             let capture = captured_place.info.capture_kind;
@@ -249,7 +237,7 @@ fn do_mir_borrowck<'tcx>(
         .iterate_to_fixpoint()
         .into_results_cursor(&body);
 
-    let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def.did).is_fn_or_closure();
+    let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure();
     let borrow_set =
         Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data));
 
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 73b8765e57d..78bdf00a69c 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -61,7 +61,7 @@ pub(crate) fn replace_regions_in_mir<'tcx>(
     body: &mut Body<'tcx>,
     promoted: &mut IndexSlice<Promoted, Body<'tcx>>,
 ) -> UniversalRegions<'tcx> {
-    let def = body.source.with_opt_param().as_local().unwrap();
+    let def = body.source.def_id().expect_local();
 
     debug!(?def);
 
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 375eca1b29d..7cb0cec82c7 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -394,7 +394,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
                     self.cx.ascribe_user_type(
                         constant.literal.ty(),
                         UserType::TypeOf(
-                            uv.def.did,
+                            uv.def,
                             UserSubsts { substs: uv.substs, user_self_ty: None },
                         ),
                         locations.span(&self.cx.body),
@@ -1766,7 +1766,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             if let Some(uv) = maybe_uneval {
                 if uv.promoted.is_none() {
                     let tcx = self.tcx();
-                    let def_id = uv.def.def_id_for_type_of();
+                    let def_id = uv.def;
                     if tcx.def_kind(def_id) == DefKind::InlineConst {
                         let def_id = def_id.expect_local();
                         let predicates =
@@ -2306,7 +2306,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             Rvalue::AddressOf(..)
             | Rvalue::ThreadLocalRef(..)
             | Rvalue::Len(..)
-            | Rvalue::Discriminant(..) => {}
+            | Rvalue::Discriminant(..)
+            | Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => {}
         }
     }
 
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 74241f722a6..ef37c01cef8 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -226,7 +226,7 @@ impl<'tcx> UniversalRegions<'tcx> {
     /// known between those regions.
     pub fn new(
         infcx: &BorrowckInferCtxt<'_, 'tcx>,
-        mir_def: ty::WithOptConstParam<LocalDefId>,
+        mir_def: LocalDefId,
         param_env: ty::ParamEnv<'tcx>,
     ) -> Self {
         UniversalRegionsBuilder { infcx, mir_def, param_env }.build()
@@ -388,7 +388,7 @@ impl<'tcx> UniversalRegions<'tcx> {
 
 struct UniversalRegionsBuilder<'cx, 'tcx> {
     infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>,
-    mir_def: ty::WithOptConstParam<LocalDefId>,
+    mir_def: LocalDefId,
     param_env: ty::ParamEnv<'tcx>,
 }
 
@@ -417,12 +417,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         let mut indices = self.compute_indices(fr_static, defining_ty);
         debug!("build: indices={:?}", indices);
 
-        let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
+        let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.to_def_id());
 
         // If this is a 'root' body (not a closure/generator/inline const), then
         // there are no extern regions, so the local regions start at the same
         // position as the (empty) sub-list of extern regions
-        let first_local_index = if self.mir_def.did.to_def_id() == typeck_root_def_id {
+        let first_local_index = if self.mir_def.to_def_id() == typeck_root_def_id {
             first_extern_index
         } else {
             // If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing
@@ -433,7 +433,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             // }
             for_each_late_bound_region_in_recursive_scope(
                 self.infcx.tcx,
-                self.infcx.tcx.local_parent(self.mir_def.did),
+                self.infcx.tcx.local_parent(self.mir_def),
                 |r| {
                     debug!(?r);
                     if !indices.indices.contains_key(&r) {
@@ -462,13 +462,13 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
 
         let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
             FR,
-            self.mir_def.did,
+            self.mir_def,
             bound_inputs_and_output,
             &mut indices,
         );
         // Converse of above, if this is a function/closure then the late-bound regions declared on its
         // signature are local.
-        for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| {
+        for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def, |r| {
             debug!(?r);
             if !indices.indices.contains_key(&r) {
                 let region_vid = {
@@ -492,7 +492,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() {
                 let va_list_did = self.infcx.tcx.require_lang_item(
                     LangItem::VaList,
-                    Some(self.infcx.tcx.def_span(self.mir_def.did)),
+                    Some(self.infcx.tcx.def_span(self.mir_def)),
                 );
 
                 let reg_vid = self
@@ -544,11 +544,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
     /// see `DefiningTy` for details.
     fn defining_ty(&self) -> DefiningTy<'tcx> {
         let tcx = self.infcx.tcx;
-        let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
+        let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
 
-        match tcx.hir().body_owner_kind(self.mir_def.did) {
+        match tcx.hir().body_owner_kind(self.mir_def) {
             BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
-                let defining_ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity();
+                let defining_ty = tcx.type_of(self.mir_def).subst_identity();
 
                 debug!("defining_ty (pre-replacement): {:?}", defining_ty);
 
@@ -562,9 +562,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                     }
                     ty::FnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs),
                     _ => span_bug!(
-                        tcx.def_span(self.mir_def.did),
+                        tcx.def_span(self.mir_def),
                         "expected defining type for `{:?}`: `{:?}`",
-                        self.mir_def.did,
+                        self.mir_def,
                         defining_ty
                     ),
                 }
@@ -572,10 +572,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
 
             BodyOwnerKind::Const | BodyOwnerKind::Static(..) => {
                 let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
-                if self.mir_def.did.to_def_id() == typeck_root_def_id {
+                if self.mir_def.to_def_id() == typeck_root_def_id {
                     let substs =
                         self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_substs);
-                    DefiningTy::Const(self.mir_def.did.to_def_id(), substs)
+                    DefiningTy::Const(self.mir_def.to_def_id(), substs)
                 } else {
                     // FIXME this line creates a dependency between borrowck and typeck.
                     //
@@ -587,15 +587,15 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                     // below), so that `type_of(inline_const_def_id).substs(substs)` uses the
                     // proper type with NLL infer vars.
                     let ty = tcx
-                        .typeck(self.mir_def.did)
-                        .node_type(tcx.local_def_id_to_hir_id(self.mir_def.did));
+                        .typeck(self.mir_def)
+                        .node_type(tcx.local_def_id_to_hir_id(self.mir_def));
                     let substs = InlineConstSubsts::new(
                         tcx,
                         InlineConstSubstsParts { parent_substs: identity_substs, ty },
                     )
                     .substs;
                     let substs = self.infcx.replace_free_regions_with_nll_infer_vars(FR, substs);
-                    DefiningTy::InlineConst(self.mir_def.did.to_def_id(), substs)
+                    DefiningTy::InlineConst(self.mir_def.to_def_id(), substs)
                 }
             }
         }
@@ -611,7 +611,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         defining_ty: DefiningTy<'tcx>,
     ) -> UniversalRegionIndices<'tcx> {
         let tcx = self.infcx.tcx;
-        let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
+        let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
         let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
         let fr_substs = match defining_ty {
             DefiningTy::Closure(_, substs)
@@ -647,7 +647,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         let tcx = self.infcx.tcx;
         match defining_ty {
             DefiningTy::Closure(def_id, substs) => {
-                assert_eq!(self.mir_def.did.to_def_id(), def_id);
+                assert_eq!(self.mir_def.to_def_id(), def_id);
                 let closure_sig = substs.as_closure().sig();
                 let inputs_and_output = closure_sig.inputs_and_output();
                 let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
@@ -682,7 +682,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             }
 
             DefiningTy::Generator(def_id, substs, movability) => {
-                assert_eq!(self.mir_def.did.to_def_id(), def_id);
+                assert_eq!(self.mir_def.to_def_id(), def_id);
                 let resume_ty = substs.as_generator().resume_ty();
                 let output = substs.as_generator().return_ty();
                 let generator_ty = tcx.mk_generator(def_id, substs, movability);
@@ -700,14 +700,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             DefiningTy::Const(def_id, _) => {
                 // For a constant body, there are no inputs, and one
                 // "output" (the type of the constant).
-                assert_eq!(self.mir_def.did.to_def_id(), def_id);
-                let ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity();
+                assert_eq!(self.mir_def.to_def_id(), def_id);
+                let ty = tcx.type_of(self.mir_def).subst_identity();
                 let ty = indices.fold_to_region_vids(tcx, ty);
                 ty::Binder::dummy(tcx.mk_type_list(&[ty]))
             }
 
             DefiningTy::InlineConst(def_id, substs) => {
-                assert_eq!(self.mir_def.did.to_def_id(), def_id);
+                assert_eq!(self.mir_def.to_def_id(), def_id);
                 let ty = substs.as_inline_const().ty();
                 ty::Binder::dummy(tcx.mk_type_list(&[ty]))
             }
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index 83dc1ac50e5..fca6012a408 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -149,3 +149,6 @@ builtin_macros_format_pos_mismatch = {$n} positional {$n ->
     [one] argument
     *[more] arguments
     } in format string, but {$desc}
+builtin_macros_offset_of_expected_field = expected field
+
+builtin_macros_offset_of_expected_two_args = expected 2 arguments
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index c9e3cd486f8..090e00616fb 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -301,6 +301,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
             | ExprKind::If(_, _, _)
             | ExprKind::IncludedBytes(..)
             | ExprKind::InlineAsm(_)
+            | ExprKind::OffsetOf(_, _)
             | ExprKind::Let(_, _, _)
             | ExprKind::Lit(_)
             | ExprKind::Loop(_, _, _)
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 134d64ce9cc..8f86ef44aa3 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -45,6 +45,7 @@ mod format;
 mod format_foreign;
 mod global_allocator;
 mod log_syntax;
+mod offset_of;
 mod source_util;
 mod test;
 mod trace_macros;
@@ -92,6 +93,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
         line: source_util::expand_line,
         log_syntax: log_syntax::expand_log_syntax,
         module_path: source_util::expand_mod,
+        offset_of: offset_of::expand_offset_of,
         option_env: env::expand_option_env,
         core_panic: edition_panic::expand_panic,
         std_panic: edition_panic::expand_panic,
diff --git a/compiler/rustc_builtin_macros/src/offset_of.rs b/compiler/rustc_builtin_macros/src/offset_of.rs
new file mode 100644
index 00000000000..0ef3e000e41
--- /dev/null
+++ b/compiler/rustc_builtin_macros/src/offset_of.rs
@@ -0,0 +1,99 @@
+use rustc_ast as ast;
+use rustc_ast::ptr::P;
+use rustc_ast::token;
+use rustc_ast::tokenstream::TokenStream;
+use rustc_errors::PResult;
+use rustc_expand::base::{self, *};
+use rustc_macros::Diagnostic;
+use rustc_parse::parser::Parser;
+use rustc_span::{symbol::Ident, Span};
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_offset_of_expected_field)]
+struct ExpectedField {
+    #[primary_span]
+    span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_offset_of_expected_two_args)]
+struct ExpectedTwoArgs {
+    #[primary_span]
+    span: Span,
+}
+
+fn parse_field<'a>(cx: &ExtCtxt<'a>, p: &mut Parser<'a>) -> PResult<'a, Ident> {
+    let token = p.token.uninterpolate();
+    let field = match token.kind {
+        token::Ident(name, _) => Ident::new(name, token.span),
+        token::Literal(token::Lit { kind: token::Integer, symbol, suffix: None }) => {
+            Ident::new(symbol, token.span)
+        }
+        _ => return Err(cx.create_err(ExpectedField { span: p.token.span })),
+    };
+
+    p.bump();
+
+    Ok(field)
+}
+
+fn parse_args<'a>(
+    cx: &mut ExtCtxt<'a>,
+    sp: Span,
+    tts: TokenStream,
+) -> PResult<'a, (P<ast::Ty>, P<[Ident]>)> {
+    let mut p = cx.new_parser_from_tts(tts);
+
+    let container = p.parse_ty()?;
+
+    p.expect(&token::Comma)?;
+
+    if p.eat(&token::Eof) {
+        return Err(cx.create_err(ExpectedTwoArgs { span: sp }));
+    }
+
+    let mut fields = Vec::new();
+
+    loop {
+        let field = parse_field(cx, &mut p)?;
+        fields.push(field);
+
+        if p.eat(&token::Dot) {
+            continue;
+        }
+
+        p.eat(&token::Comma);
+
+        if !p.eat(&token::Eof) {
+            return Err(cx.create_err(ExpectedTwoArgs { span: sp }));
+        }
+
+        break;
+    }
+
+    Ok((container, fields.into()))
+}
+
+pub fn expand_offset_of<'cx>(
+    cx: &'cx mut ExtCtxt<'_>,
+    sp: Span,
+    tts: TokenStream,
+) -> Box<dyn base::MacResult + 'cx> {
+    match parse_args(cx, sp, tts) {
+        Ok((container, fields)) => {
+            let expr = P(ast::Expr {
+                id: ast::DUMMY_NODE_ID,
+                kind: ast::ExprKind::OffsetOf(container, fields),
+                span: sp,
+                attrs: ast::AttrVec::new(),
+                tokens: None,
+            });
+
+            MacEager::expr(expr)
+        }
+        Err(mut err) => {
+            err.emit();
+            DummyResult::any(sp)
+        }
+    }
+}
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index f5301f9f7f1..f481290583e 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -781,12 +781,15 @@ fn codegen_stmt<'tcx>(
                     let operand = operand.load_scalar(fx);
                     lval.write_cvalue(fx, CValue::by_val(operand, box_layout));
                 }
-                Rvalue::NullaryOp(null_op, ty) => {
+                Rvalue::NullaryOp(ref null_op, ty) => {
                     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(),
                         NullOp::AlignOf => layout.align.abi.bytes(),
+                        NullOp::OffsetOf(fields) => {
+                            layout.offset_of_subfield(fx, fields.iter().map(|f| f.index())).bytes()
+                        }
                     };
                     let val = CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into());
                     lval.write_cvalue(fx, val);
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index e87f4e25891..aacf37bb5b7 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -91,7 +91,7 @@ pub(crate) fn eval_mir_constant<'tcx>(
             ),
         },
         ConstantKind::Unevaluated(mir::UnevaluatedConst { def, .. }, _)
-            if fx.tcx.is_static(def.did) =>
+            if fx.tcx.is_static(def) =>
         {
             span_bug!(constant.span, "MIR constant refers to static");
         }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 21a0a60b012..25fe3cb265d 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -29,7 +29,6 @@ use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_middle::bug;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
-use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{
     self, AdtKind, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt, Visibility,
 };
@@ -1182,12 +1181,12 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
             let names = get_parameter_names(cx, generics);
             let template_params: SmallVec<_> = iter::zip(substs, names)
                 .filter_map(|(kind, name)| {
-                    if let GenericArgKind::Type(ty) = kind.unpack() {
+                    kind.as_type().map(|ty| {
                         let actual_type =
                             cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
                         let actual_type_di_node = type_di_node(cx, actual_type);
                         let name = name.as_str();
-                        Some(unsafe {
+                        unsafe {
                             llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
                                 DIB(cx),
                                 None,
@@ -1195,10 +1194,8 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
                                 name.len(),
                                 actual_type_di_node,
                             )
-                        })
-                    } else {
-                        None
-                    }
+                        }
+                    })
                 })
                 .collect();
 
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 56844c7951f..dfc226db57b 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -27,7 +27,7 @@ use rustc_hir::def_id::{DefId, DefIdMap};
 use rustc_index::vec::IndexVec;
 use rustc_middle::mir;
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
+use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt};
 use rustc_session::config::{self, DebugInfo};
 use rustc_session::Session;
@@ -461,12 +461,12 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                 let names = get_parameter_names(cx, generics);
                 iter::zip(substs, names)
                     .filter_map(|(kind, name)| {
-                        if let GenericArgKind::Type(ty) = kind.unpack() {
+                        kind.as_type().map(|ty| {
                             let actual_type =
                                 cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
                             let actual_type_metadata = type_di_node(cx, actual_type);
                             let name = name.as_str();
-                            Some(unsafe {
+                            unsafe {
                                 Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
                                     DIB(cx),
                                     None,
@@ -474,10 +474,8 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                                     name.len(),
                                     actual_type_metadata,
                                 ))
-                            })
-                        } else {
-                            None
-                        }
+                            }
+                        })
                     })
                     .collect()
             } else {
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index d0fd3cd7666..8f2f829c17c 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -333,7 +333,7 @@ fn exported_symbols_provider_local(
             match *mono_item {
                 MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => {
                     if substs.non_erasable_generics().next().is_some() {
-                        let symbol = ExportedSymbol::Generic(def.did, substs);
+                        let symbol = ExportedSymbol::Generic(def, substs);
                         symbols.push((
                             symbol,
                             SymbolExportInfo {
diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs
index 2421acab471..81b49afb883 100644
--- a/compiler/rustc_codegen_ssa/src/meth.rs
+++ b/compiler/rustc_codegen_ssa/src/meth.rs
@@ -67,10 +67,10 @@ impl<'a, 'tcx> VirtualIndex {
 /// ref of the type.
 fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> {
     for arg in ty.peel_refs().walk() {
-        if let GenericArgKind::Type(ty) = arg.unpack() {
-            if let ty::Dynamic(data, _, _) = ty.kind() {
-                return data.principal().expect("expected principal trait object");
-            }
+        if let GenericArgKind::Type(ty) = arg.unpack()
+            && let ty::Dynamic(data, _, _) = ty.kind()
+        {
+            return data.principal().expect("expected principal trait object");
         }
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index d88226f5db0..94de19a9c29 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -12,6 +12,7 @@ use rustc_middle::mir::Operand;
 use rustc_middle::ty::cast::{CastTy, IntTy};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt};
+use rustc_session::config::OptLevel;
 use rustc_span::source_map::{Span, DUMMY_SP};
 use rustc_target::abi::{self, FIRST_VARIANT};
 
@@ -231,10 +232,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         (ScalarOrZst::Scalar(in_scalar), ScalarOrZst::Scalar(out_scalar))
                             if in_scalar.size(self.cx) == out_scalar.size(self.cx) =>
                         {
+                            let operand_bty = bx.backend_type(operand.layout);
                             let cast_bty = bx.backend_type(cast);
-                            Some(OperandValue::Immediate(
-                                self.transmute_immediate(bx, imm, in_scalar, out_scalar, cast_bty),
-                            ))
+                            Some(OperandValue::Immediate(self.transmute_immediate(
+                                bx,
+                                imm,
+                                in_scalar,
+                                operand_bty,
+                                out_scalar,
+                                cast_bty,
+                            )))
                         }
                         _ => None,
                     }
@@ -250,11 +257,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     && in_a.size(self.cx) == out_a.size(self.cx)
                     && in_b.size(self.cx) == out_b.size(self.cx)
                 {
+                    let in_a_ibty = bx.scalar_pair_element_backend_type(operand.layout, 0, false);
+                    let in_b_ibty = bx.scalar_pair_element_backend_type(operand.layout, 1, false);
                     let out_a_ibty = bx.scalar_pair_element_backend_type(cast, 0, false);
                     let out_b_ibty = bx.scalar_pair_element_backend_type(cast, 1, false);
                     Some(OperandValue::Pair(
-                        self.transmute_immediate(bx, imm_a, in_a, out_a, out_a_ibty),
-                        self.transmute_immediate(bx, imm_b, in_b, out_b, out_b_ibty),
+                        self.transmute_immediate(bx, imm_a, in_a, in_a_ibty, out_a, out_a_ibty),
+                        self.transmute_immediate(bx, imm_b, in_b, in_b_ibty, out_b, out_b_ibty),
                     ))
                 } else {
                     None
@@ -273,6 +282,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         bx: &mut Bx,
         mut imm: Bx::Value,
         from_scalar: abi::Scalar,
+        from_backend_ty: Bx::Type,
         to_scalar: abi::Scalar,
         to_backend_ty: Bx::Type,
     ) -> Bx::Value {
@@ -280,6 +290,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         use abi::Primitive::*;
         imm = bx.from_immediate(imm);
+
+        // When scalars are passed by value, there's no metadata recording their
+        // valid ranges. For example, `char`s are passed as just `i32`, with no
+        // way for LLVM to know that they're 0x10FFFF at most. Thus we assume
+        // the range of the input value too, not just the output range.
+        self.assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
+
         imm = match (from_scalar.primitive(), to_scalar.primitive()) {
             (Int(..) | F32 | F64, Int(..) | F32 | F64) => bx.bitcast(imm, to_backend_ty),
             (Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty),
@@ -294,10 +311,55 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 bx.bitcast(int_imm, to_backend_ty)
             }
         };
+        self.assume_scalar_range(bx, imm, to_scalar, to_backend_ty);
         imm = bx.to_immediate_scalar(imm, to_scalar);
         imm
     }
 
+    fn assume_scalar_range(
+        &self,
+        bx: &mut Bx,
+        imm: Bx::Value,
+        scalar: abi::Scalar,
+        backend_ty: Bx::Type,
+    ) {
+        if matches!(self.cx.sess().opts.optimize, OptLevel::No | OptLevel::Less)
+            // For now, the critical niches are all over `Int`eger values.
+            // Should floating-point values or pointers ever get more complex
+            // niches, then this code will probably want to handle them too.
+            || !matches!(scalar.primitive(), abi::Primitive::Int(..))
+            || scalar.is_always_valid(self.cx)
+        {
+            return;
+        }
+
+        let abi::WrappingRange { start, end } = scalar.valid_range(self.cx);
+
+        if start <= end {
+            if start > 0 {
+                let low = bx.const_uint_big(backend_ty, start);
+                let cmp = bx.icmp(IntPredicate::IntUGE, imm, low);
+                bx.assume(cmp);
+            }
+
+            let type_max = scalar.size(self.cx).unsigned_int_max();
+            if end < type_max {
+                let high = bx.const_uint_big(backend_ty, end);
+                let cmp = bx.icmp(IntPredicate::IntULE, imm, high);
+                bx.assume(cmp);
+            }
+        } else {
+            let low = bx.const_uint_big(backend_ty, start);
+            let cmp_low = bx.icmp(IntPredicate::IntUGE, imm, low);
+
+            let high = bx.const_uint_big(backend_ty, end);
+            let cmp_high = bx.icmp(IntPredicate::IntULE, imm, high);
+
+            let or = bx.or(cmp_low, cmp_high);
+            bx.assume(or);
+        }
+    }
+
     pub fn codegen_rvalue_unsized(
         &mut self,
         bx: &mut Bx,
@@ -604,13 +666,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }
             }
 
-            mir::Rvalue::NullaryOp(null_op, ty) => {
+            mir::Rvalue::NullaryOp(ref null_op, ty) => {
                 let ty = self.monomorphize(ty);
                 assert!(bx.cx().type_is_sized(ty));
                 let layout = bx.cx().layout_of(ty);
                 let val = match null_op {
                     mir::NullOp::SizeOf => layout.size.bytes(),
                     mir::NullOp::AlignOf => layout.align.abi.bytes(),
+                    mir::NullOp::OffsetOf(fields) => {
+                        layout.offset_of_subfield(bx.cx(), fields.iter().map(|f| f.index())).bytes()
+                    }
                 };
                 let val = bx.cx().const_usize(val);
                 let tcx = self.cx.tcx();
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 4bd6fe19931..99f180f475d 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -296,12 +296,12 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
     }
 
     let cid = key.value;
-    let def = cid.instance.def.with_opt_param();
-    let is_static = tcx.is_static(def.did);
+    let def = cid.instance.def.def_id();
+    let is_static = tcx.is_static(def);
 
     let mut ecx = InterpCx::new(
         tcx,
-        tcx.def_span(def.did),
+        tcx.def_span(def),
         key.param_env,
         // Statics (and promoteds inside statics) may access other statics, because unlike consts
         // they do not have to behave "as if" they were evaluated at runtime.
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index a5dfd1072f0..814b67b46ec 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -375,9 +375,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
     ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
         match instance {
             ty::InstanceDef::Item(def) => {
-                if ecx.tcx.is_ctfe_mir_available(def.did) {
-                    Ok(ecx.tcx.mir_for_ctfe_opt_const_arg(def))
-                } else if ecx.tcx.def_kind(def.did) == DefKind::AssocConst {
+                if ecx.tcx.is_ctfe_mir_available(def) {
+                    Ok(ecx.tcx.mir_for_ctfe(def))
+                } else if ecx.tcx.def_kind(def) == DefKind::AssocConst {
                     let guar = ecx.tcx.sess.delay_span_bug(
                         rustc_span::DUMMY_SP,
                         "This is likely a const item that is missing from its impl",
@@ -386,7 +386,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
                 } else {
                     // `find_mir_or_eval_fn` checks that this is a const fn before even calling us,
                     // so this should be unreachable.
-                    let path = ecx.tcx.def_path_str(def.did);
+                    let path = ecx.tcx.def_path_str(def);
                     bug!("trying to call extern function `{path}` at compile-time");
                 }
             }
@@ -410,9 +410,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
             // Execution might have wandered off into other crates, so we cannot do a stability-
             // sensitive check here. But we can at least rule out functions that are not const
             // at all.
-            if !ecx.tcx.is_const_fn_raw(def.did) {
+            if !ecx.tcx.is_const_fn_raw(def) {
                 // allow calling functions inside a trait marked with #[const_trait].
-                if !ecx.tcx.is_const_default_method(def.did) {
+                if !ecx.tcx.is_const_default_method(def) {
                     // We certainly do *not* want to actually call the fn
                     // though, so be sure we return here.
                     throw_unsup_format!("calling non-const function `{}`", instance)
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index b5b5cc4f196..6030498e946 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -461,10 +461,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         instance: ty::InstanceDef<'tcx>,
         promoted: Option<mir::Promoted>,
     ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
-        let def = instance.with_opt_param();
         trace!("load mir(instance={:?}, promoted={:?})", instance, promoted);
         let body = if let Some(promoted) = promoted {
-            &self.tcx.promoted_mir_opt_const_arg(def)[promoted]
+            let def = instance.def_id();
+            &self.tcx.promoted_mir(def)[promoted]
         } else {
             M::load_mir(self, instance)?
         };
@@ -502,13 +502,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// The `substs` are assumed to already be in our interpreter "universe" (param_env).
     pub(super) fn resolve(
         &self,
-        def: ty::WithOptConstParam<DefId>,
+        def: DefId,
         substs: SubstsRef<'tcx>,
     ) -> InterpResult<'tcx, ty::Instance<'tcx>> {
         trace!("resolve: {:?}, {:#?}", def, substs);
         trace!("param_env: {:#?}", self.param_env);
         trace!("substs: {:#?}", substs);
-        match ty::Instance::resolve_opt_const_arg(*self.tcx, self.param_env, def, substs) {
+        match ty::Instance::resolve(*self.tcx, self.param_env, def, substs) {
             Ok(Some(instance)) => Ok(instance),
             Ok(None) => throw_inval!(TooGeneric),
 
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 9a366364e76..4d3a1193508 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -280,20 +280,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.write_immediate(*val, &dest)?;
             }
 
-            NullaryOp(null_op, ty) => {
+            NullaryOp(ref null_op, ty) => {
                 let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?;
                 let layout = self.layout_of(ty)?;
-                if layout.is_unsized() {
+                if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op && layout.is_unsized() {
                     // FIXME: This should be a span_bug (#80742)
                     self.tcx.sess.delay_span_bug(
                         self.frame().current_span(),
-                        &format!("Nullary MIR operator called for unsized type {}", ty),
+                        &format!("{null_op:?} MIR operator called for unsized type {ty}"),
                     );
                     throw_inval!(SizeOfUnsizedType(ty));
                 }
                 let val = match null_op {
                     mir::NullOp::SizeOf => layout.size.bytes(),
                     mir::NullOp::AlignOf => layout.align.abi.bytes(),
+                    mir::NullOp::OffsetOf(fields) => {
+                        layout.offset_of_subfield(self, fields.iter().map(|f| f.index())).bytes()
+                    }
                 };
                 self.write_scalar(Scalar::from_target_usize(val, self), &dest)?;
             }
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index a07702f7d9b..df387920010 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -83,8 +83,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         (fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false)
                     }
                     ty::FnDef(def_id, substs) => {
-                        let instance =
-                            self.resolve(ty::WithOptConstParam::unknown(def_id), substs)?;
+                        let instance = self.resolve(def_id, substs)?;
                         (
                             FnVal::Instance(instance),
                             self.fn_abi_of_instance(instance, extra_args)?,
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index bf2b4ee69ab..7cb19744987 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -36,7 +36,7 @@ where
                 ty::Closure(def_id, substs)
                 | ty::Generator(def_id, substs, ..)
                 | ty::FnDef(def_id, substs) => {
-                    let instance = ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id));
+                    let instance = ty::InstanceDef::Item(def_id);
                     let unused_params = self.tcx.unused_generic_params(instance);
                     for (index, subst) in substs.into_iter().enumerate() {
                         let index = index
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 9dad9479053..696c4517700 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -558,7 +558,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
 
             Rvalue::Cast(_, _, _) => {}
 
-            Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
+            Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) => {}
             Rvalue::ShallowInitBox(_, _) => {}
 
             Rvalue::UnaryOp(_, operand) => {
@@ -874,7 +874,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     debug!("Resolving ({:?}) -> {:?}", callee, instance);
                     if let Ok(Some(func)) = instance {
                         if let InstanceDef::Item(def) = func.def {
-                            callee = def.did;
+                            callee = def;
                         }
                     }
                 }
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 6758cba2eed..bf688f2b34e 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -364,9 +364,8 @@ where
         assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
 
         // Don't peek inside trait associated constants.
-        if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() {
-            assert_eq!(def.const_param_did, None, "expected associated const: {def:?}");
-            let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def.did);
+        if promoted.is_none() && cx.tcx.trait_of_item(def).is_none() {
+            let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def);
 
             if !Q::in_qualifs(&qualifs) {
                 return false;
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index 7919aed097a..e978e344283 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -514,6 +514,7 @@ impl<'tcx> Validator<'_, 'tcx> {
             Rvalue::NullaryOp(op, _) => match op {
                 NullOp::SizeOf => {}
                 NullOp::AlignOf => {}
+                NullOp::OffsetOf(_) => {}
             },
 
             Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable),
@@ -828,7 +829,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
     }
 
     fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> Body<'tcx> {
-        let def = self.source.source.with_opt_param();
+        let def = self.source.source.def_id();
         let mut rvalue = {
             let promoted = &mut self.promoted;
             let promoted_id = Promoted::new(next_promoted_id);
@@ -836,7 +837,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
             let mut promoted_operand = |ty, span| {
                 promoted.span = span;
                 promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
-                let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did));
+                let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def));
                 let uneval = mir::UnevaluatedConst { def, substs, promoted: Some(promoted_id) };
 
                 Operand::Constant(Box::new(Constant {
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 8aee019e994..9ab2b13d9d1 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -8,9 +8,10 @@ use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::{
     traversal, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, Local, Location,
-    MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, ProjectionElem,
-    RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
-    TerminatorKind, UnOp, UnwindAction, VarDebugInfo, VarDebugInfoContents, START_BLOCK,
+    MirPass, MirPhase, NonDivergingIntrinsic, NullOp, Operand, Place, PlaceElem, PlaceRef,
+    ProjectionElem, RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind,
+    Terminator, TerminatorKind, UnOp, UnwindAction, VarDebugInfo, VarDebugInfoContents,
+    START_BLOCK,
 };
 use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
 use rustc_mir_dataflow::impls::MaybeStorageLive;
@@ -711,10 +712,54 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     }
                 }
             }
+            Rvalue::NullaryOp(NullOp::OffsetOf(fields), container) => {
+                let fail_out_of_bounds = |this: &Self, location, field, ty| {
+                    this.fail(location, format!("Out of bounds field {field:?} for {ty:?}"));
+                };
+
+                let mut current_ty = *container;
+
+                for field in fields.iter() {
+                    match current_ty.kind() {
+                        ty::Tuple(fields) => {
+                            let Some(&f_ty) = fields.get(field.as_usize()) else {
+                                fail_out_of_bounds(self, location, field, current_ty);
+                                return;
+                            };
+
+                            current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
+                        }
+                        ty::Adt(adt_def, substs) => {
+                            if adt_def.is_enum() {
+                                self.fail(
+                                    location,
+                                    format!("Cannot get field offset from enum {current_ty:?}"),
+                                );
+                                return;
+                            }
+
+                            let Some(field) = adt_def.non_enum_variant().fields.get(field) else {
+                                fail_out_of_bounds(self, location, field, current_ty);
+                                return;
+                            };
+
+                            let f_ty = field.ty(self.tcx, substs);
+                            current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
+                        }
+                        _ => {
+                            self.fail(
+                                location,
+                                format!("Cannot get field offset from non-adt type {current_ty:?}"),
+                            );
+                            return;
+                        }
+                    }
+                }
+            }
             Rvalue::Repeat(_, _)
             | Rvalue::ThreadLocalRef(_)
             | Rvalue::AddressOf(_, _)
-            | Rvalue::NullaryOp(_, _)
+            | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _)
             | Rvalue::Discriminant(_) => {}
         }
         self.super_rvalue(rvalue, location);
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 405ae99395b..426d2c4034b 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -35,6 +35,7 @@
 #![allow(rustc::potential_query_instability)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
+#![deny(unsafe_op_in_unsafe_fn)]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_data_structures/src/memmap.rs b/compiler/rustc_data_structures/src/memmap.rs
index ef37a606f31..ca908671ae5 100644
--- a/compiler/rustc_data_structures/src/memmap.rs
+++ b/compiler/rustc_data_structures/src/memmap.rs
@@ -13,7 +13,8 @@ pub struct Mmap(Vec<u8>);
 impl Mmap {
     #[inline]
     pub unsafe fn map(file: File) -> io::Result<Self> {
-        memmap2::Mmap::map(&file).map(Mmap)
+        // Safety: this is in fact not safe.
+        unsafe { memmap2::Mmap::map(&file).map(Mmap) }
     }
 }
 
diff --git a/compiler/rustc_data_structures/src/sip128.rs b/compiler/rustc_data_structures/src/sip128.rs
index d849fe0373f..4a0ed87f77c 100644
--- a/compiler/rustc_data_structures/src/sip128.rs
+++ b/compiler/rustc_data_structures/src/sip128.rs
@@ -96,28 +96,30 @@ macro_rules! compress {
 unsafe fn copy_nonoverlapping_small(src: *const u8, dst: *mut u8, count: usize) {
     debug_assert!(count <= 8);
 
-    if count == 8 {
-        ptr::copy_nonoverlapping(src, dst, 8);
-        return;
-    }
+    unsafe {
+        if count == 8 {
+            ptr::copy_nonoverlapping(src, dst, 8);
+            return;
+        }
 
-    let mut i = 0;
-    if i + 3 < count {
-        ptr::copy_nonoverlapping(src.add(i), dst.add(i), 4);
-        i += 4;
-    }
+        let mut i = 0;
+        if i + 3 < count {
+            ptr::copy_nonoverlapping(src.add(i), dst.add(i), 4);
+            i += 4;
+        }
 
-    if i + 1 < count {
-        ptr::copy_nonoverlapping(src.add(i), dst.add(i), 2);
-        i += 2
-    }
+        if i + 1 < count {
+            ptr::copy_nonoverlapping(src.add(i), dst.add(i), 2);
+            i += 2
+        }
 
-    if i < count {
-        *dst.add(i) = *src.add(i);
-        i += 1;
-    }
+        if i < count {
+            *dst.add(i) = *src.add(i);
+            i += 1;
+        }
 
-    debug_assert_eq!(i, count);
+        debug_assert_eq!(i, count);
+    }
 }
 
 // # Implementation
@@ -232,38 +234,40 @@ impl SipHasher128 {
     // overflow) if it wasn't already.
     #[inline(never)]
     unsafe fn short_write_process_buffer<const LEN: usize>(&mut self, bytes: [u8; LEN]) {
-        let nbuf = self.nbuf;
-        debug_assert!(LEN <= 8);
-        debug_assert!(nbuf < BUFFER_SIZE);
-        debug_assert!(nbuf + LEN >= BUFFER_SIZE);
-        debug_assert!(nbuf + LEN < BUFFER_WITH_SPILL_SIZE);
+        unsafe {
+            let nbuf = self.nbuf;
+            debug_assert!(LEN <= 8);
+            debug_assert!(nbuf < BUFFER_SIZE);
+            debug_assert!(nbuf + LEN >= BUFFER_SIZE);
+            debug_assert!(nbuf + LEN < BUFFER_WITH_SPILL_SIZE);
+
+            // Copy first part of input into end of buffer, possibly into spill
+            // element. The memcpy call is optimized away because the size is known.
+            let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf);
+            ptr::copy_nonoverlapping(bytes.as_ptr(), dst, LEN);
+
+            // Process buffer.
+            for i in 0..BUFFER_CAPACITY {
+                let elem = self.buf.get_unchecked(i).assume_init().to_le();
+                self.state.v3 ^= elem;
+                Sip13Rounds::c_rounds(&mut self.state);
+                self.state.v0 ^= elem;
+            }
 
-        // Copy first part of input into end of buffer, possibly into spill
-        // element. The memcpy call is optimized away because the size is known.
-        let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf);
-        ptr::copy_nonoverlapping(bytes.as_ptr(), dst, LEN);
-
-        // Process buffer.
-        for i in 0..BUFFER_CAPACITY {
-            let elem = self.buf.get_unchecked(i).assume_init().to_le();
-            self.state.v3 ^= elem;
-            Sip13Rounds::c_rounds(&mut self.state);
-            self.state.v0 ^= elem;
+            // Copy remaining input into start of buffer by copying LEN - 1
+            // elements from spill (at most LEN - 1 bytes could have overflowed
+            // into the spill). The memcpy call is optimized away because the size
+            // is known. And the whole copy is optimized away for LEN == 1.
+            let dst = self.buf.as_mut_ptr() as *mut u8;
+            let src = self.buf.get_unchecked(BUFFER_SPILL_INDEX) as *const _ as *const u8;
+            ptr::copy_nonoverlapping(src, dst, LEN - 1);
+
+            // This function should only be called when the write fills the buffer.
+            // Therefore, when LEN == 1, the new `self.nbuf` must be zero.
+            // LEN is statically known, so the branch is optimized away.
+            self.nbuf = if LEN == 1 { 0 } else { nbuf + LEN - BUFFER_SIZE };
+            self.processed += BUFFER_SIZE;
         }
-
-        // Copy remaining input into start of buffer by copying LEN - 1
-        // elements from spill (at most LEN - 1 bytes could have overflowed
-        // into the spill). The memcpy call is optimized away because the size
-        // is known. And the whole copy is optimized away for LEN == 1.
-        let dst = self.buf.as_mut_ptr() as *mut u8;
-        let src = self.buf.get_unchecked(BUFFER_SPILL_INDEX) as *const _ as *const u8;
-        ptr::copy_nonoverlapping(src, dst, LEN - 1);
-
-        // This function should only be called when the write fills the buffer.
-        // Therefore, when LEN == 1, the new `self.nbuf` must be zero.
-        // LEN is statically known, so the branch is optimized away.
-        self.nbuf = if LEN == 1 { 0 } else { nbuf + LEN - BUFFER_SIZE };
-        self.processed += BUFFER_SIZE;
     }
 
     // A write function for byte slices.
@@ -301,57 +305,59 @@ impl SipHasher128 {
     // containing the byte offset `self.nbuf`.
     #[inline(never)]
     unsafe fn slice_write_process_buffer(&mut self, msg: &[u8]) {
-        let length = msg.len();
-        let nbuf = self.nbuf;
-        debug_assert!(nbuf < BUFFER_SIZE);
-        debug_assert!(nbuf + length >= BUFFER_SIZE);
-
-        // Always copy first part of input into current element of buffer.
-        // This function should only be called when the write fills the buffer,
-        // so we know that there is enough input to fill the current element.
-        let valid_in_elem = nbuf % ELEM_SIZE;
-        let needed_in_elem = ELEM_SIZE - valid_in_elem;
-
-        let src = msg.as_ptr();
-        let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf);
-        copy_nonoverlapping_small(src, dst, needed_in_elem);
-
-        // Process buffer.
+        unsafe {
+            let length = msg.len();
+            let nbuf = self.nbuf;
+            debug_assert!(nbuf < BUFFER_SIZE);
+            debug_assert!(nbuf + length >= BUFFER_SIZE);
+
+            // Always copy first part of input into current element of buffer.
+            // This function should only be called when the write fills the buffer,
+            // so we know that there is enough input to fill the current element.
+            let valid_in_elem = nbuf % ELEM_SIZE;
+            let needed_in_elem = ELEM_SIZE - valid_in_elem;
+
+            let src = msg.as_ptr();
+            let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf);
+            copy_nonoverlapping_small(src, dst, needed_in_elem);
+
+            // Process buffer.
+
+            // Using `nbuf / ELEM_SIZE + 1` rather than `(nbuf + needed_in_elem) /
+            // ELEM_SIZE` to show the compiler that this loop's upper bound is > 0.
+            // We know that is true, because last step ensured we have a full
+            // element in the buffer.
+            let last = nbuf / ELEM_SIZE + 1;
+
+            for i in 0..last {
+                let elem = self.buf.get_unchecked(i).assume_init().to_le();
+                self.state.v3 ^= elem;
+                Sip13Rounds::c_rounds(&mut self.state);
+                self.state.v0 ^= elem;
+            }
 
-        // Using `nbuf / ELEM_SIZE + 1` rather than `(nbuf + needed_in_elem) /
-        // ELEM_SIZE` to show the compiler that this loop's upper bound is > 0.
-        // We know that is true, because last step ensured we have a full
-        // element in the buffer.
-        let last = nbuf / ELEM_SIZE + 1;
+            // Process the remaining element-sized chunks of input.
+            let mut processed = needed_in_elem;
+            let input_left = length - processed;
+            let elems_left = input_left / ELEM_SIZE;
+            let extra_bytes_left = input_left % ELEM_SIZE;
+
+            for _ in 0..elems_left {
+                let elem = (msg.as_ptr().add(processed) as *const u64).read_unaligned().to_le();
+                self.state.v3 ^= elem;
+                Sip13Rounds::c_rounds(&mut self.state);
+                self.state.v0 ^= elem;
+                processed += ELEM_SIZE;
+            }
 
-        for i in 0..last {
-            let elem = self.buf.get_unchecked(i).assume_init().to_le();
-            self.state.v3 ^= elem;
-            Sip13Rounds::c_rounds(&mut self.state);
-            self.state.v0 ^= elem;
-        }
+            // Copy remaining input into start of buffer.
+            let src = msg.as_ptr().add(processed);
+            let dst = self.buf.as_mut_ptr() as *mut u8;
+            copy_nonoverlapping_small(src, dst, extra_bytes_left);
 
-        // Process the remaining element-sized chunks of input.
-        let mut processed = needed_in_elem;
-        let input_left = length - processed;
-        let elems_left = input_left / ELEM_SIZE;
-        let extra_bytes_left = input_left % ELEM_SIZE;
-
-        for _ in 0..elems_left {
-            let elem = (msg.as_ptr().add(processed) as *const u64).read_unaligned().to_le();
-            self.state.v3 ^= elem;
-            Sip13Rounds::c_rounds(&mut self.state);
-            self.state.v0 ^= elem;
-            processed += ELEM_SIZE;
+            self.nbuf = extra_bytes_left;
+            self.processed += nbuf + processed;
         }
-
-        // Copy remaining input into start of buffer.
-        let src = msg.as_ptr().add(processed);
-        let dst = self.buf.as_mut_ptr() as *mut u8;
-        copy_nonoverlapping_small(src, dst, extra_bytes_left);
-
-        self.nbuf = extra_bytes_left;
-        self.processed += nbuf + processed;
     }
 
     #[inline]
diff --git a/compiler/rustc_data_structures/src/tagged_ptr.rs b/compiler/rustc_data_structures/src/tagged_ptr.rs
index c26bffac678..8568aac67c0 100644
--- a/compiler/rustc_data_structures/src/tagged_ptr.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr.rs
@@ -153,7 +153,7 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Box<T> {
     #[inline]
     unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
         // Safety: `ptr` comes from `into_ptr` which calls `Box::into_raw`
-        Box::from_raw(ptr.as_ptr())
+        unsafe { Box::from_raw(ptr.as_ptr()) }
     }
 }
 
@@ -169,7 +169,7 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Rc<T> {
     #[inline]
     unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
         // Safety: `ptr` comes from `into_ptr` which calls `Rc::into_raw`
-        Rc::from_raw(ptr.as_ptr())
+        unsafe { Rc::from_raw(ptr.as_ptr()) }
     }
 }
 
@@ -185,7 +185,7 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Arc<T> {
     #[inline]
     unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
         // Safety: `ptr` comes from `into_ptr` which calls `Arc::into_raw`
-        Arc::from_raw(ptr.as_ptr())
+        unsafe { Arc::from_raw(ptr.as_ptr()) }
     }
 }
 
@@ -201,7 +201,7 @@ unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a T {
     unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
         // Safety:
         // `ptr` comes from `into_ptr` which gets the pointer from a reference
-        ptr.as_ref()
+        unsafe { ptr.as_ref() }
     }
 }
 
@@ -217,7 +217,7 @@ unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T {
     unsafe fn from_ptr(mut ptr: NonNull<T>) -> Self {
         // Safety:
         // `ptr` comes from `into_ptr` which gets the pointer from a reference
-        ptr.as_mut()
+        unsafe { ptr.as_mut() }
     }
 }
 
diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs
index 446c6832cb7..ee64b18d3f6 100644
--- a/compiler/rustc_driver_impl/src/pretty.rs
+++ b/compiler/rustc_driver_impl/src/pretty.rs
@@ -488,12 +488,7 @@ fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuarante
             abort_on_err(rustc_hir_analysis::check_crate(tcx), tcx.sess);
             debug!("pretty printing THIR tree");
             for did in tcx.hir().body_owners() {
-                let _ = writeln!(
-                    out,
-                    "{:?}:\n{}\n",
-                    did,
-                    tcx.thir_tree(ty::WithOptConstParam::unknown(did))
-                );
+                let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_tree(did));
             }
             out
         }
@@ -503,12 +498,7 @@ fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuarante
             abort_on_err(rustc_hir_analysis::check_crate(tcx), tcx.sess);
             debug!("pretty printing THIR flat");
             for did in tcx.hir().body_owners() {
-                let _ = writeln!(
-                    out,
-                    "{:?}:\n{}\n",
-                    did,
-                    tcx.thir_flat(ty::WithOptConstParam::unknown(did))
-                );
+                let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_flat(did));
             }
             out
         }
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 8c76d5e010f..2498ae2b7bc 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -1336,6 +1336,7 @@ impl EmitterWriter {
         //                see?
         for (text, style) in msg.iter() {
             let text = self.translate_message(text, args).map_err(Report::new).unwrap();
+            let text = &normalize_whitespace(&text);
             let lines = text.split('\n').collect::<Vec<_>>();
             if lines.len() > 1 {
                 for (i, line) in lines.iter().enumerate() {
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 341ae18541b..1e7d07bc22d 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -18,7 +18,7 @@ use rustc_span::def_id::CrateNum;
 use rustc_span::symbol::{self, sym, Symbol};
 use rustc_span::{BytePos, FileName, Pos, SourceFile, Span};
 use smallvec::{smallvec, SmallVec};
-use std::ops::Bound;
+use std::ops::{Bound, Range};
 
 trait FromInternal<T> {
     fn from_internal(x: T) -> Self;
@@ -634,6 +634,15 @@ impl server::Span for Rustc<'_, '_> {
         span.source_callsite()
     }
 
+    fn byte_range(&mut self, span: Self::Span) -> Range<usize> {
+        let source_map = self.sess().source_map();
+
+        let relative_start_pos = source_map.lookup_byte_offset(span.lo()).pos;
+        let relative_end_pos = source_map.lookup_byte_offset(span.hi()).pos;
+
+        Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize }
+    }
+
     fn start(&mut self, span: Self::Span) -> LineColumn {
         let loc = self.sess().source_map().lookup_char_pos(span.lo());
         LineColumn { line: loc.line, column: loc.col.to_usize() }
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 486718ea6a0..52ed9660256 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1715,6 +1715,7 @@ impl Expr<'_> {
             ExprKind::Continue(..) => ExprPrecedence::Continue,
             ExprKind::Ret(..) => ExprPrecedence::Ret,
             ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
+            ExprKind::OffsetOf(..) => ExprPrecedence::OffsetOf,
             ExprKind::Struct(..) => ExprPrecedence::Struct,
             ExprKind::Repeat(..) => ExprPrecedence::Repeat,
             ExprKind::Yield(..) => ExprPrecedence::Yield,
@@ -1774,6 +1775,7 @@ impl Expr<'_> {
             | ExprKind::Loop(..)
             | ExprKind::Assign(..)
             | ExprKind::InlineAsm(..)
+            | ExprKind::OffsetOf(..)
             | ExprKind::AssignOp(..)
             | ExprKind::Lit(_)
             | ExprKind::ConstBlock(..)
@@ -1818,7 +1820,7 @@ impl Expr<'_> {
 
     pub fn can_have_side_effects(&self) -> bool {
         match self.peel_drop_temps().kind {
-            ExprKind::Path(_) | ExprKind::Lit(_) => false,
+            ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) => false,
             ExprKind::Type(base, _)
             | ExprKind::Unary(_, base)
             | ExprKind::Field(base, _)
@@ -2022,6 +2024,9 @@ pub enum ExprKind<'hir> {
     /// Inline assembly (from `asm!`), with its outputs and inputs.
     InlineAsm(&'hir InlineAsm<'hir>),
 
+    /// Field offset (`offset_of!`)
+    OffsetOf(&'hir Ty<'hir>, &'hir [Ident]),
+
     /// A struct or struct-like variant literal expression.
     ///
     /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`,
@@ -3529,12 +3534,20 @@ impl<'hir> OwnerNode<'hir> {
 
     pub fn body_id(&self) -> Option<BodyId> {
         match self {
-            OwnerNode::TraitItem(TraitItem {
-                kind: TraitItemKind::Fn(_, TraitFn::Provided(body_id)),
+            OwnerNode::Item(Item {
+                kind:
+                    ItemKind::Static(_, _, body) | ItemKind::Const(_, body) | ItemKind::Fn(_, _, body),
+                ..
+            })
+            | OwnerNode::TraitItem(TraitItem {
+                kind:
+                    TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)),
                 ..
             })
-            | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. })
-            | OwnerNode::Item(Item { kind: ItemKind::Fn(.., body_id), .. }) => Some(*body_id),
+            | OwnerNode::ImplItem(ImplItem {
+                kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body),
+                ..
+            }) => Some(*body),
             _ => None,
         }
     }
@@ -3729,12 +3742,27 @@ impl<'hir> Node<'hir> {
 
     pub fn body_id(&self) -> Option<BodyId> {
         match self {
-            Node::TraitItem(TraitItem {
-                kind: TraitItemKind::Fn(_, TraitFn::Provided(body_id)),
+            Node::Item(Item {
+                kind:
+                    ItemKind::Static(_, _, body) | ItemKind::Const(_, body) | ItemKind::Fn(_, _, body),
                 ..
             })
-            | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. })
-            | Node::Item(Item { kind: ItemKind::Fn(.., body_id), .. }) => Some(*body_id),
+            | Node::TraitItem(TraitItem {
+                kind:
+                    TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)),
+                ..
+            })
+            | Node::ImplItem(ImplItem {
+                kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body),
+                ..
+            })
+            | Node::Expr(Expr {
+                kind:
+                    ExprKind::ConstBlock(AnonConst { body, .. })
+                    | ExprKind::Closure(Closure { body, .. })
+                    | ExprKind::Repeat(_, ArrayLen::Body(AnonConst { body, .. })),
+                ..
+            }) => Some(*body),
             _ => None,
         }
     }
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 234256ab553..df0047d82e1 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -786,6 +786,10 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
         ExprKind::InlineAsm(ref asm) => {
             visitor.visit_inline_asm(asm, expression.hir_id);
         }
+        ExprKind::OffsetOf(ref container, ref fields) => {
+            visitor.visit_ty(container);
+            walk_list!(visitor, visit_ident, fields.iter().copied());
+        }
         ExprKind::Yield(ref subexpression, _) => {
             visitor.visit_expr(subexpression);
         }
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 7eb12d380a7..992316edb63 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -447,14 +447,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         handle_ty_args(has_default, &inf.to_ty())
                     }
                     (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
-                        ty::Const::from_opt_const_arg_anon_const(
-                            tcx,
-                            ty::WithOptConstParam {
-                                did: ct.value.def_id,
-                                const_param_did: Some(param.def_id),
-                            },
-                        )
-                        .into()
+                        let did = ct.value.def_id;
+                        tcx.feed_anon_const_type(did, tcx.type_of(param.def_id));
+                        ty::Const::from_anon_const(tcx, did).into()
                     }
                     (&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => {
                         let ty = tcx
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 0c54fd70c9b..51ec5dd7a28 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -863,7 +863,7 @@ fn check_impl_items_against_trait<'tcx>(
         if !missing_items.is_empty() {
             let full_impl_span =
                 tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id));
-            missing_items_err(tcx, tcx.def_span(impl_id), &missing_items, full_impl_span);
+            missing_items_err(tcx, impl_id, &missing_items, full_impl_span);
         }
 
         if let Some(missing_items) = must_implement_one_of {
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 8fe4c44fca4..4b3f3cf169d 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -198,7 +198,7 @@ fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_imp
 
 fn missing_items_err(
     tcx: TyCtxt<'_>,
-    impl_span: Span,
+    impl_def_id: LocalDefId,
     missing_items: &[ty::AssocItem],
     full_impl_span: Span,
 ) {
@@ -211,6 +211,7 @@ fn missing_items_err(
         .collect::<Vec<_>>()
         .join("`, `");
 
+    let impl_span = tcx.def_span(impl_def_id);
     let mut err = struct_span_err!(
         tcx.sess,
         impl_span,
@@ -229,7 +230,11 @@ fn missing_items_err(
         tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new());
 
     for &trait_item in missing_items {
-        let snippet = suggestion_signature(trait_item, tcx);
+        let snippet = suggestion_signature(
+            tcx,
+            trait_item,
+            tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(),
+        );
         let code = format!("{}{}\n{}", padding, snippet, padding);
         let msg = format!("implement the missing item: `{snippet}`");
         let appl = Applicability::HasPlaceholders;
@@ -301,11 +306,11 @@ fn default_body_is_unstable(
 /// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
 fn bounds_from_generic_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
-    predicates: ty::GenericPredicates<'tcx>,
+    predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
 ) -> (String, String) {
     let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
     let mut projections = vec![];
-    for (predicate, _) in predicates.predicates {
+    for (predicate, _) in predicates {
         debug!("predicate {:?}", predicate);
         let bound_predicate = predicate.kind();
         match bound_predicate.skip_binder() {
@@ -367,7 +372,7 @@ fn fn_sig_suggestion<'tcx>(
     tcx: TyCtxt<'tcx>,
     sig: ty::FnSig<'tcx>,
     ident: Ident,
-    predicates: ty::GenericPredicates<'tcx>,
+    predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
     assoc: ty::AssocItem,
 ) -> String {
     let args = sig
@@ -436,7 +441,17 @@ pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
 /// Return placeholder code for the given associated item.
 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
 /// structured suggestion.
-fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String {
+fn suggestion_signature<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    assoc: ty::AssocItem,
+    impl_trait_ref: ty::TraitRef<'tcx>,
+) -> String {
+    let substs = ty::InternalSubsts::identity_for_item(tcx, assoc.def_id).rebase_onto(
+        tcx,
+        assoc.container_id(tcx),
+        impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).substs,
+    );
+
     match assoc.kind {
         ty::AssocKind::Fn => {
             // We skip the binder here because the binder would deanonymize all
@@ -445,16 +460,22 @@ fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String {
             // regions just fine, showing `fn(&MyType)`.
             fn_sig_suggestion(
                 tcx,
-                tcx.fn_sig(assoc.def_id).subst_identity().skip_binder(),
+                tcx.fn_sig(assoc.def_id).subst(tcx, substs).skip_binder(),
                 assoc.ident(tcx),
-                tcx.predicates_of(assoc.def_id),
+                tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
                 assoc,
             )
         }
-        ty::AssocKind::Type => format!("type {} = Type;", assoc.name),
+        ty::AssocKind::Type => {
+            let (generics, where_clauses) = bounds_from_generic_predicates(
+                tcx,
+                tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
+            );
+            format!("type {}{generics} = /* Type */{where_clauses};", assoc.name)
+        }
         ty::AssocKind::Const => {
             let ty = tcx.type_of(assoc.def_id).subst_identity();
-            let val = ty_kind_suggestion(ty).unwrap_or("value");
+            let val = ty_kind_suggestion(ty).unwrap_or("todo!()");
             format!("const {}: {} = {};", assoc.name, ty, val)
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 7c07a1ebaec..36e294e8aa2 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -55,7 +55,6 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
 pub fn provide(providers: &mut Providers) {
     resolve_bound_vars::provide(providers);
     *providers = Providers {
-        opt_const_param_of: type_of::opt_const_param_of,
         type_of: type_of::type_of,
         item_bounds: item_bounds::item_bounds,
         explicit_item_bounds: item_bounds::explicit_item_bounds,
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index f82fad47422..d7d509e5394 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -1,6 +1,6 @@
 use rustc_errors::{Applicability, StashKey};
 use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{HirId, Node};
@@ -16,22 +16,81 @@ use super::ItemCtxt;
 use super::{bad_placeholder, is_suggestable_infer_ty};
 use crate::errors::UnconstrainedOpaqueType;
 
-/// Computes the relevant generic parameter for a potential generic const argument.
-///
-/// This should be called using the query `tcx.opt_const_param_of`.
-pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> {
+fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
     use hir::*;
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
 
-    match tcx.hir().get(hir_id) {
-        Node::AnonConst(_) => (),
-        _ => return None,
-    };
+    let Node::AnonConst(_) = tcx.hir().get(hir_id) else { panic!() };
 
     let parent_node_id = tcx.hir().parent_id(hir_id);
     let parent_node = tcx.hir().get(parent_node_id);
 
     let (generics, arg_idx) = match parent_node {
+        // Easy case: arrays repeat expressions.
+        Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. })
+        | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
+            if constant.hir_id() == hir_id =>
+        {
+            return tcx.types.usize
+        }
+        Node::Ty(&Ty { kind: TyKind::Typeof(ref e), .. }) if e.hir_id == hir_id => {
+            return tcx.typeck(def_id).node_type(e.hir_id)
+        }
+        Node::Expr(&Expr { kind: ExprKind::ConstBlock(ref anon_const), .. })
+            if anon_const.hir_id == hir_id =>
+        {
+            let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
+            return substs.as_inline_const().ty()
+        }
+        Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
+        | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
+            if asm.operands.iter().any(|(op, _op_sp)| match op {
+                hir::InlineAsmOperand::Const { anon_const }
+                | hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id,
+                _ => false,
+            }) =>
+        {
+            return tcx.typeck(def_id).node_type(hir_id)
+        }
+        Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
+            return tcx
+                .adt_def(tcx.hir().get_parent_item(hir_id))
+                .repr()
+                .discr_type()
+                .to_ty(tcx)
+        }
+        Node::GenericParam(&GenericParam {
+            def_id: param_def_id,
+            kind: GenericParamKind::Const { default: Some(ct), .. },
+            ..
+        }) if ct.hir_id == hir_id => {
+            return tcx.type_of(param_def_id)
+                .no_bound_vars()
+                .expect("const parameter types cannot be generic")
+        }
+
+        Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, ..  })
+            if let Node::TraitRef(trait_ref) = tcx.hir().get(
+                tcx.hir().parent_id(binding_id)
+            ) =>
+        {
+            let Some(trait_def_id) = trait_ref.trait_def_id() else {
+                return tcx.ty_error_with_message(tcx.def_span(def_id), "Could not find trait");
+            };
+            let assoc_items = tcx.associated_items(trait_def_id);
+            let assoc_item = assoc_items.find_by_name_and_kind(
+                tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(),
+            );
+            return if let Some(assoc_item) = assoc_item {
+                tcx.type_of(assoc_item.def_id)
+                    .no_bound_vars()
+                    .expect("const parameter types cannot be generic")
+            } else {
+                // FIXME(associated_const_equality): add a useful error message here.
+                tcx.ty_error_with_message(tcx.def_span(def_id), "Could not find associated const on trait")
+            }
+        }
+
         // This match arm is for when the def_id appears in a GAT whose
         // path can't be resolved without typechecking e.g.
         //
@@ -86,11 +145,10 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
                 (generics, arg_index)
             } else {
                 // I dont think it's possible to reach this but I'm not 100% sure - BoxyUwU
-                tcx.sess.delay_span_bug(
+                return tcx.ty_error_with_message(
                     tcx.def_span(def_id),
                     "unexpected non-GAT usage of an anon const",
                 );
-                return None;
             }
         }
         Node::Expr(&Expr {
@@ -103,7 +161,12 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
             // This may fail in case the method/path does not actually exist.
             // As there is no relevant param for `def_id`, we simply return
             // `None` here.
-            let type_dependent_def = tables.type_dependent_def_id(parent_node_id)?;
+            let Some(type_dependent_def) = tables.type_dependent_def_id(parent_node_id) else {
+                return tcx.ty_error_with_message(
+                    tcx.def_span(def_id),
+                    &format!("unable to find type-dependent def for {:?}", parent_node_id),
+                );
+            };
             let idx = segment
                 .args
                 .and_then(|args| {
@@ -140,19 +203,17 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
                     if let Some(path) = get_path_containing_arg_in_pat(pat, hir_id) {
                         path
                     } else {
-                        tcx.sess.delay_span_bug(
+                        return tcx.ty_error_with_message(
                             tcx.def_span(def_id),
                             &format!("unable to find const parent for {} in pat {:?}", hir_id, pat),
                         );
-                        return None;
                     }
                 }
                 _ => {
-                    tcx.sess.delay_span_bug(
+                    return tcx.ty_error_with_message(
                         tcx.def_span(def_id),
                         &format!("unexpected const parent path {:?}", parent_node),
                     );
-                    return None;
                 }
             };
 
@@ -171,32 +232,34 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
                     .position(|ct| ct.hir_id == hir_id)
                     .map(|idx| (idx, seg)))
             }) else {
-                tcx.sess.delay_span_bug(
+                return tcx.ty_error_with_message(
                     tcx.def_span(def_id),
                     "no arg matching AnonConst in path",
                 );
-                return None;
             };
 
             let generics = match tcx.res_generics_def_id(segment.res) {
                 Some(def_id) => tcx.generics_of(def_id),
                 None => {
-                    tcx.sess.delay_span_bug(
+                    return tcx.ty_error_with_message(
                         tcx.def_span(def_id),
                         &format!("unexpected anon const res {:?} in path: {:?}", segment.res, path),
                     );
-                    return None;
                 }
             };
 
             (generics, arg_index)
         }
-        _ => return None,
+
+        _ => return tcx.ty_error_with_message(
+            tcx.def_span(def_id),
+            &format!("unexpected const parent in type_of(): {parent_node:?}"),
+        ),
     };
 
     debug!(?parent_node);
     debug!(?generics, ?arg_idx);
-    generics
+    if let Some(param_def_id) = generics
         .params
         .iter()
         .filter(|param| param.kind.is_ty_or_const())
@@ -211,6 +274,14 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
             }
             _ => None,
         })
+    {
+        tcx.type_of(param_def_id).no_bound_vars().expect("const parameter types cannot be generic")
+    } else {
+        return tcx.ty_error_with_message(
+            tcx.def_span(def_id),
+            &format!("const generic parameter not found in {generics:?} at position {arg_idx:?}"),
+        );
+    }
 }
 
 fn get_path_containing_arg_in_pat<'hir>(
@@ -415,143 +486,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
             tcx.typeck(def_id).node_type(hir_id)
         }
 
-        Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => {
-            // We defer to `type_of` of the corresponding parameter
-            // for generic arguments.
-            tcx.type_of(param).subst_identity()
-        }
-
-        Node::AnonConst(_) => {
-            let parent_node = tcx.hir().get_parent(hir_id);
-            match parent_node {
-                Node::Ty(Ty { kind: TyKind::Array(_, constant), .. })
-                | Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. })
-                    if constant.hir_id() == hir_id =>
-                {
-                    tcx.types.usize
-                }
-                Node::Ty(Ty { kind: TyKind::Typeof(e), .. }) if e.hir_id == hir_id => {
-                    tcx.typeck(def_id).node_type(e.hir_id)
-                }
-
-                Node::Expr(Expr { kind: ExprKind::ConstBlock(anon_const), .. })
-                    if anon_const.hir_id == hir_id =>
-                {
-                    let substs = InternalSubsts::identity_for_item(tcx, def_id);
-                    substs.as_inline_const().ty()
-                }
-
-                Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
-                | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
-                    if asm.operands.iter().any(|(op, _op_sp)| match op {
-                        hir::InlineAsmOperand::Const { anon_const }
-                        | hir::InlineAsmOperand::SymFn { anon_const } => {
-                            anon_const.hir_id == hir_id
-                        }
-                        _ => false,
-                    }) =>
-                {
-                    tcx.typeck(def_id).node_type(hir_id)
-                }
-
-                Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => {
-                    tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
-                }
-
-                Node::TypeBinding(TypeBinding {
-                    hir_id: binding_id,
-                    kind: TypeBindingKind::Equality { term: Term::Const(e) },
-                    ident,
-                    ..
-                }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id)
-                    && e.hir_id == hir_id =>
-                {
-                    let Some(trait_def_id) = trait_ref.trait_def_id() else {
-                        return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"));
-                    };
-                    let assoc_items = tcx.associated_items(trait_def_id);
-                    let assoc_item = assoc_items.find_by_name_and_kind(
-                        tcx,
-                        *ident,
-                        ty::AssocKind::Const,
-                        def_id.to_def_id(),
-                    );
-                    if let Some(assoc_item) = assoc_item {
-                        tcx.type_of(assoc_item.def_id)
-                            .no_bound_vars()
-                            .expect("const parameter types cannot be generic")
-                    } else {
-                        // FIXME(associated_const_equality): add a useful error message here.
-                        tcx.ty_error_with_message(
-                            DUMMY_SP,
-                            "Could not find associated const on trait",
-                        )
-                    }
-                }
-
-                Node::TypeBinding(TypeBinding {
-                    hir_id: binding_id,
-                    gen_args,
-                    kind,
-                    ident,
-                    ..
-                }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id)
-                    && let Some((idx, _)) =
-                        gen_args.args.iter().enumerate().find(|(_, arg)| {
-                            if let GenericArg::Const(ct) = arg {
-                                ct.value.hir_id == hir_id
-                            } else {
-                                false
-                            }
-                        }) =>
-                {
-                    let Some(trait_def_id) = trait_ref.trait_def_id() else {
-                        return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"));
-                    };
-                    let assoc_items = tcx.associated_items(trait_def_id);
-                    let assoc_item = assoc_items.find_by_name_and_kind(
-                        tcx,
-                        *ident,
-                        match kind {
-                            // I think `<A: T>` type bindings requires that `A` is a type
-                            TypeBindingKind::Constraint { .. }
-                            | TypeBindingKind::Equality { term: Term::Ty(..) } => {
-                                ty::AssocKind::Type
-                            }
-                            TypeBindingKind::Equality { term: Term::Const(..) } => {
-                                ty::AssocKind::Const
-                            }
-                        },
-                        def_id.to_def_id(),
-                    );
-                    if let Some(assoc_item) = assoc_item
-                        && let param = &tcx.generics_of(assoc_item.def_id).params[idx]
-                        && matches!(param.kind, ty::GenericParamDefKind::Const { .. })
-                    {
-                        tcx.type_of(param.def_id)
-                            .no_bound_vars()
-                            .expect("const parameter types cannot be generic")
-                    } else {
-                        // FIXME(associated_const_equality): add a useful error message here.
-                        tcx.ty_error_with_message(
-                            DUMMY_SP,
-                            "Could not find const param on associated item",
-                        )
-                    }
-                }
-
-                Node::GenericParam(&GenericParam {
-                    def_id: param_def_id,
-                    kind: GenericParamKind::Const { default: Some(ct), .. },
-                    ..
-                }) if ct.hir_id == hir_id => tcx.type_of(param_def_id).subst_identity(),
-
-                x => tcx.ty_error_with_message(
-                    DUMMY_SP,
-                    &format!("unexpected const parent in type_of(): {x:?}"),
-                ),
-            }
-        }
+        Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
 
         Node::GenericParam(param) => match &param.kind {
             GenericParamKind::Type { default: Some(ty), .. }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 74f5b359021..2db4f1e50d4 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1551,6 +1551,23 @@ impl<'a> State<'a> {
                 self.word("asm!");
                 self.print_inline_asm(asm);
             }
+            hir::ExprKind::OffsetOf(container, ref fields) => {
+                self.word("offset_of!(");
+                self.print_type(container);
+                self.word(",");
+                self.space();
+
+                if let Some((&first, rest)) = fields.split_first() {
+                    self.print_ident(first);
+
+                    for &field in rest {
+                        self.word(".");
+                        self.print_ident(field);
+                    }
+                }
+
+                self.word(")");
+            }
             hir::ExprKind::Yield(expr, _) => {
                 self.word_space("yield");
                 self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index 2c537bf4064..6d40df7d0cc 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -3,21 +3,6 @@ hir_typeck_field_multiply_specified_in_initializer =
     .label = used more than once
     .previous_use_label = first use of `{$ident}`
 
-hir_typeck_copy_impl_on_type_with_dtor =
-    the trait `Copy` cannot be implemented for this type; the type has a destructor
-    .label = `Copy` not allowed on types with destructors
-
-hir_typeck_multiple_relaxed_default_bounds =
-    type parameter has more than one relaxed default bound, only one is supported
-
-hir_typeck_copy_impl_on_non_adt =
-    the trait `Copy` cannot be implemented for this type
-    .label = type is not a structure or enumeration
-
-hir_typeck_trait_object_declared_with_no_traits =
-    at least one trait is required for an object type
-    .alias_span = this alias does not contain a trait
-
 hir_typeck_functional_record_update_on_non_struct =
     functional record update syntax requires a struct
 
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 0c0a7515d9c..3ffc583d43f 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -309,6 +309,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.deferred_asm_checks.borrow_mut().push((asm, expr.hir_id));
                 self.check_expr_asm(asm)
             }
+            ExprKind::OffsetOf(container, ref fields) => {
+                self.check_offset_of(container, fields, expr)
+            }
             ExprKind::Break(destination, ref expr_opt) => {
                 self.check_expr_break(destination, expr_opt.as_deref(), expr)
             }
@@ -2450,15 +2453,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         base_did: DefId,
         return_ty: Option<Ty<'tcx>>,
     ) -> ErrorGuaranteed {
-        let struct_path = self.tcx().def_path_str(base_did);
-        let kind_name = self.tcx().def_descr(base_did);
-        let mut err = struct_span_err!(
-            self.tcx().sess,
-            field.span,
-            E0616,
-            "field `{field}` of {kind_name} `{struct_path}` is private",
-        );
-        err.span_label(field.span, "private field");
+        let mut err = self.private_field_err(field, base_did);
+
         // Also check if an accessible method exists, which is often what is meant.
         if self.method_exists(field, expr_t, expr.hir_id, false, return_ty)
             && !self.expr_in_place(expr.hir_id)
@@ -2698,6 +2694,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err
     }
 
+    fn private_field_err(
+        &self,
+        field: Ident,
+        base_did: DefId,
+    ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
+        let struct_path = self.tcx().def_path_str(base_did);
+        let kind_name = self.tcx().def_descr(base_did);
+        let mut err = struct_span_err!(
+            self.tcx().sess,
+            field.span,
+            E0616,
+            "field `{field}` of {kind_name} `{struct_path}` is private",
+        );
+        err.span_label(field.span, "private field");
+
+        err
+    }
+
     pub(crate) fn get_field_candidates_considering_privacy(
         &self,
         span: Span,
@@ -3042,4 +3056,78 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.tcx.mk_unit()
         }
     }
+
+    fn check_offset_of(
+        &self,
+        container: &'tcx hir::Ty<'tcx>,
+        fields: &[Ident],
+        expr: &'tcx hir::Expr<'tcx>,
+    ) -> Ty<'tcx> {
+        let container = self.to_ty(container).normalized;
+
+        let mut field_indices = Vec::with_capacity(fields.len());
+        let mut current_container = container;
+
+        for &field in fields {
+            let container = self.structurally_resolved_type(expr.span, current_container);
+
+            match container.kind() {
+                ty::Adt(container_def, substs) if !container_def.is_enum() => {
+                    let block = self.tcx.hir().local_def_id_to_hir_id(self.body_id);
+                    let (ident, def_scope) =
+                        self.tcx.adjust_ident_and_get_scope(field, container_def.did(), block);
+
+                    let fields = &container_def.non_enum_variant().fields;
+                    if let Some((index, field)) = fields
+                        .iter_enumerated()
+                        .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == ident)
+                    {
+                        let field_ty = self.field_ty(expr.span, field, substs);
+
+                        // FIXME: DSTs with static alignment should be allowed
+                        self.require_type_is_sized(field_ty, expr.span, traits::MiscObligation);
+
+                        if field.vis.is_accessible_from(def_scope, self.tcx) {
+                            self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
+                        } else {
+                            self.private_field_err(ident, container_def.did()).emit();
+                        }
+
+                        // Save the index of all fields regardless of their visibility in case
+                        // of error recovery.
+                        field_indices.push(index);
+                        current_container = field_ty;
+
+                        continue;
+                    }
+                }
+                ty::Tuple(tys) => {
+                    let fstr = field.as_str();
+
+                    if let Ok(index) = fstr.parse::<usize>() {
+                        if fstr == index.to_string() {
+                            if let Some(&field_ty) = tys.get(index) {
+                                field_indices.push(index.into());
+                                current_container = field_ty;
+
+                                continue;
+                            }
+                        }
+                    }
+                }
+                _ => (),
+            };
+
+            self.no_such_field_err(field, container, expr.hir_id).emit();
+
+            break;
+        }
+
+        self.typeck_results
+            .borrow_mut()
+            .offset_of_data_mut()
+            .insert(expr.hir_id, (container, field_indices));
+
+        self.tcx.types.usize
+    }
 }
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index ee1c6fbfd65..94b6a0f8f47 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -300,6 +300,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
             hir::ExprKind::Continue(..)
             | hir::ExprKind::Lit(..)
             | hir::ExprKind::ConstBlock(..)
+            | hir::ExprKind::OffsetOf(..)
             | hir::ExprKind::Err(_) => {}
 
             hir::ExprKind::Loop(blk, ..) => {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 13a869caa8f..2b5af4bc81b 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -420,9 +420,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ast_c: &hir::AnonConst,
         param_def_id: DefId,
     ) -> ty::Const<'tcx> {
-        let const_def =
-            ty::WithOptConstParam { did: ast_c.def_id, const_param_did: Some(param_def_id) };
-        let c = ty::Const::from_opt_const_arg_anon_const(self.tcx, const_def);
+        let did = ast_c.def_id;
+        self.tcx.feed_anon_const_type(did, self.tcx.type_of(param_def_id));
+        let c = ty::Const::from_anon_const(self.tcx, did);
         self.register_wf_obligation(
             c.into(),
             self.tcx.hir().span(ast_c.hir_id),
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index c6fd0b61035..3ba679df3ed 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -17,7 +17,6 @@ use rustc_infer::infer;
 use rustc_infer::infer::error_reporting::TypeErrCtxt;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
-use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
 use rustc_session::Session;
 use rustc_span::symbol::Ident;
@@ -250,16 +249,12 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
     }
 
     fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
-        if let Some(param) = param {
-            if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() {
-                return ty;
-            }
-            unreachable!()
-        } else {
-            self.next_ty_var(TypeVariableOrigin {
+        match param {
+            Some(param) => self.var_for_def(span, param).as_type().unwrap(),
+            None => self.next_ty_var(TypeVariableOrigin {
                 kind: TypeVariableOriginKind::TypeInference,
                 span,
-            })
+            }),
         }
     }
 
@@ -269,16 +264,12 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
         param: Option<&ty::GenericParamDef>,
         span: Span,
     ) -> Const<'tcx> {
-        if let Some(param) = param {
-            if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() {
-                return ct;
-            }
-            unreachable!()
-        } else {
-            self.next_const_var(
+        match param {
+            Some(param) => self.var_for_def(span, param).as_const().unwrap(),
+            None => self.next_const_var(
                 ty,
                 ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span },
-            )
+            ),
         }
     }
 
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs
index 3e9a9ce1b31..28c44aa5703 100644
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs
+++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs
@@ -215,6 +215,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
             | ExprKind::Continue(..)
             | ExprKind::Ret(..)
             | ExprKind::InlineAsm(..)
+            | ExprKind::OffsetOf(..)
             | ExprKind::Struct(..)
             | ExprKind::Repeat(..)
             | ExprKind::Yield(..)
@@ -485,6 +486,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
             | ExprKind::Field(..)
             | ExprKind::Index(..)
             | ExprKind::InlineAsm(..)
+            | ExprKind::OffsetOf(..)
             | ExprKind::Let(..)
             | ExprKind::Lit(..)
             | ExprKind::Path(..)
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 49da78b18e2..08d3593f91f 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -156,21 +156,9 @@ fn typeck_item_bodies(tcx: TyCtxt<'_>, (): ()) {
     tcx.hir().par_body_owners(|body_owner_def_id| tcx.ensure().typeck(body_owner_def_id));
 }
 
-fn typeck_const_arg<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    (did, param_did): (LocalDefId, DefId),
-) -> &ty::TypeckResults<'tcx> {
-    let fallback = move || tcx.type_of(param_did).subst_identity();
-    typeck_with_fallback(tcx, did, fallback)
-}
-
 fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
-    if let Some(param_did) = tcx.opt_const_param_of(def_id) {
-        tcx.typeck_const_arg((def_id, param_did))
-    } else {
-        let fallback = move || tcx.type_of(def_id.to_def_id()).subst_identity();
-        typeck_with_fallback(tcx, def_id, fallback)
-    }
+    let fallback = move || tcx.type_of(def_id.to_def_id()).subst_identity();
+    typeck_with_fallback(tcx, def_id, fallback)
 }
 
 /// Used only to get `TypeckResults` for type inference during error recovery.
@@ -492,7 +480,6 @@ pub fn provide(providers: &mut Providers) {
     method::provide(providers);
     *providers = Providers {
         typeck_item_bodies,
-        typeck_const_arg,
         typeck,
         diagnostic_only_typeck,
         has_typeck_results,
diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs
index 6c861b5930a..f5fca14eca8 100644
--- a/compiler/rustc_hir_typeck/src/mem_categorization.rs
+++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs
@@ -381,6 +381,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
             | hir::ExprKind::Struct(..)
             | hir::ExprKind::Repeat(..)
             | hir::ExprKind::InlineAsm(..)
+            | hir::ExprKind::OffsetOf(..)
             | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty)),
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index e876fa27593..9432a5840b2 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -70,6 +70,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         wbcx.visit_user_provided_tys();
         wbcx.visit_user_provided_sigs();
         wbcx.visit_generator_interior_types();
+        wbcx.visit_offset_of_container_types();
 
         wbcx.typeck_results.rvalue_scopes =
             mem::take(&mut self.typeck_results.borrow_mut().rvalue_scopes);
@@ -295,7 +296,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
                     self.visit_field_id(field.hir_id);
                 }
             }
-            hir::ExprKind::Field(..) => {
+            hir::ExprKind::Field(..) | hir::ExprKind::OffsetOf(..) => {
                 self.visit_field_id(e.hir_id);
             }
             hir::ExprKind::ConstBlock(anon_const) => {
@@ -682,6 +683,28 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         }
     }
 
+    fn visit_offset_of_container_types(&mut self) {
+        let fcx_typeck_results = self.fcx.typeck_results.borrow();
+        assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
+        let common_hir_owner = fcx_typeck_results.hir_owner;
+
+        for (local_id, &(container, ref indices)) in
+            fcx_typeck_results.offset_of_data().items_in_stable_order()
+        {
+            let hir_id = hir::HirId { owner: common_hir_owner, local_id };
+
+            if cfg!(debug_assertions) && container.needs_infer() {
+                span_bug!(
+                    hir_id.to_span(self.fcx.tcx),
+                    "writeback: `{:?}` has inference variables",
+                    container
+                );
+            };
+
+            self.typeck_results.offset_of_data_mut().insert(hir_id, (container, indices.clone()));
+        }
+    }
+
     fn resolve<T>(&mut self, x: T, span: &dyn Locatable) -> T
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index f298b95ca35..df15cab00b4 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -131,10 +131,9 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
             self.dump_constraints();
         }
 
-        let graph = self.construct_graph();
         self.expansion(&mut var_data);
         self.collect_errors(&mut var_data, errors);
-        self.collect_var_errors(&var_data, &graph, errors);
+        self.collect_var_errors(&var_data, errors);
         var_data
     }
 
@@ -622,7 +621,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
     fn collect_var_errors(
         &self,
         var_data: &LexicalRegionResolutions<'tcx>,
-        graph: &RegionGraph<'tcx>,
         errors: &mut Vec<RegionResolutionError<'tcx>>,
     ) {
         debug!("collect_var_errors, var_data = {:#?}", var_data.values);
@@ -640,6 +638,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         // overlapping locations.
         let mut dup_vec = IndexVec::from_elem_n(None, self.num_vars());
 
+        // Only construct the graph when necessary, because it's moderately
+        // expensive.
+        let mut graph = None;
+
         for (node_vid, value) in var_data.values.iter_enumerated() {
             match *value {
                 VarValue::Empty(_) | VarValue::Value(_) => { /* Inference successful */ }
@@ -672,7 +674,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
                     // influence the constraints on this value for
                     // richer diagnostics in `static_impl_trait`.
 
-                    self.collect_error_for_expanding_node(graph, &mut dup_vec, node_vid, errors);
+                    let g = graph.get_or_insert_with(|| self.construct_graph());
+                    self.collect_error_for_expanding_node(g, &mut dup_vec, node_vid, errors);
                 }
             }
         }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index f263a0773e4..3e80bb906e4 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1500,7 +1500,7 @@ impl<'tcx> InferCtxt<'tcx> {
             Ok(Some(val)) => Ok(self.tcx.mk_const(val, ty)),
             Ok(None) => {
                 let tcx = self.tcx;
-                let def_id = unevaluated.def.did;
+                let def_id = unevaluated.def;
                 span_bug!(
                     tcx.def_span(def_id),
                     "unable to construct a constant value for the unevaluated constant {:?}",
@@ -1547,8 +1547,8 @@ impl<'tcx> InferCtxt<'tcx> {
                     substs = replace_param_and_infer_substs_with_placeholder(tcx, substs);
                 }
             } else {
-                substs = InternalSubsts::identity_for_item(tcx, unevaluated.def.did);
-                param_env = tcx.param_env(unevaluated.def.did);
+                substs = InternalSubsts::identity_for_item(tcx, unevaluated.def);
+                param_env = tcx.param_env(unevaluated.def);
             }
         }
 
diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs
index ff23087fe8d..cb63d2f18b6 100644
--- a/compiler/rustc_infer/src/infer/outlives/components.rs
+++ b/compiler/rustc_infer/src/infer/outlives/components.rs
@@ -143,7 +143,7 @@ fn compute_components<'tcx>(
                     // through and constrain Pi.
                     let mut subcomponents = smallvec![];
                     let mut subvisited = SsoHashSet::new();
-                    compute_components_recursive(tcx, ty.into(), &mut subcomponents, &mut subvisited);
+                    compute_alias_components_recursive(tcx, ty, &mut subcomponents, &mut subvisited);
                     out.push(Component::EscapingAlias(subcomponents.into_iter().collect()));
                 }
             }
@@ -193,7 +193,43 @@ fn compute_components<'tcx>(
 ///
 /// This should not be used to get the components of `parent` itself.
 /// Use [push_outlives_components] instead.
-pub(super) fn compute_components_recursive<'tcx>(
+pub(super) fn compute_alias_components_recursive<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    alias_ty: Ty<'tcx>,
+    out: &mut SmallVec<[Component<'tcx>; 4]>,
+    visited: &mut SsoHashSet<GenericArg<'tcx>>,
+) {
+    let ty::Alias(kind, alias_ty) = alias_ty.kind() else { bug!() };
+    let opt_variances = if *kind == ty::Opaque { tcx.variances_of(alias_ty.def_id) } else { &[] };
+    for (index, child) in alias_ty.substs.iter().enumerate() {
+        if opt_variances.get(index) == Some(&ty::Bivariant) {
+            continue;
+        }
+        if !visited.insert(child) {
+            continue;
+        }
+        match child.unpack() {
+            GenericArgKind::Type(ty) => {
+                compute_components(tcx, ty, out, visited);
+            }
+            GenericArgKind::Lifetime(lt) => {
+                // Ignore late-bound regions.
+                if !lt.is_late_bound() {
+                    out.push(Component::Region(lt));
+                }
+            }
+            GenericArgKind::Const(_) => {
+                compute_components_recursive(tcx, child, out, visited);
+            }
+        }
+    }
+}
+
+/// Collect [Component]s for *all* the substs of `parent`.
+///
+/// This should not be used to get the components of `parent` itself.
+/// Use [push_outlives_components] instead.
+fn compute_components_recursive<'tcx>(
     tcx: TyCtxt<'tcx>,
     parent: GenericArg<'tcx>,
     out: &mut SmallVec<[Component<'tcx>; 4]>,
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index ccf11c61b57..2f5e2e417a6 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -344,12 +344,14 @@ where
         // the problem is to add `T: 'r`, which isn't true. So, if there are no
         // inference variables, we use a verify constraint instead of adding
         // edges, which winds up enforcing the same condition.
+        let is_opaque = alias_ty.kind(self.tcx) == ty::Opaque;
         if approx_env_bounds.is_empty()
             && trait_bounds.is_empty()
-            && (alias_ty.needs_infer() || alias_ty.kind(self.tcx) == ty::Opaque)
+            && (alias_ty.needs_infer() || is_opaque)
         {
             debug!("no declared bounds");
-            self.substs_must_outlive(alias_ty.substs, origin, region);
+            let opt_variances = is_opaque.then(|| self.tcx.variances_of(alias_ty.def_id));
+            self.substs_must_outlive(alias_ty.substs, origin, region, opt_variances);
             return;
         }
 
@@ -395,22 +397,31 @@ where
         self.delegate.push_verify(origin, GenericKind::Alias(alias_ty), region, verify_bound);
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn substs_must_outlive(
         &mut self,
         substs: SubstsRef<'tcx>,
         origin: infer::SubregionOrigin<'tcx>,
         region: ty::Region<'tcx>,
+        opt_variances: Option<&[ty::Variance]>,
     ) {
         let constraint = origin.to_constraint_category();
-        for k in substs {
+        for (index, k) in substs.iter().enumerate() {
             match k.unpack() {
                 GenericArgKind::Lifetime(lt) => {
-                    self.delegate.push_sub_region_constraint(
-                        origin.clone(),
-                        region,
-                        lt,
-                        constraint,
-                    );
+                    let variance = if let Some(variances) = opt_variances {
+                        variances[index]
+                    } else {
+                        ty::Invariant
+                    };
+                    if variance == ty::Invariant {
+                        self.delegate.push_sub_region_constraint(
+                            origin.clone(),
+                            region,
+                            lt,
+                            constraint,
+                        );
+                    }
                 }
                 GenericArgKind::Type(ty) => {
                     self.type_must_outlive(origin.clone(), ty, region, constraint);
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index bae246418b0..e1cb53bc71d 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -1,4 +1,4 @@
-use crate::infer::outlives::components::{compute_components_recursive, Component};
+use crate::infer::outlives::components::{compute_alias_components_recursive, Component};
 use crate::infer::outlives::env::RegionBoundPairs;
 use crate::infer::region_constraints::VerifyIfEq;
 use crate::infer::VerifyBound;
@@ -130,7 +130,12 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
         // see the extensive comment in projection_must_outlive
         let recursive_bound = {
             let mut components = smallvec![];
-            compute_components_recursive(self.tcx, alias_ty_as_ty.into(), &mut components, visited);
+            compute_alias_components_recursive(
+                self.tcx,
+                alias_ty_as_ty.into(),
+                &mut components,
+                visited,
+            );
             self.bound_from_components(&components, visited)
         };
 
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 0e4e20c7cd1..de78f26eec6 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -794,9 +794,14 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
             }
             tcx.ensure().has_ffi_unwind_calls(def_id);
 
-            if tcx.hir().body_const_context(def_id).is_some() {
-                tcx.ensure()
-                    .mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(def_id));
+            // If we need to codegen, ensure that we emit all errors from
+            // `mir_drops_elaborated_and_const_checked` now, to avoid discovering
+            // them later during codegen.
+            if tcx.sess.opts.output_types.should_codegen()
+                || tcx.hir().body_const_context(def_id).is_some()
+            {
+                tcx.ensure().mir_drops_elaborated_and_const_checked(def_id);
+                tcx.ensure().unused_generic_params(ty::InstanceDef::Item(def_id.to_def_id()));
             }
         }
     });
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 10dfd32d418..f5d44d239e0 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -747,7 +747,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(emit_thin_lto, false);
     tracked!(export_executable_symbols, true);
     tracked!(fewer_names, Some(true));
-    tracked!(flatten_format_args, true);
+    tracked!(flatten_format_args, false);
     tracked!(force_unstable_if_unmarked, true);
     tracked!(fuel, Some(("abc".to_string(), 99)));
     tracked!(function_sections, Some(false));
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 55bef6d3b3d..aeb791901bd 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -166,10 +166,8 @@ declare_lint_pass!(BoxPointers => [BOX_POINTERS]);
 impl BoxPointers {
     fn check_heap_type(&self, cx: &LateContext<'_>, span: Span, ty: Ty<'_>) {
         for leaf in ty.walk() {
-            if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
-                if leaf_ty.is_box() {
-                    cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty });
-                }
+            if let GenericArgKind::Type(leaf_ty) = leaf.unpack() && leaf_ty.is_box() {
+                cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty });
             }
         }
     }
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 648a7c6eed6..79253cbc8b4 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -33,6 +33,11 @@ pub fn method_context(cx: &LateContext<'_>, id: LocalDefId) -> MethodLateContext
     }
 }
 
+fn assoc_item_in_trait_impl(cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) -> bool {
+    let item = cx.tcx.associated_item(ii.owner_id);
+    item.trait_item_def_id.is_some()
+}
+
 declare_lint! {
     /// The `non_camel_case_types` lint detects types, variants, traits and
     /// type parameters that don't have camel case names.
@@ -177,6 +182,7 @@ impl EarlyLintPass for NonCamelCaseTypes {
             // trait impls where we should have warned for the trait definition already.
             ast::ItemKind::Impl(box ast::Impl { of_trait: None, items, .. }) => {
                 for it in items {
+                    // FIXME: this doesn't respect `#[allow(..)]` on the item itself.
                     if let ast::AssocItemKind::Type(..) = it.kind {
                         self.check_case(cx, "associated type", &it.ident);
                     }
@@ -494,15 +500,6 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
             hir::ItemKind::Const(..) => {
                 NonUpperCaseGlobals::check_upper_case(cx, "constant", &it.ident);
             }
-            // we only want to check inherent associated consts, trait consts
-            // are linted at def-site.
-            hir::ItemKind::Impl(hir::Impl { of_trait: None, items, .. }) => {
-                for it in *items {
-                    if let hir::AssocItemKind::Const = it.kind {
-                        NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &it.ident);
-                    }
-                }
-            }
             _ => {}
         }
     }
@@ -513,6 +510,12 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
         }
     }
 
+    fn check_impl_item(&mut self, cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) {
+        if let hir::ImplItemKind::Const(..) = ii.kind && !assoc_item_in_trait_impl(cx, ii) {
+            NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ii.ident);
+        }
+    }
+
     fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) {
         // Lint for constants that look like binding identifiers (#7526)
         if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.kind {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 951fb303e3c..601281fddba 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -876,16 +876,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             variant_did,
             ctor,
             data.discr,
-            self.root
-                .tables
-                .children
-                .get(self, index)
-                .expect("fields are not encoded for a variant")
-                .decode(self)
-                .map(|index| ty::FieldDef {
-                    did: self.local_def_id(index),
-                    name: self.item_name(index),
-                    vis: self.get_visibility(index),
+            self.get_associated_item_or_field_def_ids(index)
+                .map(|did| ty::FieldDef {
+                    did,
+                    name: self.item_name(did.index),
+                    vis: self.get_visibility(did.index),
                 })
                 .collect(),
             adt_kind,
@@ -910,7 +905,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         let variants = if let ty::AdtKind::Enum = adt_kind {
             self.root
                 .tables
-                .children
+                .module_children_non_reexports
                 .get(self, item_id)
                 .expect("variants are not encoded for an enum")
                 .decode(self)
@@ -1022,11 +1017,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                 }
             } else {
                 // Iterate over all children.
-                for child_index in self.root.tables.children.get(self, id).unwrap().decode(self) {
-                    // FIXME: Do not encode RPITITs as a part of this list.
-                    if self.root.tables.opt_rpitit_info.get(self, child_index).is_none() {
-                        yield self.get_mod_child(child_index, sess);
-                    }
+                let non_reexports = self.root.tables.module_children_non_reexports.get(self, id);
+                for child_index in non_reexports.unwrap().decode(self) {
+                    yield self.get_mod_child(child_index, sess);
                 }
 
                 let reexports = self.root.tables.module_children_reexports.get(self, id);
@@ -1058,17 +1051,16 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .map_or(false, |ident| ident.name == kw::SelfLower)
     }
 
-    fn get_associated_item_def_ids(
+    fn get_associated_item_or_field_def_ids(
         self,
         id: DefIndex,
-        sess: &'a Session,
     ) -> impl Iterator<Item = DefId> + 'a {
         self.root
             .tables
-            .children
+            .associated_item_or_field_def_ids
             .get(self, id)
-            .expect("associated items not encoded for an item")
-            .decode((self, sess))
+            .unwrap_or_else(|| self.missing("associated_item_or_field_def_ids", id))
+            .decode(self)
             .map(move |child_index| self.local_def_id(child_index))
     }
 
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 31798afb852..141980912b1 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -276,7 +276,7 @@ provide! { tcx, def_id, other, cdata,
         tcx.calculate_dtor(def_id, |_,_| Ok(()))
     }
     associated_item_def_ids => {
-        tcx.arena.alloc_from_iter(cdata.get_associated_item_def_ids(def_id.index, tcx.sess))
+        tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(def_id.index))
     }
     associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) }
     inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
@@ -516,14 +516,6 @@ impl CStore {
         self.get_crate_data(def.krate).get_ctor(def.index)
     }
 
-    pub fn module_children_untracked<'a>(
-        &'a self,
-        def_id: DefId,
-        sess: &'a Session,
-    ) -> impl Iterator<Item = ModChild> + 'a {
-        self.get_crate_data(def_id.krate).get_module_children(def_id.index, sess)
-    }
-
     pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
         let _prof_timer = sess.prof.generic_activity("metadata_load_macro");
 
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index d6500cd93a7..17a9daee7d0 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -824,6 +824,7 @@ fn should_encode_span(def_kind: DefKind) -> bool {
         | DefKind::AssocTy
         | DefKind::TyParam
         | DefKind::ConstParam
+        | DefKind::LifetimeParam
         | DefKind::Fn
         | DefKind::Const
         | DefKind::Static(_)
@@ -840,10 +841,7 @@ fn should_encode_span(def_kind: DefKind) -> bool {
         | DefKind::Impl { .. }
         | DefKind::Closure
         | DefKind::Generator => true,
-        DefKind::ForeignMod
-        | DefKind::ImplTraitPlaceholder
-        | DefKind::LifetimeParam
-        | DefKind::GlobalAsm => false,
+        DefKind::ForeignMod | DefKind::ImplTraitPlaceholder | DefKind::GlobalAsm => false,
     }
 }
 
@@ -1367,7 +1365,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
         if adt_def.is_enum() {
             let module_children = tcx.module_children_non_reexports(local_def_id);
-            record_array!(self.tables.children[def_id] <-
+            record_array!(self.tables.module_children_non_reexports[def_id] <-
                 module_children.iter().map(|def_id| def_id.local_def_index));
         } else {
             // For non-enum, there is only one variant, and its def_id is the adt's.
@@ -1385,7 +1383,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             record!(self.tables.variant_data[variant.def_id] <- data);
 
             self.tables.constness.set_some(variant.def_id.index, hir::Constness::Const);
-            record_array!(self.tables.children[variant.def_id] <- variant.fields.iter().map(|f| {
+            record_array!(self.tables.associated_item_or_field_def_ids[variant.def_id] <- variant.fields.iter().map(|f| {
                 assert!(f.did.is_local());
                 f.did.index
             }));
@@ -1415,7 +1413,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
         } else {
             let non_reexports = tcx.module_children_non_reexports(local_def_id);
-            record_array!(self.tables.children[def_id] <-
+            record_array!(self.tables.module_children_non_reexports[def_id] <-
                 non_reexports.iter().map(|def_id| def_id.local_def_index));
 
             record_defaulted_array!(self.tables.module_children_reexports[def_id] <-
@@ -1539,8 +1537,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             }
             record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id));
 
-            let instance =
-                ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id()));
+            let instance = ty::InstanceDef::Item(def_id.to_def_id());
             let unused = tcx.unused_generic_params(instance);
             self.tables.unused_generic_params.set(def_id.local_def_index, unused);
         }
@@ -1618,7 +1615,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         debug!("EncodeContext::encode_info_for_item({:?})", def_id);
 
         let record_associated_item_def_ids = |this: &mut Self, def_ids: &[DefId]| {
-            record_array!(this.tables.children[def_id] <- def_ids.iter().map(|&def_id| {
+            record_array!(this.tables.associated_item_or_field_def_ids[def_id] <- def_ids.iter().map(|&def_id| {
                 assert!(def_id.is_local());
                 def_id.index
             }))
@@ -1679,6 +1676,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hir::ItemKind::Trait(..) => {
                 record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
 
+                let module_children = tcx.module_children_non_reexports(item.owner_id.def_id);
+                record_array!(self.tables.module_children_non_reexports[def_id] <-
+                    module_children.iter().map(|def_id| def_id.local_def_index));
+
                 let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
                 record_associated_item_def_ids(self, associated_item_def_ids);
                 for &item_def_id in associated_item_def_ids {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index a6a34765324..f2302c0ad43 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -361,7 +361,8 @@ define_tables! {
 
 - optional:
     attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
-    children: Table<DefIndex, LazyArray<DefIndex>>,
+    module_children_non_reexports: Table<DefIndex, LazyArray<DefIndex>>,
+    associated_item_or_field_def_ids: Table<DefIndex, LazyArray<DefIndex>>,
     opt_def_kind: Table<DefIndex, DefKind>,
     visibility: Table<DefIndex, LazyValue<ty::Visibility<DefIndex>>>,
     def_span: Table<DefIndex, LazyValue<Span>>,
diff --git a/compiler/rustc_middle/src/mir/graphviz.rs b/compiler/rustc_middle/src/mir/graphviz.rs
index cf6d46e1e2c..2de73db3a3c 100644
--- a/compiler/rustc_middle/src/mir/graphviz.rs
+++ b/compiler/rustc_middle/src/mir/graphviz.rs
@@ -16,19 +16,16 @@ where
 {
     let def_ids = dump_mir_def_ids(tcx, single);
 
-    let mirs =
-        def_ids
-            .iter()
-            .flat_map(|def_id| {
-                if tcx.is_const_fn_raw(*def_id) {
-                    vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)]
-                } else {
-                    vec![tcx.instance_mir(ty::InstanceDef::Item(ty::WithOptConstParam::unknown(
-                        *def_id,
-                    )))]
-                }
-            })
-            .collect::<Vec<_>>();
+    let mirs = def_ids
+        .iter()
+        .flat_map(|def_id| {
+            if tcx.is_const_fn_raw(*def_id) {
+                vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)]
+            } else {
+                vec![tcx.instance_mir(ty::InstanceDef::Item(*def_id))]
+            }
+        })
+        .collect::<Vec<_>>();
 
     let use_subgraphs = mirs.len() > 1;
     if use_subgraphs {
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 856d821a5cf..ed4ee93e97d 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -42,7 +42,7 @@ impl<'tcx> TyCtxt<'tcx> {
         span: Option<Span>,
     ) -> EvalToConstValueResult<'tcx> {
         // Cannot resolve `Unevaluated` constants that contain inference
-        // variables. We reject those here since `resolve_opt_const_arg`
+        // variables. We reject those here since `resolve`
         // would fail otherwise.
         //
         // When trying to evaluate constants containing inference variables,
@@ -51,7 +51,7 @@ impl<'tcx> TyCtxt<'tcx> {
             bug!("did not expect inference variables here");
         }
 
-        match ty::Instance::resolve_opt_const_arg(
+        match ty::Instance::resolve(
             self, param_env,
             // FIXME: maybe have a separate version for resolving mir::UnevaluatedConst?
             ct.def, ct.substs,
@@ -73,7 +73,7 @@ impl<'tcx> TyCtxt<'tcx> {
         span: Option<Span>,
     ) -> EvalToValTreeResult<'tcx> {
         // Cannot resolve `Unevaluated` constants that contain inference
-        // variables. We reject those here since `resolve_opt_const_arg`
+        // variables. We reject those here since `resolve`
         // would fail otherwise.
         //
         // When trying to evaluate constants containing inference variables,
@@ -82,7 +82,7 @@ impl<'tcx> TyCtxt<'tcx> {
             bug!("did not expect inference variables here");
         }
 
-        match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
+        match ty::Instance::resolve(self, param_env, ct.def, ct.substs) {
             Ok(Some(instance)) => {
                 let cid = GlobalId { instance, promoted: None };
                 self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| {
@@ -94,14 +94,14 @@ impl<'tcx> TyCtxt<'tcx> {
                     // used generic parameters is a bug of evaluation, so checking for it
                     // here does feel somewhat sensible.
                     if !self.features().generic_const_exprs && ct.substs.has_non_region_param() {
-                        assert!(matches!(self.def_kind(ct.def.did), DefKind::AnonConst));
-                        let mir_body = self.mir_for_ctfe_opt_const_arg(ct.def);
+                        assert!(matches!(self.def_kind(ct.def), DefKind::AnonConst));
+                        let mir_body = self.mir_for_ctfe(ct.def);
                         if mir_body.is_polymorphic {
-                            let Some(local_def_id) = ct.def.did.as_local() else { return };
+                            let Some(local_def_id) = ct.def.as_local() else { return };
                             self.struct_span_lint_hir(
                                 lint::builtin::CONST_EVALUATABLE_UNCHECKED,
                                 self.hir().local_def_id_to_hir_id(local_def_id),
-                                self.def_span(ct.def.did),
+                                self.def_span(ct.def),
                                 "cannot use constants which depend on generic parameters in types",
                                 |err| err,
                             )
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index f985aae9a22..6b6a2e561f5 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -191,20 +191,13 @@ pub struct MirSource<'tcx> {
 
 impl<'tcx> MirSource<'tcx> {
     pub fn item(def_id: DefId) -> Self {
-        MirSource {
-            instance: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
-            promoted: None,
-        }
+        MirSource { instance: InstanceDef::Item(def_id), promoted: None }
     }
 
     pub fn from_instance(instance: InstanceDef<'tcx>) -> Self {
         MirSource { instance, promoted: None }
     }
 
-    pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> {
-        self.instance.with_opt_param()
-    }
-
     #[inline]
     pub fn def_id(&self) -> DefId {
         self.instance.def_id()
@@ -2048,7 +2041,11 @@ impl<'tcx> Debug for Rvalue<'tcx> {
             }
             UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
             Discriminant(ref place) => write!(fmt, "discriminant({:?})", place),
-            NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t),
+            NullaryOp(ref op, ref t) => match op {
+                NullOp::SizeOf => write!(fmt, "SizeOf({:?})", t),
+                NullOp::AlignOf => write!(fmt, "AlignOf({:?})", t),
+                NullOp::OffsetOf(fields) => write!(fmt, "OffsetOf({:?}, {:?})", t, fields),
+            },
             ThreadLocalRef(did) => ty::tls::with(|tcx| {
                 let muta = tcx.static_mutability(did).unwrap().prefix_str();
                 write!(fmt, "&/*tls*/ {}{}", muta, tcx.def_path_str(did))
@@ -2436,16 +2433,6 @@ impl<'tcx> ConstantKind<'tcx> {
         Self::Val(val, ty)
     }
 
-    /// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly
-    /// converted to a constant, everything else becomes `Unevaluated`.
-    pub fn from_anon_const(
-        tcx: TyCtxt<'tcx>,
-        def_id: LocalDefId,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> Self {
-        Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id), param_env)
-    }
-
     #[instrument(skip(tcx), level = "debug", ret)]
     pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
         let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
@@ -2485,28 +2472,25 @@ impl<'tcx> ConstantKind<'tcx> {
             ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
                 .substs;
 
-        let uneval = UnevaluatedConst {
-            def: ty::WithOptConstParam::unknown(def_id).to_global(),
-            substs,
-            promoted: None,
-        };
+        let uneval = UnevaluatedConst { def: def_id.to_def_id(), substs, promoted: None };
         debug_assert!(!uneval.has_free_regions());
 
         Self::Unevaluated(uneval, ty)
     }
 
+    /// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly
+    /// converted to a constant, everything else becomes `Unevaluated`.
     #[instrument(skip(tcx), level = "debug", ret)]
-    fn from_opt_const_arg_anon_const(
+    pub fn from_anon_const(
         tcx: TyCtxt<'tcx>,
-        def: ty::WithOptConstParam<LocalDefId>,
+        def: LocalDefId,
         param_env: ty::ParamEnv<'tcx>,
     ) -> Self {
-        let body_id = match tcx.hir().get_by_def_id(def.did) {
+        let body_id = match tcx.hir().get_by_def_id(def) {
             hir::Node::AnonConst(ac) => ac.body,
-            _ => span_bug!(
-                tcx.def_span(def.did.to_def_id()),
-                "from_anon_const can only process anonymous constants"
-            ),
+            _ => {
+                span_bug!(tcx.def_span(def), "from_anon_const can only process anonymous constants")
+            }
         };
 
         let expr = &tcx.hir().body(body_id).value;
@@ -2522,7 +2506,7 @@ impl<'tcx> ConstantKind<'tcx> {
         };
         debug!("expr.kind: {:?}", expr.kind);
 
-        let ty = tcx.type_of(def.def_id_for_type_of()).subst_identity();
+        let ty = tcx.type_of(def).subst_identity();
         debug!(?ty);
 
         // FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
@@ -2549,7 +2533,7 @@ impl<'tcx> ConstantKind<'tcx> {
             _ => {}
         }
 
-        let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
+        let hir_id = tcx.hir().local_def_id_to_hir_id(def);
         let parent_substs = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id)
             && let Some(parent_did) = parent_hir_id.as_owner()
         {
@@ -2559,15 +2543,14 @@ impl<'tcx> ConstantKind<'tcx> {
         };
         debug!(?parent_substs);
 
-        let did = def.did.to_def_id();
+        let did = def.to_def_id();
         let child_substs = InternalSubsts::identity_for_item(tcx, did);
         let substs =
             tcx.mk_substs_from_iter(parent_substs.into_iter().chain(child_substs.into_iter()));
         debug!(?substs);
 
-        let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
-        let span = tcx.hir().span(hir_id);
-        let uneval = UnevaluatedConst::new(def.to_global(), substs);
+        let span = tcx.def_span(def);
+        let uneval = UnevaluatedConst::new(did, substs);
         debug!(?span, ?param_env);
 
         match tcx.const_eval_resolve(param_env, uneval, Some(span)) {
@@ -2581,8 +2564,8 @@ impl<'tcx> ConstantKind<'tcx> {
                 // new unevaluated const and error hard later in codegen
                 Self::Unevaluated(
                     UnevaluatedConst {
-                        def: def.to_global(),
-                        substs: InternalSubsts::identity_for_item(tcx, def.did),
+                        def: did,
+                        substs: InternalSubsts::identity_for_item(tcx, did),
                         promoted: None,
                     },
                     ty,
@@ -2607,7 +2590,7 @@ impl<'tcx> ConstantKind<'tcx> {
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
 #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
 pub struct UnevaluatedConst<'tcx> {
-    pub def: ty::WithOptConstParam<DefId>,
+    pub def: DefId,
     pub substs: SubstsRef<'tcx>,
     pub promoted: Option<Promoted>,
 }
@@ -2623,10 +2606,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
 
 impl<'tcx> UnevaluatedConst<'tcx> {
     #[inline]
-    pub fn new(
-        def: ty::WithOptConstParam<DefId>,
-        substs: SubstsRef<'tcx>,
-    ) -> UnevaluatedConst<'tcx> {
+    pub fn new(def: DefId, substs: SubstsRef<'tcx>) -> UnevaluatedConst<'tcx> {
         UnevaluatedConst { def, substs, promoted: Default::default() }
     }
 }
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index a9468a90b53..67235f0f524 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -373,7 +373,7 @@ impl<'tcx> CodegenUnit<'tcx> {
                             // instances into account. The others don't matter for
                             // the codegen tests and can even make item order
                             // unstable.
-                            InstanceDef::Item(def) => def.did.as_local().map(Idx::index),
+                            InstanceDef::Item(def) => def.as_local().map(Idx::index),
                             InstanceDef::VTableShim(..)
                             | InstanceDef::ReifyShim(..)
                             | InstanceDef::Intrinsic(..)
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 7e51953599d..89510bbb3aa 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -298,8 +298,7 @@ pub fn write_mir_pretty<'tcx>(
             // are shared between mir_for_ctfe and optimized_mir
             write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w)?;
         } else {
-            let instance_mir =
-                tcx.instance_mir(ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)));
+            let instance_mir = tcx.instance_mir(ty::InstanceDef::Item(def_id));
             render_body(w, instance_mir)?;
         }
     }
@@ -464,11 +463,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
                 ConstantKind::Ty(ct) => match ct.kind() {
                     ty::ConstKind::Param(p) => format!("Param({})", p),
                     ty::ConstKind::Unevaluated(uv) => {
-                        format!(
-                            "Unevaluated({}, {:?})",
-                            self.tcx.def_path_str(uv.def.did),
-                            uv.substs,
-                        )
+                        format!("Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.substs,)
                     }
                     ty::ConstKind::Value(val) => format!("Value({})", fmt_valtree(&val)),
                     ty::ConstKind::Error(_) => "Error".to_string(),
@@ -481,7 +476,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
                 ConstantKind::Unevaluated(uv, _) => {
                     format!(
                         "Unevaluated({}, {:?}, {:?})",
-                        self.tcx.def_path_str(uv.def.did),
+                        self.tcx.def_path_str(uv.def),
                         uv.substs,
                         uv.promoted,
                     )
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index cfdf1dcf5c0..17eaf3e08d8 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -1,12 +1,12 @@
 //! Values computed by queries that use MIR.
 
-use crate::mir::{Body, ConstantKind, Promoted};
+use crate::mir::ConstantKind;
 use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::unord::UnordSet;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::LocalDefId;
 use rustc_index::bit_set::BitMatrix;
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_span::Span;
@@ -454,42 +454,3 @@ pub struct CoverageInfo {
     /// The total number of coverage region counter expressions added to the MIR `Body`.
     pub num_expressions: u32,
 }
-
-/// Shims which make dealing with `WithOptConstParam` easier.
-///
-/// For more information on why this is needed, consider looking
-/// at the docs for `WithOptConstParam` itself.
-impl<'tcx> TyCtxt<'tcx> {
-    #[inline]
-    pub fn mir_const_qualif_opt_const_arg(
-        self,
-        def: ty::WithOptConstParam<LocalDefId>,
-    ) -> ConstQualifs {
-        if let Some(param_did) = def.const_param_did {
-            self.mir_const_qualif_const_arg((def.did, param_did))
-        } else {
-            self.mir_const_qualif(def.did)
-        }
-    }
-
-    #[inline]
-    pub fn promoted_mir_opt_const_arg(
-        self,
-        def: ty::WithOptConstParam<DefId>,
-    ) -> &'tcx IndexVec<Promoted, Body<'tcx>> {
-        if let Some((did, param_did)) = def.as_const_arg() {
-            self.promoted_mir_of_const_arg((did, param_did))
-        } else {
-            self.promoted_mir(def.did)
-        }
-    }
-
-    #[inline]
-    pub fn mir_for_ctfe_opt_const_arg(self, def: ty::WithOptConstParam<DefId>) -> &'tcx Body<'tcx> {
-        if let Some((did, param_did)) = def.as_const_arg() {
-            self.mir_for_ctfe_of_const_arg((did, param_did))
-        } else {
-            self.mir_for_ctfe(def.did)
-        }
-    }
-}
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index c38a347809f..d7d0366e101 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1115,7 +1115,7 @@ pub enum Rvalue<'tcx> {
     CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
 
     /// Computes a value as described by the operation.
-    NullaryOp(NullOp, Ty<'tcx>),
+    NullaryOp(NullOp<'tcx>, Ty<'tcx>),
 
     /// Exactly like `BinaryOp`, but less operands.
     ///
@@ -1211,12 +1211,14 @@ pub enum AggregateKind<'tcx> {
     Generator(DefId, SubstsRef<'tcx>, hir::Movability),
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
-pub enum NullOp {
+#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
+pub enum NullOp<'tcx> {
     /// Returns the size of a value of that type
     SizeOf,
     /// Returns the minimum alignment of a type
     AlignOf,
+    /// Returns the offset of a field
+    OffsetOf(&'tcx List<FieldIdx>),
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 4f00abf7fab..5ca82413448 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -188,7 +188,9 @@ impl<'tcx> Rvalue<'tcx> {
             }
             Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx),
             Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx),
-            Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => tcx.types.usize,
+            Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
+                tcx.types.usize
+            }
             Rvalue::Aggregate(ref ak, ref ops) => match **ak {
                 AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64),
                 AggregateKind::Tuple => {
diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs
index ace856b9f95..06874741bb0 100644
--- a/compiler/rustc_middle/src/mir/type_foldable.rs
+++ b/compiler/rustc_middle/src/mir/type_foldable.rs
@@ -16,7 +16,6 @@ TrivialTypeTraversalAndLiftImpls! {
     UserTypeAnnotationIndex,
     BorrowKind,
     CastKind,
-    NullOp,
     hir::Movability,
     BasicBlock,
     SwitchTargets,
@@ -26,6 +25,7 @@ TrivialTypeTraversalAndLiftImpls! {
 
 TrivialTypeTraversalImpls! {
     ConstValue<'tcx>,
+    NullOp<'tcx>,
 }
 
 impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [InlineAsmTemplatePiece] {
diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs
index 23b28ac5ca9..fa62b7f32b1 100644
--- a/compiler/rustc_middle/src/query/keys.rs
+++ b/compiler/rustc_middle/src/query/keys.rs
@@ -174,14 +174,6 @@ impl AsLocalKey for DefId {
     }
 }
 
-impl Key for ty::WithOptConstParam<LocalDefId> {
-    type CacheSelector = DefaultCacheSelector<Self>;
-
-    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        self.did.default_span(tcx)
-    }
-}
-
 impl Key for SimplifiedType {
     type CacheSelector = DefaultCacheSelector<Self>;
 
@@ -313,7 +305,7 @@ impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) {
     type CacheSelector = DefaultCacheSelector<Self>;
 
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
-        (self.0).def.did.default_span(tcx)
+        (self.0).def.default_span(tcx)
     }
 }
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 7e26e05025f..1c370b29961 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -127,29 +127,6 @@ rustc_queries! {
         desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
-    /// Computes the `DefId` of the corresponding const parameter in case the `key` is a
-    /// const argument and returns `None` otherwise.
-    ///
-    /// ```ignore (incomplete)
-    /// let a = foo::<7>();
-    /// //            ^ Calling `opt_const_param_of` for this argument,
-    ///
-    /// fn foo<const N: usize>()
-    /// //           ^ returns this `DefId`.
-    ///
-    /// fn bar() {
-    /// // ^ While calling `opt_const_param_of` for other bodies returns `None`.
-    /// }
-    /// ```
-    // It looks like caching this query on disk actually slightly
-    // worsened performance in #74376.
-    //
-    // Once const generics are more prevalently used, we might want to
-    // consider only caching calls returning `Some`.
-    query opt_const_param_of(key: LocalDefId) -> Option<DefId> {
-        desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) }
-    }
-
     /// Given the def_id of a const-generic parameter, computes the associated default const
     /// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`.
     query const_param_default(param: DefId) -> ty::EarlyBinder<ty::Const<'tcx>> {
@@ -369,26 +346,24 @@ rustc_queries! {
     }
 
     /// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`.
-    query thir_body(key: ty::WithOptConstParam<LocalDefId>)
-        -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed>
-    {
+    query thir_body(key: LocalDefId) -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> {
         // Perf tests revealed that hashing THIR is inefficient (see #85729).
         no_hash
-        desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.did.to_def_id()) }
+        desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
     /// Create a THIR tree for debugging.
-    query thir_tree(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx String {
+    query thir_tree(key: LocalDefId) -> &'tcx String {
         no_hash
         arena_cache
-        desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.did.to_def_id()) }
+        desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
     /// Create a list-like THIR representation for debugging.
-    query thir_flat(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx String {
+    query thir_flat(key: LocalDefId) -> &'tcx String {
         no_hash
         arena_cache
-        desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key.did.to_def_id()) }
+        desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
     /// Set of all the `DefId`s in this crate that have MIR associated with
@@ -407,31 +382,19 @@ rustc_queries! {
         cache_on_disk_if { key.is_local() }
         separate_provide_extern
     }
-    query mir_const_qualif_const_arg(
-        key: (LocalDefId, DefId)
-    ) -> mir::ConstQualifs {
-        desc {
-            |tcx| "const checking the const argument `{}`",
-            tcx.def_path_str(key.0.to_def_id())
-        }
-    }
 
     /// Fetch the MIR for a given `DefId` right after it's built - this includes
     /// unreachable code.
-    query mir_built(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> {
-        desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.did.to_def_id()) }
+    query mir_built(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
+        desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
     /// Fetch the MIR for a given `DefId` up till the point where it is
     /// ready for const qualification.
     ///
     /// See the README for the `mir` module for details.
-    query mir_const(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> {
-        desc {
-            |tcx| "preparing {}`{}` for borrow checking",
-            if key.const_param_did.is_some() { "the const argument " } else { "" },
-            tcx.def_path_str(key.did.to_def_id()),
-        }
+    query mir_const(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
+        desc { |tcx| "preparing `{}` for borrow checking", tcx.def_path_str(key.to_def_id()) }
         no_hash
     }
 
@@ -444,22 +407,10 @@ rustc_queries! {
         }
         separate_provide_extern
     }
-    /// Try to build an abstract representation of the given constant.
-    query thir_abstract_const_of_const_arg(
-        key: (LocalDefId, DefId)
-    ) -> Result<Option<ty::Const<'tcx>>, ErrorGuaranteed> {
-        desc {
-            |tcx|
-            "building an abstract representation for the const argument `{}`",
-            tcx.def_path_str(key.0.to_def_id()),
-        }
-    }
 
-    query mir_drops_elaborated_and_const_checked(
-        key: ty::WithOptConstParam<LocalDefId>
-    ) -> &'tcx Steal<mir::Body<'tcx>> {
+    query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
         no_hash
-        desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.did.to_def_id()) }
+        desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
     query mir_for_ctfe(
@@ -470,24 +421,12 @@ rustc_queries! {
         separate_provide_extern
     }
 
-    query mir_for_ctfe_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> {
-        desc {
-            |tcx| "caching MIR for CTFE of the const argument `{}`",
-            tcx.def_path_str(key.0.to_def_id())
-        }
-    }
-
-    query mir_promoted(key: ty::WithOptConstParam<LocalDefId>) ->
-        (
-            &'tcx Steal<mir::Body<'tcx>>,
-            &'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>>
-        ) {
+    query mir_promoted(key: LocalDefId) -> (
+        &'tcx Steal<mir::Body<'tcx>>,
+        &'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>>
+    ) {
         no_hash
-        desc {
-            |tcx| "processing MIR for {}`{}`",
-            if key.const_param_did.is_some() { "the const argument " } else { "" },
-            tcx.def_path_str(key.did.to_def_id()),
-        }
+        desc { |tcx| "promoting constants in MIR for `{}`", tcx.def_path_str(key.to_def_id()) }
     }
 
     query closure_typeinfo(key: LocalDefId) -> ty::ClosureTypeInfo<'tcx> {
@@ -544,14 +483,6 @@ rustc_queries! {
         cache_on_disk_if { key.is_local() }
         separate_provide_extern
     }
-    query promoted_mir_of_const_arg(
-        key: (LocalDefId, DefId)
-    ) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> {
-        desc {
-            |tcx| "optimizing promoted MIR for the const argument `{}`",
-            tcx.def_path_str(key.0.to_def_id()),
-        }
-    }
 
     /// Erases regions from `ty` to yield a new type.
     /// Normally you would just use `tcx.erase_regions(value)`,
@@ -739,9 +670,10 @@ rustc_queries! {
         desc { "computing the inferred outlives predicates for items in this crate" }
     }
 
-    /// Maps from an impl/trait `DefId` to a list of the `DefId`s of its items.
+    /// Maps from an impl/trait or struct/variant `DefId`
+    /// to a list of the `DefId`s of its associated items or fields.
     query associated_item_def_ids(key: DefId) -> &'tcx [DefId] {
-        desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) }
+        desc { |tcx| "collecting associated items or fields of `{}`", tcx.def_path_str(key) }
         cache_on_disk_if { key.is_local() }
         separate_provide_extern
     }
@@ -840,12 +772,6 @@ rustc_queries! {
         desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) }
         cache_on_disk_if { true }
     }
-    query unsafety_check_result_for_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::UnsafetyCheckResult {
-        desc {
-            |tcx| "unsafety-checking the const argument `{}`",
-            tcx.def_path_str(key.0.to_def_id())
-        }
-    }
 
     /// Unsafety-check this `LocalDefId` with THIR unsafeck. This should be
     /// used with `-Zthir-unsafeck`.
@@ -853,12 +779,6 @@ rustc_queries! {
         desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) }
         cache_on_disk_if { true }
     }
-    query thir_check_unsafety_for_const_arg(key: (LocalDefId, DefId)) {
-        desc {
-            |tcx| "unsafety-checking the const argument `{}`",
-            tcx.def_path_str(key.0.to_def_id())
-        }
-    }
 
     /// Returns the types assumed to be well formed while "inside" of the given item.
     ///
@@ -960,14 +880,6 @@ rustc_queries! {
         desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) }
         cache_on_disk_if { true }
     }
-    query typeck_const_arg(
-        key: (LocalDefId, DefId)
-    ) -> &'tcx ty::TypeckResults<'tcx> {
-        desc {
-            |tcx| "type-checking the const argument `{}`",
-            tcx.def_path_str(key.0.to_def_id()),
-        }
-    }
     query diagnostic_only_typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> {
         desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) }
         cache_on_disk_if { true }
@@ -992,12 +904,6 @@ rustc_queries! {
         desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key.to_def_id()) }
         cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) }
     }
-    query mir_borrowck_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::BorrowCheckResult<'tcx> {
-        desc {
-            |tcx| "borrow-checking the const argument`{}`",
-            tcx.def_path_str(key.0.to_def_id())
-        }
-    }
 
     /// Gets a complete map from all types to their inherent impls.
     /// Not meant to be used directly outside of coherence.
@@ -2117,15 +2023,6 @@ rustc_queries! {
         desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
     }
 
-    query resolve_instance_of_const_arg(
-        key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)>
-    ) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> {
-        desc {
-            "resolving instance of the const argument `{}`",
-            ty::Instance::new(key.value.0.to_def_id(), key.value.2),
-        }
-    }
-
     query reveal_opaque_types_in_bounds(key: &'tcx ty::List<ty::Predicate<'tcx>>) -> &'tcx ty::List<ty::Predicate<'tcx>> {
         desc { "revealing opaque types in `{:?}`", key }
     }
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 7d79a13d3fd..8700a98b365 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -20,7 +20,7 @@ use rustc_middle::mir::interpret::AllocId;
 use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Mutability, UnOp};
 use rustc_middle::ty::adjustment::PointerCast;
 use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, AdtDef, FnSig, Ty, UpvarSubsts};
+use rustc_middle::ty::{self, AdtDef, FnSig, List, Ty, UpvarSubsts};
 use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{sym, Span, Symbol, DUMMY_SP};
@@ -481,6 +481,11 @@ pub enum ExprKind<'tcx> {
     },
     /// Inline assembly, i.e. `asm!()`.
     InlineAsm(Box<InlineAsmExpr<'tcx>>),
+    /// Field offset (`offset_of!`)
+    OffsetOf {
+        container: Ty<'tcx>,
+        fields: &'tcx List<FieldIdx>,
+    },
     /// An expression taking a reference to a thread local.
     ThreadLocalRef(DefId),
     /// A `yield` expression.
@@ -929,8 +934,8 @@ mod size_asserts {
     static_assert_size!(Block, 56);
     static_assert_size!(Expr<'_>, 64);
     static_assert_size!(ExprKind<'_>, 40);
-    static_assert_size!(Pat<'_>, 72);
-    static_assert_size!(PatKind<'_>, 56);
+    static_assert_size!(Pat<'_>, 64);
+    static_assert_size!(PatKind<'_>, 48);
     static_assert_size!(Stmt<'_>, 56);
     static_assert_size!(StmtKind<'_>, 48);
     // tidy-alphabetical-end
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 5614528c4cb..5c7ec31cf93 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -160,6 +160,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
                 }
             }
         }
+        OffsetOf { container: _, fields: _ } => {}
         ThreadLocalRef(_) => {}
         Yield { value } => visitor.visit_expr(&visitor.thir()[value]),
     }
diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs
index 223b763e34b..029cf793ad8 100644
--- a/compiler/rustc_middle/src/ty/abstract_const.rs
+++ b/compiler/rustc_middle/src/ty/abstract_const.rs
@@ -36,15 +36,8 @@ pub type BoundAbstractConst<'tcx> = Result<Option<EarlyBinder<ty::Const<'tcx>>>,
 
 impl<'tcx> TyCtxt<'tcx> {
     /// Returns a const without substs applied
-    pub fn bound_abstract_const(
-        self,
-        uv: ty::WithOptConstParam<DefId>,
-    ) -> BoundAbstractConst<'tcx> {
-        let ac = if let Some((did, param_did)) = uv.as_const_arg() {
-            self.thir_abstract_const_of_const_arg((did, param_did))
-        } else {
-            self.thir_abstract_const(uv.did)
-        };
+    pub fn bound_abstract_const(self, uv: DefId) -> BoundAbstractConst<'tcx> {
+        let ac = self.thir_abstract_const(uv);
         Ok(ac?.map(|ac| EarlyBinder(ac)))
     }
 
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 8ef4a46a733..5454d406dd1 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -19,6 +19,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::ty::TyCtxt;
 use rustc_serialize::{Decodable, Encodable};
 use rustc_span::Span;
+use rustc_target::abi::FieldIdx;
 pub use rustc_type_ir::{TyDecoder, TyEncoder};
 use std::hash::Hash;
 use std::intrinsics;
@@ -401,6 +402,15 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty
     }
 }
 
+impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<FieldIdx> {
+    fn decode(decoder: &mut D) -> &'tcx Self {
+        let len = decoder.read_usize();
+        decoder
+            .interner()
+            .mk_fields_from_iter((0..len).map::<FieldIdx, _>(|_| Decodable::decode(decoder)))
+    }
+}
+
 impl_decodable_via_ref! {
     &'tcx ty::TypeckResults<'tcx>,
     &'tcx ty::List<Ty<'tcx>>,
@@ -412,6 +422,7 @@ impl_decodable_via_ref! {
     &'tcx mir::coverage::CodeRegion,
     &'tcx ty::List<ty::BoundVariableKind>,
     &'tcx ty::List<ty::Predicate<'tcx>>,
+    &'tcx ty::List<FieldIdx>,
 }
 
 #[macro_export]
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index bcedae233d9..0a191ff7626 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -53,19 +53,12 @@ impl<'tcx> Const<'tcx> {
 
     /// Literals and const generic parameters are eagerly converted to a constant, everything else
     /// becomes `Unevaluated`.
-    pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
-        Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id))
-    }
-
     #[instrument(skip(tcx), level = "debug")]
-    pub fn from_opt_const_arg_anon_const(
-        tcx: TyCtxt<'tcx>,
-        def: ty::WithOptConstParam<LocalDefId>,
-    ) -> Self {
-        let body_id = match tcx.hir().get_by_def_id(def.did) {
+    pub fn from_anon_const(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self {
+        let body_id = match tcx.hir().get_by_def_id(def) {
             hir::Node::AnonConst(ac) => ac.body,
             _ => span_bug!(
-                tcx.def_span(def.did.to_def_id()),
+                tcx.def_span(def.to_def_id()),
                 "from_anon_const can only process anonymous constants"
             ),
         };
@@ -73,17 +66,14 @@ impl<'tcx> Const<'tcx> {
         let expr = &tcx.hir().body(body_id).value;
         debug!(?expr);
 
-        let ty = tcx
-            .type_of(def.def_id_for_type_of())
-            .no_bound_vars()
-            .expect("const parameter types cannot be generic");
+        let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic");
 
         match Self::try_eval_lit_or_param(tcx, ty, expr) {
             Some(v) => v,
             None => tcx.mk_const(
                 ty::UnevaluatedConst {
-                    def: def.to_global(),
-                    substs: InternalSubsts::identity_for_item(tcx, def.did),
+                    def: def.to_def_id(),
+                    substs: InternalSubsts::identity_for_item(tcx, def.to_def_id()),
                 },
                 ty,
             ),
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 560caa041a7..1ac2cd13982 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -17,7 +17,7 @@ use super::ScalarInt;
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
 #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
 pub struct UnevaluatedConst<'tcx> {
-    pub def: ty::WithOptConstParam<DefId>,
+    pub def: DefId,
     pub substs: SubstsRef<'tcx>,
 }
 
@@ -36,10 +36,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
 
 impl<'tcx> UnevaluatedConst<'tcx> {
     #[inline]
-    pub fn new(
-        def: ty::WithOptConstParam<DefId>,
-        substs: SubstsRef<'tcx>,
-    ) -> UnevaluatedConst<'tcx> {
+    pub fn new(def: DefId, substs: SubstsRef<'tcx>) -> UnevaluatedConst<'tcx> {
         UnevaluatedConst { def, substs }
     }
 }
@@ -224,9 +221,9 @@ impl<'tcx> ConstKind<'tcx> {
             // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
             // we can call `infcx.const_eval_resolve` which handles inference variables.
             let param_env_and = if (param_env, unevaluated).has_non_region_infer() {
-                tcx.param_env(unevaluated.def.did).and(ty::UnevaluatedConst {
+                tcx.param_env(unevaluated.def).and(ty::UnevaluatedConst {
                     def: unevaluated.def,
-                    substs: InternalSubsts::identity_for_item(tcx, unevaluated.def.did),
+                    substs: InternalSubsts::identity_for_item(tcx, unevaluated.def),
                 })
             } else {
                 tcx.erase_regions(param_env)
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index f9d3ffc8f00..6f122d97a39 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -13,7 +13,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
 use crate::middle::resolve_bound_vars;
 use crate::middle::stability;
 use crate::mir::interpret::{self, Allocation, ConstAllocation};
-use crate::mir::{Body, BorrowCheckResult, Local, Place, PlaceElem, ProjectionKind, Promoted};
+use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
 use crate::query::LocalCrate;
 use crate::thir::Thir;
 use crate::traits;
@@ -24,7 +24,7 @@ use crate::ty::{
     self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid,
     GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy,
     PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind, ReprOptions,
-    TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, TypeckResults, UintTy, Visibility,
+    TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, UintTy, Visibility,
 };
 use crate::ty::{GenericArg, InternalSubsts, SubstsRef};
 use rustc_ast::{self as ast, attr};
@@ -155,6 +155,7 @@ pub struct CtxtInterners<'tcx> {
     layout: InternedSet<'tcx, LayoutS>,
     adt_def: InternedSet<'tcx, AdtDefData>,
     external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>,
+    fields: InternedSet<'tcx, List<FieldIdx>>,
 }
 
 impl<'tcx> CtxtInterners<'tcx> {
@@ -178,6 +179,7 @@ impl<'tcx> CtxtInterners<'tcx> {
             layout: Default::default(),
             adt_def: Default::default(),
             external_constraints: Default::default(),
+            fields: Default::default(),
         }
     }
 
@@ -449,6 +451,14 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn feed_local_crate(self) -> TyCtxtFeed<'tcx, CrateNum> {
         TyCtxtFeed { tcx: self, key: LOCAL_CRATE }
     }
+
+    /// In order to break cycles involving `AnonConst`, we need to set the expected type by side
+    /// effect. However, we do not want this as a general capability, so this interface restricts
+    /// to the only allowed case.
+    pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<Ty<'tcx>>) {
+        debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
+        TyCtxtFeed { tcx: self, key }.type_of(value)
+    }
 }
 
 impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
@@ -583,28 +593,6 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    pub fn typeck_opt_const_arg(
-        self,
-        def: ty::WithOptConstParam<LocalDefId>,
-    ) -> &'tcx TypeckResults<'tcx> {
-        if let Some(param_did) = def.const_param_did {
-            self.typeck_const_arg((def.did, param_did))
-        } else {
-            self.typeck(def.did)
-        }
-    }
-
-    pub fn mir_borrowck_opt_const_arg(
-        self,
-        def: ty::WithOptConstParam<LocalDefId>,
-    ) -> &'tcx BorrowCheckResult<'tcx> {
-        if let Some(param_did) = def.const_param_did {
-            self.mir_borrowck_const_arg((def.did, param_did))
-        } else {
-            self.mir_borrowck(def.did)
-        }
-    }
-
     pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> {
         self.arena.alloc(Steal::new(thir))
     }
@@ -1585,6 +1573,7 @@ slice_interners!(
     projs: pub mk_projs(ProjectionKind),
     place_elems: pub mk_place_elems(PlaceElem<'tcx>),
     bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
+    fields: pub mk_fields(FieldIdx),
 );
 
 impl<'tcx> TyCtxt<'tcx> {
@@ -2253,6 +2242,14 @@ impl<'tcx> TyCtxt<'tcx> {
         T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
     }
 
+    pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output
+    where
+        I: Iterator<Item = T>,
+        T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>,
+    {
+        T::collect_and_apply(iter, |xs| self.mk_fields(xs))
+    }
+
     pub fn mk_substs_trait(
         self,
         self_ty: Ty<'tcx>,
diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs
index 4c7822acdf7..02baa395c3c 100644
--- a/compiler/rustc_middle/src/ty/impls_ty.rs
+++ b/compiler/rustc_middle/src/ty/impls_ty.rs
@@ -73,34 +73,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArg<'t
     }
 }
 
-impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArgKind<'tcx> {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        match self {
-            // WARNING: We dedup cache the `HashStable` results for `List`
-            // while ignoring types and freely transmute
-            // between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`.
-            // See `fn mk_type_list` for more details.
-            //
-            // We therefore hash types without adding a hash for their discriminant.
-            //
-            // In order to make it very unlikely for the sequence of bytes being hashed for
-            // a `GenericArgKind::Type` to be the same as the sequence of bytes being
-            // hashed for one of the other variants, we hash some very high number instead
-            // of their actual discriminant since `TyKind` should never start with anything
-            // that high.
-            ty::subst::GenericArgKind::Type(ty) => ty.hash_stable(hcx, hasher),
-            ty::subst::GenericArgKind::Const(ct) => {
-                0xF3u8.hash_stable(hcx, hasher);
-                ct.hash_stable(hcx, hasher);
-            }
-            ty::subst::GenericArgKind::Lifetime(lt) => {
-                0xF5u8.hash_stable(hcx, hasher);
-                lt.hash_stable(hcx, hasher);
-            }
-        }
-    }
-}
-
 // AllocIds get resolved to whatever they point to (to be stable)
 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index e73225f70cc..cc86cba6fda 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -34,7 +34,7 @@ pub enum InstanceDef<'tcx> {
     /// - `fn` items
     /// - closures
     /// - generators
-    Item(ty::WithOptConstParam<DefId>),
+    Item(DefId),
 
     /// An intrinsic `fn` item (with `"rust-intrinsic"` or `"platform-intrinsic"` ABI).
     ///
@@ -143,7 +143,7 @@ impl<'tcx> Instance<'tcx> {
 
         match self.def {
             InstanceDef::Item(def) => tcx
-                .upstream_monomorphizations_for(def.did)
+                .upstream_monomorphizations_for(def)
                 .and_then(|monos| monos.get(&self.substs).cloned()),
             InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs),
             _ => None,
@@ -155,8 +155,8 @@ impl<'tcx> InstanceDef<'tcx> {
     #[inline]
     pub fn def_id(self) -> DefId {
         match self {
-            InstanceDef::Item(def) => def.did,
-            InstanceDef::VTableShim(def_id)
+            InstanceDef::Item(def_id)
+            | InstanceDef::VTableShim(def_id)
             | InstanceDef::ReifyShim(def_id)
             | InstanceDef::FnPtrShim(def_id, _)
             | InstanceDef::Virtual(def_id, _)
@@ -172,7 +172,7 @@ impl<'tcx> InstanceDef<'tcx> {
     /// Returns the `DefId` of instances which might not require codegen locally.
     pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> {
         match self {
-            ty::InstanceDef::Item(def) => Some(def.did),
+            ty::InstanceDef::Item(def) => Some(def),
             ty::InstanceDef::DropGlue(def_id, Some(_)) | InstanceDef::ThreadLocalShim(def_id) => {
                 Some(def_id)
             }
@@ -189,23 +189,6 @@ impl<'tcx> InstanceDef<'tcx> {
     }
 
     #[inline]
-    pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> {
-        match self {
-            InstanceDef::Item(def) => def,
-            InstanceDef::VTableShim(def_id)
-            | InstanceDef::ReifyShim(def_id)
-            | InstanceDef::FnPtrShim(def_id, _)
-            | InstanceDef::Virtual(def_id, _)
-            | InstanceDef::Intrinsic(def_id)
-            | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ }
-            | InstanceDef::DropGlue(def_id, _)
-            | InstanceDef::CloneShim(def_id, _)
-            | InstanceDef::ThreadLocalShim(def_id)
-            | InstanceDef::FnPtrAddrShim(def_id, _) => ty::WithOptConstParam::unknown(def_id),
-        }
-    }
-
-    #[inline]
     pub fn get_attrs(
         &self,
         tcx: TyCtxt<'tcx>,
@@ -222,7 +205,7 @@ impl<'tcx> InstanceDef<'tcx> {
     pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool {
         use rustc_hir::definitions::DefPathData;
         let def_id = match *self {
-            ty::InstanceDef::Item(def) => def.did,
+            ty::InstanceDef::Item(def) => def,
             ty::InstanceDef::DropGlue(_, Some(_)) => return false,
             ty::InstanceDef::ThreadLocalShim(_) => return false,
             _ => return true,
@@ -273,8 +256,7 @@ impl<'tcx> InstanceDef<'tcx> {
 
     pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
         match *self {
-            InstanceDef::Item(ty::WithOptConstParam { did: def_id, .. })
-            | InstanceDef::Virtual(def_id, _) => {
+            InstanceDef::Item(def_id) | InstanceDef::Virtual(def_id, _) => {
                 tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
             }
             InstanceDef::ClosureOnceShim { call_once: _, track_caller } => track_caller,
@@ -358,7 +340,7 @@ impl<'tcx> Instance<'tcx> {
             def_id,
             substs
         );
-        Instance { def: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), substs }
+        Instance { def: InstanceDef::Item(def_id), substs }
     }
 
     pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
@@ -403,18 +385,21 @@ impl<'tcx> Instance<'tcx> {
     /// couldn't complete due to errors elsewhere - this is distinct
     /// from `Ok(None)` to avoid misleading diagnostics when an error
     /// has already been/will be emitted, for the original cause
+    #[instrument(level = "debug", skip(tcx))]
     pub fn resolve(
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         def_id: DefId,
         substs: SubstsRef<'tcx>,
     ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
-        Instance::resolve_opt_const_arg(
-            tcx,
-            param_env,
-            ty::WithOptConstParam::unknown(def_id),
-            substs,
-        )
+        // All regions in the result of this query are erased, so it's
+        // fine to erase all of the input regions.
+
+        // HACK(eddyb) erase regions in `substs` first, so that `param_env.and(...)`
+        // below is more likely to ignore the bounds in scope (e.g. if the only
+        // generic parameters mentioned by `substs` were lifetime ones).
+        let substs = tcx.erase_regions(substs);
+        tcx.resolve_instance(tcx.erase_regions(param_env.and((def_id, substs))))
     }
 
     pub fn expect_resolve(
@@ -432,31 +417,6 @@ impl<'tcx> Instance<'tcx> {
         }
     }
 
-    // This should be kept up to date with `resolve`.
-    pub fn resolve_opt_const_arg(
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        def: ty::WithOptConstParam<DefId>,
-        substs: SubstsRef<'tcx>,
-    ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
-        // All regions in the result of this query are erased, so it's
-        // fine to erase all of the input regions.
-
-        // HACK(eddyb) erase regions in `substs` first, so that `param_env.and(...)`
-        // below is more likely to ignore the bounds in scope (e.g. if the only
-        // generic parameters mentioned by `substs` were lifetime ones).
-        let substs = tcx.erase_regions(substs);
-
-        // FIXME(eddyb) should this always use `param_env.with_reveal_all()`?
-        if let Some((did, param_did)) = def.as_const_arg() {
-            tcx.resolve_instance_of_const_arg(
-                tcx.erase_regions(param_env.and((did, param_did, substs))),
-            )
-        } else {
-            tcx.resolve_instance(tcx.erase_regions(param_env.and((def.did, substs))))
-        }
-    }
-
     pub fn resolve_for_fn_ptr(
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -470,7 +430,7 @@ impl<'tcx> Instance<'tcx> {
             match resolved.def {
                 InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => {
                     debug!(" => fn pointer created for function with #[track_caller]");
-                    resolved.def = InstanceDef::ReifyShim(def.did);
+                    resolved.def = InstanceDef::ReifyShim(def);
                 }
                 InstanceDef::Virtual(def_id, _) => {
                     debug!(" => fn pointer created for virtual call");
@@ -513,23 +473,23 @@ impl<'tcx> Instance<'tcx> {
                         if resolved.def.requires_caller_location(tcx)
                             // 2) The caller location parameter comes from having `#[track_caller]`
                             // on the implementation, and *not* on the trait method.
-                            && !tcx.should_inherit_track_caller(def.did)
+                            && !tcx.should_inherit_track_caller(def)
                             // If the method implementation comes from the trait definition itself
                             // (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`),
                             // then we don't need to generate a shim. This check is needed because
                             // `should_inherit_track_caller` returns `false` if our method
                             // implementation comes from the trait block, and not an impl block
                             && !matches!(
-                                tcx.opt_associated_item(def.did),
+                                tcx.opt_associated_item(def),
                                 Some(ty::AssocItem {
                                     container: ty::AssocItemContainer::TraitContainer,
                                     ..
                                 })
                             )
                         {
-                            if tcx.is_closure(def.did) {
+                            if tcx.is_closure(def) {
                                 debug!(" => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}",
-                                       def.did, def_id, substs);
+                                       def, def_id, substs);
 
                                 // Create a shim for the `FnOnce/FnMut/Fn` method we are calling
                                 // - unlike functions, invoking a closure always goes through a
@@ -537,9 +497,9 @@ impl<'tcx> Instance<'tcx> {
                                 resolved = Instance { def: InstanceDef::ReifyShim(def_id), substs };
                             } else {
                                 debug!(
-                                    " => vtable fn pointer created for function with #[track_caller]: {:?}", def.did
+                                    " => vtable fn pointer created for function with #[track_caller]: {:?}", def
                                 );
-                                resolved.def = InstanceDef::ReifyShim(def.did);
+                                resolved.def = InstanceDef::ReifyShim(def);
                             }
                         }
                     }
@@ -714,11 +674,8 @@ fn polymorphize<'tcx>(
             debug!("fold_ty: ty={:?}", ty);
             match *ty.kind() {
                 ty::Closure(def_id, substs) => {
-                    let polymorphized_substs = polymorphize(
-                        self.tcx,
-                        ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
-                        substs,
-                    );
+                    let polymorphized_substs =
+                        polymorphize(self.tcx, ty::InstanceDef::Item(def_id), substs);
                     if substs == polymorphized_substs {
                         ty
                     } else {
@@ -726,11 +683,8 @@ fn polymorphize<'tcx>(
                     }
                 }
                 ty::Generator(def_id, substs, movability) => {
-                    let polymorphized_substs = polymorphize(
-                        self.tcx,
-                        ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
-                        substs,
-                    );
+                    let polymorphized_substs =
+                        polymorphize(self.tcx, ty::InstanceDef::Item(def_id), substs);
                     if substs == polymorphized_substs {
                         ty
                     } else {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 1061c320793..42b98540ac7 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1007,7 +1007,7 @@ impl<'tcx> Term<'tcx> {
                 _ => None,
             },
             TermKind::Const(ct) => match ct.kind() {
-                ConstKind::Unevaluated(uv) => Some(tcx.mk_alias_ty(uv.def.did, uv.substs)),
+                ConstKind::Unevaluated(uv) => Some(tcx.mk_alias_ty(uv.def, uv.substs)),
                 _ => None,
             },
         }
@@ -1471,135 +1471,6 @@ pub struct BoundConst<'tcx> {
 
 pub type PlaceholderConst<'tcx> = Placeholder<BoundVar>;
 
-/// A `DefId` which, in case it is a const argument, is potentially bundled with
-/// the `DefId` of the generic parameter it instantiates.
-///
-/// This is used to avoid calls to `type_of` for const arguments during typeck
-/// which cause cycle errors.
-///
-/// ```rust
-/// struct A;
-/// impl A {
-///     fn foo<const N: usize>(&self) -> [u8; N] { [0; N] }
-///     //           ^ const parameter
-/// }
-/// struct B;
-/// impl B {
-///     fn foo<const M: u8>(&self) -> usize { 42 }
-///     //           ^ const parameter
-/// }
-///
-/// fn main() {
-///     let a = A;
-///     let _b = a.foo::<{ 3 + 7 }>();
-///     //               ^^^^^^^^^ const argument
-/// }
-/// ```
-///
-/// Let's look at the call `a.foo::<{ 3 + 7 }>()` here. We do not know
-/// which `foo` is used until we know the type of `a`.
-///
-/// We only know the type of `a` once we are inside of `typeck(main)`.
-/// We also end up normalizing the type of `_b` during `typeck(main)` which
-/// requires us to evaluate the const argument.
-///
-/// To evaluate that const argument we need to know its type,
-/// which we would get using `type_of(const_arg)`. This requires us to
-/// resolve `foo` as it can be either `usize` or `u8` in this example.
-/// However, resolving `foo` once again requires `typeck(main)` to get the type of `a`,
-/// which results in a cycle.
-///
-/// In short we must not call `type_of(const_arg)` during `typeck(main)`.
-///
-/// When first creating the `ty::Const` of the const argument inside of `typeck` we have
-/// already resolved `foo` so we know which const parameter this argument instantiates.
-/// This means that we also know the expected result of `type_of(const_arg)` even if we
-/// aren't allowed to call that query: it is equal to `type_of(const_param)` which is
-/// trivial to compute.
-///
-/// If we now want to use that constant in a place which potentially needs its type
-/// we also pass the type of its `const_param`. This is the point of `WithOptConstParam`,
-/// except that instead of a `Ty` we bundle the `DefId` of the const parameter.
-/// Meaning that we need to use `type_of(const_param_did)` if `const_param_did` is `Some`
-/// to get the type of `did`.
-#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-#[derive(Hash, HashStable)]
-pub struct WithOptConstParam<T> {
-    pub did: T,
-    /// The `DefId` of the corresponding generic parameter in case `did` is
-    /// a const argument.
-    ///
-    /// Note that even if `did` is a const argument, this may still be `None`.
-    /// All queries taking `WithOptConstParam` start by calling `tcx.opt_const_param_of(def.did)`
-    /// to potentially update `param_did` in the case it is `None`.
-    pub const_param_did: Option<DefId>,
-}
-
-impl<T> WithOptConstParam<T> {
-    /// Creates a new `WithOptConstParam` setting `const_param_did` to `None`.
-    #[inline(always)]
-    pub fn unknown(did: T) -> WithOptConstParam<T> {
-        WithOptConstParam { did, const_param_did: None }
-    }
-}
-
-impl WithOptConstParam<LocalDefId> {
-    /// Returns `Some((did, param_did))` if `def_id` is a const argument,
-    /// `None` otherwise.
-    #[inline(always)]
-    pub fn try_lookup(did: LocalDefId, tcx: TyCtxt<'_>) -> Option<(LocalDefId, DefId)> {
-        tcx.opt_const_param_of(did).map(|param_did| (did, param_did))
-    }
-
-    /// In case `self` is unknown but `self.did` is a const argument, this returns
-    /// a `WithOptConstParam` with the correct `const_param_did`.
-    #[inline(always)]
-    pub fn try_upgrade(self, tcx: TyCtxt<'_>) -> Option<WithOptConstParam<LocalDefId>> {
-        if self.const_param_did.is_none() {
-            if let const_param_did @ Some(_) = tcx.opt_const_param_of(self.did) {
-                return Some(WithOptConstParam { did: self.did, const_param_did });
-            }
-        }
-
-        None
-    }
-
-    pub fn to_global(self) -> WithOptConstParam<DefId> {
-        WithOptConstParam { did: self.did.to_def_id(), const_param_did: self.const_param_did }
-    }
-
-    pub fn def_id_for_type_of(self) -> DefId {
-        if let Some(did) = self.const_param_did { did } else { self.did.to_def_id() }
-    }
-}
-
-impl WithOptConstParam<DefId> {
-    pub fn as_local(self) -> Option<WithOptConstParam<LocalDefId>> {
-        self.did
-            .as_local()
-            .map(|did| WithOptConstParam { did, const_param_did: self.const_param_did })
-    }
-
-    pub fn as_const_arg(self) -> Option<(LocalDefId, DefId)> {
-        if let Some(param_did) = self.const_param_did {
-            if let Some(did) = self.did.as_local() {
-                return Some((did, param_did));
-            }
-        }
-
-        None
-    }
-
-    pub fn is_local(self) -> bool {
-        self.did.is_local()
-    }
-
-    pub fn def_id_for_type_of(self) -> DefId {
-        self.const_param_did.unwrap_or(self.did)
-    }
-}
-
 /// When type checking, we use the `ParamEnv` to track
 /// details about the set of where-clauses that are in scope at this
 /// particular point.
@@ -2367,7 +2238,7 @@ impl<'tcx> TyCtxt<'tcx> {
         match instance {
             ty::InstanceDef::Item(def) => {
                 debug!("calling def_kind on def: {:?}", def);
-                let def_kind = self.def_kind(def.did);
+                let def_kind = self.def_kind(def);
                 debug!("returned from def_kind: {:?}", def_kind);
                 match def_kind {
                     DefKind::Const
@@ -2375,13 +2246,10 @@ impl<'tcx> TyCtxt<'tcx> {
                     | DefKind::AssocConst
                     | DefKind::Ctor(..)
                     | DefKind::AnonConst
-                    | DefKind::InlineConst => self.mir_for_ctfe_opt_const_arg(def),
+                    | DefKind::InlineConst => self.mir_for_ctfe(def),
                     // If the caller wants `mir_for_ctfe` of a function they should not be using
                     // `instance_mir`, so we'll assume const fn also wants the optimized version.
-                    _ => {
-                        assert_eq!(def.const_param_did, None);
-                        self.optimized_mir(def.did)
-                    }
+                    _ => self.optimized_mir(def),
                 }
             }
             ty::InstanceDef::VTableShim(..)
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index af76cf7cc4e..888b3a50b77 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -738,7 +738,9 @@ pub trait PrettyPrinter<'tcx>:
                 }
             }
             ty::Placeholder(placeholder) => match placeholder.bound.kind {
-                ty::BoundTyKind::Anon => p!(write("Placeholder({:?})", placeholder)),
+                ty::BoundTyKind::Anon => {
+                    self.pretty_print_placeholder_var(placeholder.universe, placeholder.bound.var)?
+                }
                 ty::BoundTyKind::Param(_, name) => p!(write("{}", name)),
             },
             ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
@@ -1172,6 +1174,18 @@ pub trait PrettyPrinter<'tcx>:
         }
     }
 
+    fn pretty_print_placeholder_var(
+        &mut self,
+        ui: ty::UniverseIndex,
+        var: ty::BoundVar,
+    ) -> Result<(), Self::Error> {
+        if ui == ty::UniverseIndex::ROOT {
+            write!(self, "!{}", var.index())
+        } else {
+            write!(self, "!{}_{}", ui.index(), var.index())
+        }
+    }
+
     fn ty_infer_name(&self, _: ty::TyVid) -> Option<Symbol> {
         None
     }
@@ -1328,13 +1342,13 @@ pub trait PrettyPrinter<'tcx>:
 
         match ct.kind() {
             ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => {
-                match self.tcx().def_kind(def.did) {
+                match self.tcx().def_kind(def) {
                     DefKind::Const | DefKind::AssocConst => {
-                        p!(print_value_path(def.did, substs))
+                        p!(print_value_path(def, substs))
                     }
                     DefKind::AnonConst => {
                         if def.is_local()
-                            && let span = self.tcx().def_span(def.did)
+                            && let span = self.tcx().def_span(def)
                             && let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span)
                         {
                             p!(write("{}", snip))
@@ -1344,7 +1358,7 @@ pub trait PrettyPrinter<'tcx>:
                             // cause printing to enter an infinite recursion if the anon const is in the self type i.e.
                             // `impl<T: Default> Default for [T; 32 - 1 - 1 - 1] {`
                             // where we would try to print `<[T; /* print `constant#0` again */] as Default>::{constant#0}`
-                            p!(write("{}::{}", self.tcx().crate_name(def.did.krate), self.tcx().def_path(def.did).to_string_no_crate_verbose()))
+                            p!(write("{}::{}", self.tcx().crate_name(def.krate), self.tcx().def_path(def).to_string_no_crate_verbose()))
                         }
                     }
                     defkind => bug!("`{:?}` has unexpected defkind {:?}", ct, defkind),
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 97592cbc567..e46cfb8dd16 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -76,6 +76,9 @@ use std::ops::Deref;
 use std::path::PathBuf;
 use std::sync::Arc;
 
+use rustc_data_structures::fingerprint::Fingerprint;
+use rustc_query_system::ich::StableHashingContext;
+
 #[derive(Default)]
 pub struct QuerySystem<'tcx> {
     pub arenas: QueryArenas<'tcx>,
@@ -477,7 +480,7 @@ macro_rules! define_feedable {
         $(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> {
             $(#[$attr])*
             #[inline(always)]
-            pub fn $name(self, value: query_provided::$name<'tcx>) -> $V {
+            pub fn $name(self, value: query_provided::$name<'tcx>) {
                 let key = self.key().into_query_param();
 
                 let tcx = self.tcx;
@@ -485,13 +488,25 @@ macro_rules! define_feedable {
                 let value = restore::<$V>(erased);
                 let cache = &tcx.query_system.caches.$name;
 
+                let hasher: Option<fn(&mut StableHashingContext<'_>, &_) -> _> = hash_result!([$($modifiers)*]);
                 match try_get_cached(tcx, cache, &key) {
                     Some(old) => {
                         let old = restore::<$V>(old);
-                        bug!(
-                            "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}",
-                            stringify!($name),
-                        )
+                        if let Some(hasher) = hasher {
+                            let (value_hash, old_hash): (Fingerprint, Fingerprint) = tcx.with_stable_hashing_context(|mut hcx|
+                                (hasher(&mut hcx, &value), hasher(&mut hcx, &old))
+                            );
+                            assert_eq!(
+                                old_hash, value_hash,
+                                "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}",
+                                stringify!($name),
+                            )
+                        } else {
+                            bug!(
+                                "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}",
+                                stringify!($name),
+                            )
+                        }
                     }
                     None => {
                         let dep_node = dep_graph::DepNode::construct(tcx, dep_graph::DepKind::$name, &key);
@@ -503,7 +518,6 @@ macro_rules! define_feedable {
                             hash_result!([$($modifiers)*]),
                         );
                         cache.complete(key, erased, dep_node_index);
-                        value
                     }
                 }
             }
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index da3cd27f388..a439211ca33 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -21,7 +21,6 @@ use std::marker::PhantomData;
 use std::mem;
 use std::num::NonZeroUsize;
 use std::ops::{ControlFlow, Deref};
-use std::slice;
 
 /// An entity in the Rust type system, which can be one of
 /// several kinds (types, lifetimes, and consts).
@@ -48,25 +47,13 @@ const TYPE_TAG: usize = 0b00;
 const REGION_TAG: usize = 0b01;
 const CONST_TAG: usize = 0b10;
 
-#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)]
 pub enum GenericArgKind<'tcx> {
     Lifetime(ty::Region<'tcx>),
     Type(Ty<'tcx>),
     Const(ty::Const<'tcx>),
 }
 
-/// This function goes from `&'a [Ty<'tcx>]` to `&'a [GenericArg<'tcx>]`
-///
-/// This is sound as, for types, `GenericArg` is just
-/// `NonZeroUsize::new_unchecked(ty as *const _ as usize)` as
-/// long as we use `0` for the `TYPE_TAG`.
-pub fn ty_slice_as_generic_args<'a, 'tcx>(ts: &'a [Ty<'tcx>]) -> &'a [GenericArg<'tcx>] {
-    assert_eq!(TYPE_TAG, 0);
-    // SAFETY: the whole slice is valid and immutable.
-    // `Ty` and `GenericArg` is explained above.
-    unsafe { slice::from_raw_parts(ts.as_ptr().cast(), ts.len()) }
-}
-
 impl<'tcx> GenericArgKind<'tcx> {
     #[inline]
     fn pack(self) -> GenericArg<'tcx> {
@@ -167,30 +154,45 @@ impl<'tcx> GenericArg<'tcx> {
         }
     }
 
-    /// Unpack the `GenericArg` as a region when it is known certainly to be a region.
-    pub fn expect_region(self) -> ty::Region<'tcx> {
+    #[inline]
+    pub fn as_type(self) -> Option<Ty<'tcx>> {
         match self.unpack() {
-            GenericArgKind::Lifetime(lt) => lt,
-            _ => bug!("expected a region, but found another kind"),
+            GenericArgKind::Type(ty) => Some(ty),
+            _ => None,
         }
     }
 
+    #[inline]
+    pub fn as_region(self) -> Option<ty::Region<'tcx>> {
+        match self.unpack() {
+            GenericArgKind::Lifetime(re) => Some(re),
+            _ => None,
+        }
+    }
+
+    #[inline]
+    pub fn as_const(self) -> Option<ty::Const<'tcx>> {
+        match self.unpack() {
+            GenericArgKind::Const(ct) => Some(ct),
+            _ => None,
+        }
+    }
+
+    /// Unpack the `GenericArg` as a region when it is known certainly to be a region.
+    pub fn expect_region(self) -> ty::Region<'tcx> {
+        self.as_region().unwrap_or_else(|| bug!("expected a region, but found another kind"))
+    }
+
     /// Unpack the `GenericArg` as a type when it is known certainly to be a type.
     /// This is true in cases where `Substs` is used in places where the kinds are known
     /// to be limited (e.g. in tuples, where the only parameters are type parameters).
     pub fn expect_ty(self) -> Ty<'tcx> {
-        match self.unpack() {
-            GenericArgKind::Type(ty) => ty,
-            _ => bug!("expected a type, but found another kind"),
-        }
+        self.as_type().unwrap_or_else(|| bug!("expected a type, but found another kind"))
     }
 
     /// Unpack the `GenericArg` as a const when it is known certainly to be a const.
     pub fn expect_const(self) -> ty::Const<'tcx> {
-        match self.unpack() {
-            GenericArgKind::Const(c) => c,
-            _ => bug!("expected a const, but found another kind"),
-        }
+        self.as_const().unwrap_or_else(|| bug!("expected a const, but found another kind"))
     }
 
     pub fn is_non_region_infer(self) -> bool {
@@ -369,22 +371,17 @@ impl<'tcx> InternalSubsts<'tcx> {
 
     #[inline]
     pub fn types(&'tcx self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'tcx {
-        self.iter()
-            .filter_map(|k| if let GenericArgKind::Type(ty) = k.unpack() { Some(ty) } else { None })
+        self.iter().filter_map(|k| k.as_type())
     }
 
     #[inline]
     pub fn regions(&'tcx self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> + 'tcx {
-        self.iter().filter_map(|k| {
-            if let GenericArgKind::Lifetime(lt) = k.unpack() { Some(lt) } else { None }
-        })
+        self.iter().filter_map(|k| k.as_region())
     }
 
     #[inline]
     pub fn consts(&'tcx self) -> impl DoubleEndedIterator<Item = ty::Const<'tcx>> + 'tcx {
-        self.iter().filter_map(|k| {
-            if let GenericArgKind::Const(ct) = k.unpack() { Some(ct) } else { None }
-        })
+        self.iter().filter_map(|k| k.as_const())
     }
 
     #[inline]
@@ -400,31 +397,21 @@ impl<'tcx> InternalSubsts<'tcx> {
     #[inline]
     #[track_caller]
     pub fn type_at(&self, i: usize) -> Ty<'tcx> {
-        if let GenericArgKind::Type(ty) = self[i].unpack() {
-            ty
-        } else {
-            bug!("expected type for param #{} in {:?}", i, self);
-        }
+        self[i].as_type().unwrap_or_else(|| bug!("expected type for param #{} in {:?}", i, self))
     }
 
     #[inline]
     #[track_caller]
     pub fn region_at(&self, i: usize) -> ty::Region<'tcx> {
-        if let GenericArgKind::Lifetime(lt) = self[i].unpack() {
-            lt
-        } else {
-            bug!("expected region for param #{} in {:?}", i, self);
-        }
+        self[i]
+            .as_region()
+            .unwrap_or_else(|| bug!("expected region for param #{} in {:?}", i, self))
     }
 
     #[inline]
     #[track_caller]
     pub fn const_at(&self, i: usize) -> ty::Const<'tcx> {
-        if let GenericArgKind::Const(ct) = self[i].unpack() {
-            ct
-        } else {
-            bug!("expected const for param #{} in {:?}", i, self);
-        }
+        self[i].as_const().unwrap_or_else(|| bug!("expected const for param #{} in {:?}", i, self))
     }
 
     #[inline]
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 47943b94c3b..ef8955b1d3a 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -208,6 +208,9 @@ pub struct TypeckResults<'tcx> {
     /// Contains the data for evaluating the effect of feature `capture_disjoint_fields`
     /// on closure size.
     pub closure_size_eval: FxHashMap<LocalDefId, ClosureSizeProfileData<'tcx>>,
+
+    /// Container types and field indices of `offset_of!` expressions
+    offset_of_data: ItemLocalMap<(Ty<'tcx>, Vec<FieldIdx>)>,
 }
 
 /// Whenever a value may be live across a generator yield, the type of that value winds up in the
@@ -280,6 +283,7 @@ impl<'tcx> TypeckResults<'tcx> {
             generator_interior_predicates: Default::default(),
             treat_byte_string_as_slice: Default::default(),
             closure_size_eval: Default::default(),
+            offset_of_data: Default::default(),
         }
     }
 
@@ -530,6 +534,14 @@ impl<'tcx> TypeckResults<'tcx> {
     pub fn coercion_casts(&self) -> &ItemLocalSet {
         &self.coercion_casts
     }
+
+    pub fn offset_of_data(&self) -> LocalTableInContext<'_, (Ty<'tcx>, Vec<FieldIdx>)> {
+        LocalTableInContext { hir_owner: self.hir_owner, data: &self.offset_of_data }
+    }
+
+    pub fn offset_of_data_mut(&mut self) -> LocalTableInContextMut<'_, (Ty<'tcx>, Vec<FieldIdx>)> {
+        LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.offset_of_data }
+    }
 }
 
 /// Validate that the given HirId (respectively its `local_id` part) can be
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 99291740ac8..fbcfd433724 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -78,7 +78,7 @@ pub fn as_constant_inner<'tcx>(
         ExprKind::NamedConst { def_id, substs, ref user_ty } => {
             let user_ty = user_ty.as_ref().and_then(push_cuta);
 
-            let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
+            let uneval = mir::UnevaluatedConst::new(def_id, substs);
             let literal = ConstantKind::Unevaluated(uneval, ty);
 
             Constant { user_ty, span, literal }
@@ -90,7 +90,7 @@ pub fn as_constant_inner<'tcx>(
             Constant { user_ty: None, span, literal }
         }
         ExprKind::ConstBlock { did: def_id, substs } => {
-            let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
+            let uneval = mir::UnevaluatedConst::new(def_id, substs);
             let literal = ConstantKind::Unevaluated(uneval, ty);
 
             Constant { user_ty: None, span, literal }
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index fb775766c65..7ec57add66b 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -557,6 +557,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::ConstBlock { .. }
             | ExprKind::StaticRef { .. }
             | ExprKind::InlineAsm { .. }
+            | ExprKind::OffsetOf { .. }
             | ExprKind::Yield { .. }
             | ExprKind::ThreadLocalRef(_)
             | ExprKind::Call { .. } => {
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 8631749a524..fbde0b28f54 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -481,6 +481,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 }))))
             }
 
+            ExprKind::OffsetOf { container, fields } => {
+                block.and(Rvalue::NullaryOp(NullOp::OffsetOf(fields), container))
+            }
+
             ExprKind::Literal { .. }
             | ExprKind::NamedConst { .. }
             | ExprKind::NonHirLiteral { .. }
diff --git a/compiler/rustc_mir_build/src/build/expr/category.rs b/compiler/rustc_mir_build/src/build/expr/category.rs
index d33401f0764..d9aa461c19d 100644
--- a/compiler/rustc_mir_build/src/build/expr/category.rs
+++ b/compiler/rustc_mir_build/src/build/expr/category.rs
@@ -67,7 +67,8 @@ impl Category {
             | ExprKind::Repeat { .. }
             | ExprKind::Assign { .. }
             | ExprKind::AssignOp { .. }
-            | ExprKind::ThreadLocalRef(_) => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
+            | ExprKind::ThreadLocalRef(_)
+            | ExprKind::OffsetOf { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
 
             ExprKind::ConstBlock { .. }
             | ExprKind::Literal { .. }
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 9b38ac1cc4c..29ff916d2cc 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -561,7 +561,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::ZstLiteral { .. }
             | ExprKind::ConstParam { .. }
             | ExprKind::ThreadLocalRef(_)
-            | ExprKind::StaticRef { .. } => {
+            | ExprKind::StaticRef { .. }
+            | ExprKind::OffsetOf { .. } => {
                 debug_assert!(match Category::of(&expr.kind).unwrap() {
                     // should be handled above
                     Category::Rvalue(RvalueFunc::Into) => false,
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index bc50bcbc3d0..b05c3056cba 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -32,38 +32,20 @@ use super::lints;
 
 pub(crate) fn mir_built(
     tcx: TyCtxt<'_>,
-    def: ty::WithOptConstParam<LocalDefId>,
+    def: LocalDefId,
 ) -> &rustc_data_structures::steal::Steal<Body<'_>> {
-    if let Some(def) = def.try_upgrade(tcx) {
-        return tcx.mir_built(def);
-    }
-
-    let mut body = mir_build(tcx, def);
-    if def.const_param_did.is_some() {
-        assert!(matches!(body.source.instance, ty::InstanceDef::Item(_)));
-        body.source = MirSource::from_instance(ty::InstanceDef::Item(def.to_global()));
-    }
-
-    tcx.alloc_steal_mir(body)
+    tcx.alloc_steal_mir(mir_build(tcx, def))
 }
 
 /// Construct the MIR for a given `DefId`.
-fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> {
+fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
     // Ensure unsafeck and abstract const building is ran before we steal the THIR.
-    match def {
-        ty::WithOptConstParam { did, const_param_did: Some(const_param_did) } => {
-            tcx.ensure_with_value().thir_check_unsafety_for_const_arg((did, const_param_did));
-            tcx.ensure_with_value().thir_abstract_const_of_const_arg((did, const_param_did));
-        }
-        ty::WithOptConstParam { did, const_param_did: None } => {
-            tcx.ensure_with_value().thir_check_unsafety(did);
-            tcx.ensure_with_value().thir_abstract_const(did);
-            tcx.ensure_with_value().check_match(did);
-        }
-    }
+    tcx.ensure_with_value().thir_check_unsafety(def);
+    tcx.ensure_with_value().thir_abstract_const(def);
+    tcx.ensure_with_value().check_match(def);
 
     let body = match tcx.thir_body(def) {
-        Err(error_reported) => construct_error(tcx, def.did, error_reported),
+        Err(error_reported) => construct_error(tcx, def, error_reported),
         Ok((thir, expr)) => {
             // We ran all queries that depended on THIR at the beginning
             // of `mir_build`, so now we can steal it
@@ -161,8 +143,7 @@ struct Builder<'a, 'tcx> {
     thir: &'a Thir<'tcx>,
     cfg: CFG<'tcx>,
 
-    def: ty::WithOptConstParam<LocalDefId>,
-    def_id: DefId,
+    def_id: LocalDefId,
     hir_id: hir::HirId,
     parent_module: DefId,
     check_overflow: bool,
@@ -428,26 +409,26 @@ macro_rules! unpack {
 
 fn construct_fn<'tcx>(
     tcx: TyCtxt<'tcx>,
-    fn_def: ty::WithOptConstParam<LocalDefId>,
+    fn_def: LocalDefId,
     thir: &Thir<'tcx>,
     expr: ExprId,
     fn_sig: ty::FnSig<'tcx>,
 ) -> Body<'tcx> {
-    let span = tcx.def_span(fn_def.did);
-    let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def.did);
-    let generator_kind = tcx.generator_kind(fn_def.did);
+    let span = tcx.def_span(fn_def);
+    let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def);
+    let generator_kind = tcx.generator_kind(fn_def);
 
     // The representation of thir for `-Zunpretty=thir-tree` relies on
     // the entry expression being the last element of `thir.exprs`.
     assert_eq!(expr.as_usize(), thir.exprs.len() - 1);
 
     // Figure out what primary body this item has.
-    let body_id = tcx.hir().body_owned_by(fn_def.did);
+    let body_id = tcx.hir().body_owned_by(fn_def);
     let span_with_body = tcx.hir().span_with_body(fn_id);
     let return_ty_span = tcx
         .hir()
         .fn_decl_by_hir_id(fn_id)
-        .unwrap_or_else(|| span_bug!(span, "can't build MIR for {:?}", fn_def.did))
+        .unwrap_or_else(|| span_bug!(span, "can't build MIR for {:?}", fn_def))
         .output
         .span();
 
@@ -457,7 +438,7 @@ fn construct_fn<'tcx>(
     };
 
     let mut abi = fn_sig.abi;
-    if let DefKind::Closure = tcx.def_kind(fn_def.did) {
+    if let DefKind::Closure = tcx.def_kind(fn_def) {
         // HACK(eddyb) Avoid having RustCall on closures,
         // as it adds unnecessary (and wrong) auto-tupling.
         abi = Abi::Rust;
@@ -483,7 +464,7 @@ fn construct_fn<'tcx>(
     {
         return custom::build_custom_mir(
             tcx,
-            fn_def.did.to_def_id(),
+            fn_def.to_def_id(),
             fn_id,
             thir,
             expr,
@@ -547,12 +528,12 @@ fn construct_fn<'tcx>(
 
 fn construct_const<'a, 'tcx>(
     tcx: TyCtxt<'tcx>,
-    def: ty::WithOptConstParam<LocalDefId>,
+    def: LocalDefId,
     thir: &'a Thir<'tcx>,
     expr: ExprId,
     const_ty: Ty<'tcx>,
 ) -> Body<'tcx> {
-    let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
+    let hir_id = tcx.hir().local_def_id_to_hir_id(def);
 
     // Figure out what primary body this item has.
     let (span, const_ty_span) = match tcx.hir().get(hir_id) {
@@ -568,10 +549,10 @@ fn construct_const<'a, 'tcx>(
             ..
         }) => (*span, ty.span),
         Node::AnonConst(_) => {
-            let span = tcx.def_span(def.did);
+            let span = tcx.def_span(def);
             (span, span)
         }
-        _ => span_bug!(tcx.def_span(def.did), "can't build MIR for {:?}", def.did),
+        _ => span_bug!(tcx.def_span(def), "can't build MIR for {:?}", def),
     };
 
     let infcx = tcx.infer_ctxt().build();
@@ -669,7 +650,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     fn new(
         thir: &'a Thir<'tcx>,
         infcx: InferCtxt<'tcx>,
-        def: ty::WithOptConstParam<LocalDefId>,
+        def: LocalDefId,
         hir_id: hir::HirId,
         span: Span,
         arg_count: usize,
@@ -688,20 +669,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         check_overflow |= tcx.sess.overflow_checks();
         // Constants always need overflow checks.
         check_overflow |= matches!(
-            tcx.hir().body_owner_kind(def.did),
+            tcx.hir().body_owner_kind(def),
             hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_)
         );
 
         let lint_level = LintLevel::Explicit(hir_id);
-        let param_env = tcx.param_env(def.did);
+        let param_env = tcx.param_env(def);
         let mut builder = Builder {
             thir,
             tcx,
             infcx,
-            region_scope_tree: tcx.region_scope_tree(def.did),
+            region_scope_tree: tcx.region_scope_tree(def),
             param_env,
-            def,
-            def_id: def.did.to_def_id(),
+            def_id: def,
             hir_id,
             parent_module: tcx.parent_module(hir_id).to_def_id(),
             check_overflow,
@@ -741,7 +721,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
 
         Body::new(
-            MirSource::item(self.def_id),
+            MirSource::item(self.def_id.to_def_id()),
             self.cfg.basic_blocks,
             self.source_scopes,
             self.local_decls,
@@ -779,7 +759,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
         let tcx = self.tcx;
         self.upvars = tcx
-            .closure_captures(self.def.did)
+            .closure_captures(self.def_id)
             .iter()
             .zip(capture_tys)
             .enumerate()
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 03a7f2d70fa..0506f2bf238 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -117,10 +117,10 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
     }
 
     /// Handle closures/generators/inline-consts, which is unsafecked with their parent body.
-    fn visit_inner_body(&mut self, def: ty::WithOptConstParam<LocalDefId>) {
+    fn visit_inner_body(&mut self, def: LocalDefId) {
         if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) {
             let inner_thir = &inner_thir.borrow();
-            let hir_context = self.tcx.hir().local_def_id_to_hir_id(def.did);
+            let hir_context = self.tcx.hir().local_def_id_to_hir_id(def);
             let mut inner_visitor = UnsafetyVisitor { thir: inner_thir, hir_context, ..*self };
             inner_visitor.visit_expr(&inner_thir[expr]);
             // Unsafe blocks can be used in the inner body, make sure to take it into account
@@ -323,6 +323,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
             | ExprKind::Box { .. }
             | ExprKind::If { .. }
             | ExprKind::InlineAsm { .. }
+            | ExprKind::OffsetOf { .. }
             | ExprKind::LogicalOp { .. }
             | ExprKind::Use { .. } => {
                 // We don't need to save the old value and restore it
@@ -396,18 +397,11 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 movability: _,
                 fake_reads: _,
             }) => {
-                let closure_def = if let Some((did, const_param_id)) =
-                    ty::WithOptConstParam::try_lookup(closure_id, self.tcx)
-                {
-                    ty::WithOptConstParam { did, const_param_did: Some(const_param_id) }
-                } else {
-                    ty::WithOptConstParam::unknown(closure_id)
-                };
-                self.visit_inner_body(closure_def);
+                self.visit_inner_body(closure_id);
             }
             ExprKind::ConstBlock { did, substs: _ } => {
                 let def_id = did.expect_local();
-                self.visit_inner_body(ty::WithOptConstParam::unknown(def_id));
+                self.visit_inner_body(def_id);
             }
             ExprKind::Field { lhs, .. } => {
                 let lhs = &self.thir[lhs];
@@ -706,14 +700,14 @@ impl UnsafeOpKind {
     }
 }
 
-pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) {
+pub fn thir_check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
     // THIR unsafeck is gated under `-Z thir-unsafeck`
     if !tcx.sess.opts.unstable_opts.thir_unsafeck {
         return;
     }
 
     // Closures and inline consts are handled by their owner, if it has a body
-    if tcx.is_typeck_child(def.did.to_def_id()) {
+    if tcx.is_typeck_child(def.to_def_id()) {
         return;
     }
 
@@ -726,7 +720,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) {
         return;
     }
 
-    let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
+    let hir_id = tcx.hir().local_def_id_to_hir_id(def);
     let body_unsafety = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(BodyUnsafety::Safe, |fn_sig| {
         if fn_sig.header.unsafety == hir::Unsafety::Unsafe {
             BodyUnsafety::Unsafe(fn_sig.span)
@@ -734,7 +728,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) {
             BodyUnsafety::Safe
         }
     });
-    let body_target_features = &tcx.body_codegen_attrs(def.did.to_def_id()).target_features;
+    let body_target_features = &tcx.body_codegen_attrs(def.to_def_id()).target_features;
     let safety_context =
         if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
     let mut visitor = UnsafetyVisitor {
@@ -746,23 +740,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) {
         body_target_features,
         assignment_info: None,
         in_union_destructure: false,
-        param_env: tcx.param_env(def.did),
+        param_env: tcx.param_env(def),
         inside_adt: false,
     };
     visitor.visit_expr(&thir[expr]);
 }
-
-pub(crate) fn thir_check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
-    if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
-        tcx.thir_check_unsafety_for_const_arg(def)
-    } else {
-        check_unsafety(tcx, ty::WithOptConstParam::unknown(def_id))
-    }
-}
-
-pub(crate) fn thir_check_unsafety_for_const_arg(
-    tcx: TyCtxt<'_>,
-    (did, param_did): (LocalDefId, DefId),
-) {
-    check_unsafety(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
-}
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index 259f2e43392..2765a107cf0 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -35,7 +35,6 @@ pub fn provide(providers: &mut Providers) {
     providers.lit_to_mir_constant = build::lit_to_mir_constant;
     providers.mir_built = build::mir_built;
     providers.thir_check_unsafety = check_unsafety::thir_check_unsafety;
-    providers.thir_check_unsafety_for_const_arg = check_unsafety::thir_check_unsafety_for_const_arg;
     providers.thir_body = thir::cx::thir_body;
     providers.thir_tree = thir::print::thir_tree;
     providers.thir_flat = thir::print::thir_flat;
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 8e2e92e6f6a..ce13d522aae 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -664,6 +664,14 @@ impl<'tcx> Cx<'tcx> {
                 line_spans: asm.line_spans,
             })),
 
+            hir::ExprKind::OffsetOf(_, _) => {
+                let data = self.typeck_results.offset_of_data();
+                let &(container, ref indices) = data.get(expr.hir_id).unwrap();
+                let fields = tcx.mk_fields_from_iter(indices.iter().copied());
+
+                ExprKind::OffsetOf { container, fields }
+            }
+
             hir::ExprKind::ConstBlock(ref anon_const) => {
                 let ty = self.typeck_results().node_type(anon_const.hir_id);
                 let did = anon_const.def_id.to_def_id();
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index 070544446e3..463f639defe 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -20,25 +20,25 @@ use rustc_span::Span;
 
 pub(crate) fn thir_body(
     tcx: TyCtxt<'_>,
-    owner_def: ty::WithOptConstParam<LocalDefId>,
+    owner_def: LocalDefId,
 ) -> Result<(&Steal<Thir<'_>>, ExprId), ErrorGuaranteed> {
     let hir = tcx.hir();
-    let body = hir.body(hir.body_owned_by(owner_def.did));
+    let body = hir.body(hir.body_owned_by(owner_def));
     let mut cx = Cx::new(tcx, owner_def);
     if let Some(reported) = cx.typeck_results.tainted_by_errors {
         return Err(reported);
     }
     let expr = cx.mirror_expr(&body.value);
 
-    let owner_id = hir.local_def_id_to_hir_id(owner_def.did);
+    let owner_id = hir.local_def_id_to_hir_id(owner_def);
     if let Some(ref fn_decl) = hir.fn_decl_by_hir_id(owner_id) {
-        let closure_env_param = cx.closure_env_param(owner_def.did, owner_id);
+        let closure_env_param = cx.closure_env_param(owner_def, owner_id);
         let explicit_params = cx.explicit_params(owner_id, fn_decl, body);
         cx.thir.params = closure_env_param.into_iter().chain(explicit_params).collect();
 
         // The resume argument may be missing, in that case we need to provide it here.
         // It will always be `()` in this case.
-        if tcx.def_kind(owner_def.did) == DefKind::Generator && body.params.is_empty() {
+        if tcx.def_kind(owner_def) == DefKind::Generator && body.params.is_empty() {
             cx.thir.params.push(Param {
                 ty: tcx.mk_unit(),
                 pat: None,
@@ -78,13 +78,12 @@ struct Cx<'tcx> {
 }
 
 impl<'tcx> Cx<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>) -> Cx<'tcx> {
-        let typeck_results = tcx.typeck_opt_const_arg(def);
-        let did = def.did;
+    fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Cx<'tcx> {
+        let typeck_results = tcx.typeck(def);
         let hir = tcx.hir();
-        let hir_id = hir.local_def_id_to_hir_id(did);
+        let hir_id = hir.local_def_id_to_hir_id(def);
 
-        let body_type = if hir.body_owner_kind(did).is_fn_or_closure() {
+        let body_type = if hir.body_owner_kind(def).is_fn_or_closure() {
             // fetch the fully liberated fn signature (that is, all bound
             // types/lifetimes replaced)
             BodyTy::Fn(typeck_results.liberated_fn_sigs()[hir_id])
@@ -106,11 +105,11 @@ impl<'tcx> Cx<'tcx> {
         Cx {
             tcx,
             thir: Thir::new(body_type),
-            param_env: tcx.param_env(def.did),
-            region_scope_tree: tcx.region_scope_tree(def.did),
+            param_env: tcx.param_env(def),
+            region_scope_tree: tcx.region_scope_tree(def),
             typeck_results,
             rvalue_scopes: &typeck_results.rvalue_scopes,
-            body_owner: did.to_def_id(),
+            body_owner: def.to_def_id(),
             adjustment_span: None,
             apply_adjustments: hir
                 .attrs(hir_id)
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 0ef48c42f87..2b52d70af2a 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -27,7 +27,7 @@ use rustc_span::hygiene::DesugaringKind;
 use rustc_span::Span;
 
 pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) {
-    let Ok((thir, expr)) = tcx.thir_body(ty::WithOptConstParam::unknown(def_id)) else { return };
+    let Ok((thir, expr)) = tcx.thir_body(def_id) else { return };
     let thir = thir.borrow();
     let pattern_arena = TypedArena::default();
     let mut visitor = MatchVisitor {
diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
index ed61d6ee78b..b2f2a64e29c 100644
--- a/compiler/rustc_mir_build/src/thir/print.rs
+++ b/compiler/rustc_mir_build/src/thir/print.rs
@@ -3,7 +3,7 @@ use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::def_id::LocalDefId;
 use std::fmt::{self, Write};
 
-pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String {
+pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String {
     match super::cx::thir_body(tcx, owner_def) {
         Ok((thir, _)) => {
             let thir = thir.steal();
@@ -15,7 +15,7 @@ pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalD
     }
 }
 
-pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String {
+pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String {
     match super::cx::thir_body(tcx, owner_def) {
         Ok((thir, _)) => format!("{:#?}", thir.steal()),
         Err(_) => "error".into(),
@@ -519,6 +519,19 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
                 self.print_inline_asm_expr(&**expr, depth_lvl + 2);
                 print_indented!(self, "}", depth_lvl);
             }
+            OffsetOf { container, fields } => {
+                print_indented!(self, "OffsetOf {", depth_lvl);
+                print_indented!(self, format!("container: {:?}", container), depth_lvl + 1);
+                print_indented!(self, "fields: [", depth_lvl + 1);
+
+                for field in fields.iter() {
+                    print_indented!(self, format!("{:?}", field), depth_lvl + 2);
+                    print_indented!(self, ",", depth_lvl + 1);
+                }
+
+                print_indented!(self, "]", depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
             ThreadLocalRef(def_id) => {
                 print_indented!(self, "ThreadLocalRef {", depth_lvl);
                 print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 64ed7a29f6f..736ca62cacc 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -360,7 +360,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             | Rvalue::AddressOf(..)
             | Rvalue::Discriminant(..)
             | Rvalue::Len(..)
-            | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
+            | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {}
         }
     }
 
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index d908f6b3a9b..ce6d865a7dc 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -148,7 +148,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
 
             if let Some(uv) = maybe_uneval {
                 if uv.promoted.is_none() {
-                    let def_id = uv.def.def_id_for_type_of();
+                    let def_id = uv.def;
                     if self.tcx.def_kind(def_id) == DefKind::InlineConst {
                         let local_def_id = def_id.expect_local();
                         let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
@@ -375,22 +375,7 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
 }
 
 pub(crate) fn provide(providers: &mut Providers) {
-    *providers = Providers {
-        unsafety_check_result: |tcx, def_id| {
-            if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
-                tcx.unsafety_check_result_for_const_arg(def)
-            } else {
-                unsafety_check_result(tcx, ty::WithOptConstParam::unknown(def_id))
-            }
-        },
-        unsafety_check_result_for_const_arg: |tcx, (did, param_did)| {
-            unsafety_check_result(
-                tcx,
-                ty::WithOptConstParam { did, const_param_did: Some(param_did) },
-            )
-        },
-        ..*providers
-    };
+    *providers = Providers { unsafety_check_result, ..*providers };
 }
 
 /// Context information for [`UnusedUnsafeVisitor`] traversal,
@@ -492,10 +477,7 @@ fn check_unused_unsafe(
     unused_unsafes
 }
 
-fn unsafety_check_result(
-    tcx: TyCtxt<'_>,
-    def: ty::WithOptConstParam<LocalDefId>,
-) -> &UnsafetyCheckResult {
+fn unsafety_check_result(tcx: TyCtxt<'_>, def: LocalDefId) -> &UnsafetyCheckResult {
     debug!("unsafety_violations({:?})", def);
 
     // N.B., this borrow is valid because all the consumers of
@@ -510,13 +492,13 @@ fn unsafety_check_result(
         });
     }
 
-    let param_env = tcx.param_env(def.did);
+    let param_env = tcx.param_env(def);
 
-    let mut checker = UnsafetyChecker::new(body, def.did, tcx, param_env);
+    let mut checker = UnsafetyChecker::new(body, def, tcx, param_env);
     checker.visit_body(&body);
 
-    let unused_unsafes = (!tcx.is_typeck_child(def.did.to_def_id()))
-        .then(|| check_unused_unsafe(tcx, def.did, &checker.used_unsafe_blocks));
+    let unused_unsafes = (!tcx.is_typeck_child(def.to_def_id()))
+        .then(|| check_unused_unsafe(tcx, def, &checker.used_unsafe_blocks));
 
     tcx.arena.alloc(UnsafetyCheckResult {
         violations: checker.violations,
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index 3bd7f31b45d..bf01b45eb40 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -164,7 +164,6 @@ fn is_inlined(body: &Body<'_>, statement: &Statement<'_>) -> bool {
 /// whether that means const mir or runtime mir. For `const fn` this opts for runtime
 /// mir.
 fn mir_body(tcx: TyCtxt<'_>, def_id: DefId) -> &mir::Body<'_> {
-    let id = ty::WithOptConstParam::unknown(def_id);
-    let def = ty::InstanceDef::Item(id);
+    let def = ty::InstanceDef::Item(def_id);
     tcx.instance_mir(def)
 }
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index c9b24adba0c..db68adc8bc9 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -48,7 +48,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
         return false;
     }
 
-    let body = &*tcx.mir_built(ty::WithOptConstParam::unknown(local_def_id)).borrow();
+    let body = &*tcx.mir_built(local_def_id).borrow();
 
     let body_ty = tcx.type_of(def_id).skip_binder();
     let body_abi = match body_ty.kind() {
diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs
index 8601c1b2d71..f26c6de9648 100644
--- a/compiler/rustc_mir_transform/src/function_item_references.rs
+++ b/compiler/rustc_mir_transform/src/function_item_references.rs
@@ -3,7 +3,7 @@ use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::*;
-use rustc_middle::ty::{self, EarlyBinder, GenericArgKind, PredicateKind, SubstsRef, Ty, TyCtxt};
+use rustc_middle::ty::{self, EarlyBinder, PredicateKind, SubstsRef, Ty, TyCtxt};
 use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES;
 use rustc_span::{symbol::sym, Span};
 use rustc_target::spec::abi::Abi;
@@ -45,14 +45,12 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> {
                 // Handle calls to `transmute`
                 if self.tcx.is_diagnostic_item(sym::transmute, def_id) {
                     let arg_ty = args[0].ty(self.body, self.tcx);
-                    for generic_inner_ty in arg_ty.walk() {
-                        if let GenericArgKind::Type(inner_ty) = generic_inner_ty.unpack() {
-                            if let Some((fn_id, fn_substs)) =
-                                FunctionItemRefChecker::is_fn_ref(inner_ty)
-                            {
-                                let span = self.nth_arg_span(&args, 0);
-                                self.emit_lint(fn_id, fn_substs, source_info, span);
-                            }
+                    for inner_ty in arg_ty.walk().filter_map(|arg| arg.as_type()) {
+                        if let Some((fn_id, fn_substs)) =
+                            FunctionItemRefChecker::is_fn_ref(inner_ty)
+                        {
+                            let span = self.nth_arg_span(&args, 0);
+                            self.emit_lint(fn_id, fn_substs, source_info, span);
                         }
                     }
                 } else {
@@ -82,24 +80,22 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
                 let arg_defs = self.tcx.fn_sig(def_id).subst_identity().skip_binder().inputs();
                 for (arg_num, arg_def) in arg_defs.iter().enumerate() {
                     // For all types reachable from the argument type in the fn sig
-                    for generic_inner_ty in arg_def.walk() {
-                        if let GenericArgKind::Type(inner_ty) = generic_inner_ty.unpack() {
-                            // If the inner type matches the type bound by `Pointer`
-                            if inner_ty == bound_ty {
-                                // Do a substitution using the parameters from the callsite
-                                let subst_ty = EarlyBinder(inner_ty).subst(self.tcx, substs_ref);
-                                if let Some((fn_id, fn_substs)) =
-                                    FunctionItemRefChecker::is_fn_ref(subst_ty)
-                                {
-                                    let mut span = self.nth_arg_span(args, arg_num);
-                                    if span.from_expansion() {
-                                        // The operand's ctxt wouldn't display the lint since it's inside a macro so
-                                        // we have to use the callsite's ctxt.
-                                        let callsite_ctxt = span.source_callsite().ctxt();
-                                        span = span.with_ctxt(callsite_ctxt);
-                                    }
-                                    self.emit_lint(fn_id, fn_substs, source_info, span);
+                    for inner_ty in arg_def.walk().filter_map(|arg| arg.as_type()) {
+                        // If the inner type matches the type bound by `Pointer`
+                        if inner_ty == bound_ty {
+                            // Do a substitution using the parameters from the callsite
+                            let subst_ty = EarlyBinder(inner_ty).subst(self.tcx, substs_ref);
+                            if let Some((fn_id, fn_substs)) =
+                                FunctionItemRefChecker::is_fn_ref(subst_ty)
+                            {
+                                let mut span = self.nth_arg_span(args, arg_num);
+                                if span.from_expansion() {
+                                    // The operand's ctxt wouldn't display the lint since it's inside a macro so
+                                    // we have to use the callsite's ctxt.
+                                    let callsite_ctxt = span.source_callsite().ctxt();
+                                    span = span.with_ctxt(callsite_ctxt);
                                 }
+                                self.emit_lint(fn_id, fn_substs, source_info, span);
                             }
                         }
                     }
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 507e12d7238..5b3a66bc3d2 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -1399,7 +1399,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
 ) -> GeneratorLayout<'tcx> {
     assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir);
 
-    let (body, _) = tcx.mir_promoted(ty::WithOptConstParam::unknown(def_id));
+    let (body, _) = tcx.mir_promoted(def_id);
     let body = body.borrow();
     let body = &*body;
 
diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs
index 8aa3c23d019..8b811d7e870 100644
--- a/compiler/rustc_mir_transform/src/inline/cycle.rs
+++ b/compiler/rustc_mir_transform/src/inline/cycle.rs
@@ -148,8 +148,7 @@ pub(crate) fn mir_inliner_callees<'tcx>(
     let guard;
     let body = match (instance, instance.def_id().as_local()) {
         (InstanceDef::Item(_), Some(def_id)) => {
-            let def = ty::WithOptConstParam::unknown(def_id);
-            steal = tcx.mir_promoted(def).0;
+            steal = tcx.mir_promoted(def_id).0;
             guard = steal.borrow();
             &*guard
         }
diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs
index 3d06a0a495f..432852a1fdd 100644
--- a/compiler/rustc_mir_transform/src/instcombine.rs
+++ b/compiler/rustc_mir_transform/src/instcombine.rs
@@ -1,11 +1,9 @@
 //! Performs various peephole optimizations.
 
+use crate::simplify::combine_duplicate_switch_targets;
 use crate::MirPass;
 use rustc_hir::Mutability;
-use rustc_middle::mir::{
-    BinOp, Body, CastKind, Constant, ConstantKind, LocalDecls, Operand, Place, ProjectionElem,
-    Rvalue, SourceInfo, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, UnOp,
-};
+use rustc_middle::mir::*;
 use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt};
@@ -46,7 +44,7 @@ impl<'tcx> MirPass<'tcx> for InstCombine {
                 &mut block.terminator.as_mut().unwrap(),
                 &mut block.statements,
             );
-            ctx.combine_duplicate_switch_targets(&mut block.terminator.as_mut().unwrap());
+            combine_duplicate_switch_targets(block.terminator.as_mut().unwrap());
         }
     }
 }
@@ -264,19 +262,6 @@ impl<'tcx> InstCombineContext<'tcx, '_> {
         terminator.kind = TerminatorKind::Goto { target: destination_block };
     }
 
-    fn combine_duplicate_switch_targets(&self, terminator: &mut Terminator<'tcx>) {
-        let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind
-        else { return };
-
-        let otherwise = targets.otherwise();
-        if targets.iter().any(|t| t.1 == otherwise) {
-            *targets = SwitchTargets::new(
-                targets.iter().filter(|t| t.1 != otherwise),
-                targets.otherwise(),
-            );
-        }
-    }
-
     fn combine_intrinsic_assert(
         &self,
         terminator: &mut Terminator<'tcx>,
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 4ab07ab4256..7d04aead8bc 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -23,7 +23,7 @@ use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::steal::Steal;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_index::vec::IndexVec;
 use rustc_middle::mir::visit::Visitor as _;
@@ -111,36 +111,17 @@ pub fn provide(providers: &mut Providers) {
     *providers = Providers {
         mir_keys,
         mir_const,
-        mir_const_qualif: |tcx, def_id| {
-            if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
-                tcx.mir_const_qualif_const_arg(def)
-            } else {
-                mir_const_qualif(tcx, ty::WithOptConstParam::unknown(def_id))
-            }
-        },
-        mir_const_qualif_const_arg: |tcx, (did, param_did)| {
-            mir_const_qualif(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
-        },
+        mir_const_qualif,
         mir_promoted,
         mir_drops_elaborated_and_const_checked,
         mir_for_ctfe,
-        mir_for_ctfe_of_const_arg,
         mir_generator_witnesses: generator::mir_generator_witnesses,
         optimized_mir,
         is_mir_available,
         is_ctfe_mir_available: |tcx, did| is_mir_available(tcx, did),
         mir_callgraph_reachable: inline::cycle::mir_callgraph_reachable,
         mir_inliner_callees: inline::cycle::mir_inliner_callees,
-        promoted_mir: |tcx, def_id| {
-            if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
-                tcx.promoted_mir_of_const_arg(def)
-            } else {
-                promoted_mir(tcx, ty::WithOptConstParam::unknown(def_id))
-            }
-        },
-        promoted_mir_of_const_arg: |tcx, (did, param_did)| {
-            promoted_mir(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
-        },
+        promoted_mir,
         deduced_param_attrs: deduce_param_attrs::deduced_param_attrs,
         ..*providers
     };
@@ -234,8 +215,8 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
     set
 }
 
-fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> ConstQualifs {
-    let const_kind = tcx.hir().body_const_context(def.did);
+fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
+    let const_kind = tcx.hir().body_const_context(def);
 
     // No need to const-check a non-const `fn`.
     if const_kind.is_none() {
@@ -253,7 +234,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) ->
         return Default::default();
     }
 
-    let ccx = check_consts::ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def.did) };
+    let ccx = check_consts::ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def) };
 
     let mut validator = check_consts::check::Checker::new(&ccx);
     validator.check_body();
@@ -266,22 +247,14 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) ->
 /// Make MIR ready for const evaluation. This is run on all MIR, not just on consts!
 /// FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query).
 /// We used to have this for pre-miri MIR based const eval.
-fn mir_const(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Steal<Body<'_>> {
-    if let Some(def) = def.try_upgrade(tcx) {
-        return tcx.mir_const(def);
-    }
-
+fn mir_const(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
     // Unsafety check uses the raw mir, so make sure it is run.
     if !tcx.sess.opts.unstable_opts.thir_unsafeck {
-        if let Some(param_did) = def.const_param_did {
-            tcx.ensure_with_value().unsafety_check_result_for_const_arg((def.did, param_did));
-        } else {
-            tcx.ensure_with_value().unsafety_check_result(def.did);
-        }
+        tcx.ensure_with_value().unsafety_check_result(def);
     }
 
     // has_ffi_unwind_calls query uses the raw mir, so make sure it is run.
-    tcx.ensure_with_value().has_ffi_unwind_calls(def.did);
+    tcx.ensure_with_value().has_ffi_unwind_calls(def);
 
     let mut body = tcx.mir_built(def).steal();
 
@@ -307,16 +280,12 @@ fn mir_const(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Steal<
 /// Compute the main MIR body and the list of MIR bodies of the promoteds.
 fn mir_promoted(
     tcx: TyCtxt<'_>,
-    def: ty::WithOptConstParam<LocalDefId>,
+    def: LocalDefId,
 ) -> (&Steal<Body<'_>>, &Steal<IndexVec<Promoted, Body<'_>>>) {
-    if let Some(def) = def.try_upgrade(tcx) {
-        return tcx.mir_promoted(def);
-    }
-
     // Ensure that we compute the `mir_const_qualif` for constants at
     // this point, before we steal the mir-const result.
     // Also this means promotion can rely on all const checks having been done.
-    let const_qualifs = tcx.mir_const_qualif_opt_const_arg(def);
+    let const_qualifs = tcx.mir_const_qualif(def);
     let mut body = tcx.mir_const(def).steal();
     if let Some(error_reported) = const_qualifs.tainted_by_errors {
         body.tainted_by_errors = Some(error_reported);
@@ -344,38 +313,22 @@ fn mir_promoted(
 
 /// Compute the MIR that is used during CTFE (and thus has no optimizations run on it)
 fn mir_for_ctfe(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &Body<'_> {
-    if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
-        tcx.mir_for_ctfe_of_const_arg(def)
-    } else {
-        tcx.arena.alloc(inner_mir_for_ctfe(tcx, ty::WithOptConstParam::unknown(def_id)))
-    }
+    tcx.arena.alloc(inner_mir_for_ctfe(tcx, def_id))
 }
 
-/// Same as `mir_for_ctfe`, but used to get the MIR of a const generic parameter.
-/// The docs on `WithOptConstParam` explain this a bit more, but the TLDR is that
-/// we'd get cycle errors with `mir_for_ctfe`, because typeck would need to typeck
-/// the const parameter while type checking the main body, which in turn would try
-/// to type check the main body again.
-fn mir_for_ctfe_of_const_arg(tcx: TyCtxt<'_>, (did, param_did): (LocalDefId, DefId)) -> &Body<'_> {
-    tcx.arena.alloc(inner_mir_for_ctfe(
-        tcx,
-        ty::WithOptConstParam { did, const_param_did: Some(param_did) },
-    ))
-}
-
-fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> {
+fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
     // FIXME: don't duplicate this between the optimized_mir/mir_for_ctfe queries
-    if tcx.is_constructor(def.did.to_def_id()) {
+    if tcx.is_constructor(def.to_def_id()) {
         // There's no reason to run all of the MIR passes on constructors when
         // we can just output the MIR we want directly. This also saves const
         // qualification and borrow checking the trouble of special casing
         // constructors.
-        return shim::build_adt_ctor(tcx, def.did.to_def_id());
+        return shim::build_adt_ctor(tcx, def.to_def_id());
     }
 
     let context = tcx
         .hir()
-        .body_const_context(def.did)
+        .body_const_context(def)
         .expect("mir_for_ctfe should not be used for runtime functions");
 
     let body = tcx.mir_drops_elaborated_and_const_checked(def).borrow().clone();
@@ -413,29 +366,19 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -
 /// Obtain just the main MIR (no promoteds) and run some cleanups on it. This also runs
 /// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't
 /// end up missing the source MIR due to stealing happening.
-fn mir_drops_elaborated_and_const_checked(
-    tcx: TyCtxt<'_>,
-    def: ty::WithOptConstParam<LocalDefId>,
-) -> &Steal<Body<'_>> {
-    if let Some(def) = def.try_upgrade(tcx) {
-        return tcx.mir_drops_elaborated_and_const_checked(def);
-    }
-
+fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
     if tcx.sess.opts.unstable_opts.drop_tracking_mir
-        && let DefKind::Generator = tcx.def_kind(def.did)
+        && let DefKind::Generator = tcx.def_kind(def)
     {
-        tcx.ensure_with_value().mir_generator_witnesses(def.did);
+        tcx.ensure_with_value().mir_generator_witnesses(def);
     }
-    let mir_borrowck = tcx.mir_borrowck_opt_const_arg(def);
+    let mir_borrowck = tcx.mir_borrowck(def);
 
-    let is_fn_like = tcx.def_kind(def.did).is_fn_like();
+    let is_fn_like = tcx.def_kind(def).is_fn_like();
     if is_fn_like {
-        let did = def.did.to_def_id();
-        let def = ty::WithOptConstParam::unknown(did);
-
         // Do not compute the mir call graph without said call graph actually being used.
         if inline::Inline.is_enabled(&tcx.sess) {
-            tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def));
+            tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def.to_def_id()));
         }
     }
 
@@ -564,12 +507,12 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             //
             // Const-prop runs unconditionally, but doesn't mutate the MIR at mir-opt-level=0.
             &const_debuginfo::ConstDebugInfo,
-            &o1(simplify_branches::SimplifyConstConditionPassName::AfterConstProp),
+            &o1(simplify_branches::SimplifyConstCondition::AfterConstProp),
             &early_otherwise_branch::EarlyOtherwiseBranch,
             &simplify_comparison_integral::SimplifyComparisonIntegral,
             &dead_store_elimination::DeadStoreElimination,
             &dest_prop::DestinationPropagation,
-            &o1(simplify_branches::SimplifyConstConditionPassName::Final),
+            &o1(simplify_branches::SimplifyConstCondition::Final),
             &o1(remove_noop_landing_pads::RemoveNoopLandingPads),
             &o1(simplify::SimplifyCfg::Final),
             &nrvo::RenameReturnPlace,
@@ -588,7 +531,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
 
 /// Optimize the MIR and prepare it for codegen.
 fn optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> &Body<'_> {
-    assert_eq!(ty::WithOptConstParam::try_lookup(did, tcx), None);
     tcx.arena.alloc(inner_optimized_mir(tcx, did))
 }
 
@@ -610,8 +552,7 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
         Some(other) => panic!("do not use `optimized_mir` for constants: {:?}", other),
     }
     debug!("about to call mir_drops_elaborated...");
-    let body =
-        tcx.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(did)).steal();
+    let body = tcx.mir_drops_elaborated_and_const_checked(did).steal();
     let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::NotConst);
     debug!("body: {:#?}", body);
     run_optimization_passes(tcx, &mut body);
@@ -621,15 +562,12 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
 
 /// Fetch all the promoteds of an item and prepare their MIR bodies to be ready for
 /// constant evaluation once all substitutions become known.
-fn promoted_mir(
-    tcx: TyCtxt<'_>,
-    def: ty::WithOptConstParam<LocalDefId>,
-) -> &IndexVec<Promoted, Body<'_>> {
-    if tcx.is_constructor(def.did.to_def_id()) {
+fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_>> {
+    if tcx.is_constructor(def.to_def_id()) {
         return tcx.arena.alloc(IndexVec::new());
     }
 
-    let tainted_by_errors = tcx.mir_borrowck_opt_const_arg(def).tainted_by_errors;
+    let tainted_by_errors = tcx.mir_borrowck(def).tainted_by_errors;
     let mut promoted = tcx.mir_promoted(def).1.steal();
 
     for body in &mut promoted {
diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs
index ef367faf6a7..2479856b727 100644
--- a/compiler/rustc_mir_transform/src/separate_const_switch.rs
+++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs
@@ -303,8 +303,7 @@ fn find_determining_place<'tcx>(
                     | Rvalue::NullaryOp(_, _)
                     | Rvalue::ShallowInitBox(_, _)
                     | Rvalue::UnaryOp(_, Operand::Constant(_))
-                    | Rvalue::Cast(_, Operand::Constant(_), _)
-                    => return None,
+                    | Rvalue::Cast(_, Operand::Constant(_), _) => return None,
                 }
             }
 
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index 88574addaa0..e1ca7c107b9 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -278,6 +278,18 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
     }
 }
 
+pub fn combine_duplicate_switch_targets(terminator: &mut Terminator<'_>) {
+    if let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind {
+        let otherwise = targets.otherwise();
+        if targets.iter().any(|t| t.1 == otherwise) {
+            *targets = SwitchTargets::new(
+                targets.iter().filter(|t| t.1 != otherwise),
+                targets.otherwise(),
+            );
+        }
+    }
+}
+
 pub fn remove_duplicate_unreachable_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     struct OptApplier<'tcx> {
         tcx: TyCtxt<'tcx>,
@@ -298,6 +310,8 @@ pub fn remove_duplicate_unreachable_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut B
                 }
             }
 
+            combine_duplicate_switch_targets(terminator);
+
             self.super_terminator(terminator, location);
         }
     }
diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs
index ddaf86a9e73..c65a7ec6783 100644
--- a/compiler/rustc_mir_transform/src/simplify_branches.rs
+++ b/compiler/rustc_mir_transform/src/simplify_branches.rs
@@ -2,18 +2,16 @@ use crate::MirPass;
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
 
-pub enum SimplifyConstConditionPassName {
+pub enum SimplifyConstCondition {
     AfterConstProp,
     Final,
 }
 /// A pass that replaces a branch with a goto when its condition is known.
-impl<'tcx> MirPass<'tcx> for SimplifyConstConditionPassName {
+impl<'tcx> MirPass<'tcx> for SimplifyConstCondition {
     fn name(&self) -> &'static str {
         match self {
-            SimplifyConstConditionPassName::AfterConstProp => {
-                "SimplifyConstCondition-after-const-prop"
-            }
-            SimplifyConstConditionPassName::Final => "SimplifyConstCondition-final",
+            SimplifyConstCondition::AfterConstProp => "SimplifyConstCondition-after-const-prop",
+            SimplifyConstCondition::Final => "SimplifyConstCondition-final",
         }
     }
 
diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs
index 4f2c2ea425f..bd24deb590a 100644
--- a/compiler/rustc_monomorphize/src/partitioning/default.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/default.rs
@@ -270,7 +270,7 @@ fn characteristic_def_id_of_mono_item<'tcx>(
     match mono_item {
         MonoItem::Fn(instance) => {
             let def_id = match instance.def {
-                ty::InstanceDef::Item(def) => def.did,
+                ty::InstanceDef::Item(def) => def,
                 ty::InstanceDef::VTableShim(..)
                 | ty::InstanceDef::ReifyShim(..)
                 | ty::InstanceDef::FnPtrShim(..)
@@ -424,8 +424,7 @@ fn mono_item_visibility<'tcx>(
     };
 
     let def_id = match instance.def {
-        InstanceDef::Item(def) => def.did,
-        InstanceDef::DropGlue(def_id, Some(_)) => def_id,
+        InstanceDef::Item(def_id) | InstanceDef::DropGlue(def_id, Some(_)) => def_id,
 
         // We match the visibility of statics here
         InstanceDef::ThreadLocalShim(def_id) => {
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index 63263a642ac..ddc62d9c390 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -232,7 +232,7 @@ impl<'a, 'tcx> MarkUsedGenericParams<'a, 'tcx> {
     /// a closure, generator or constant).
     #[instrument(level = "debug", skip(self, def_id, substs))]
     fn visit_child_body(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) {
-        let instance = ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id));
+        let instance = ty::InstanceDef::Item(def_id);
         let unused = self.tcx.unused_generic_params(instance);
         debug!(?self.unused_parameters, ?unused);
         for (i, arg) in substs.iter().enumerate() {
@@ -272,10 +272,10 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
                 // Avoid considering `T` unused when constants are of the form:
                 //   `<Self as Foo<T>>::foo::promoted[p]`
                 if let Some(p) = promoted {
-                    if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self {
+                    if self.def_id == def && !self.tcx.generics_of(def).has_self {
                         // If there is a promoted, don't look at the substs - since it will always contain
                         // the generic parameters, instead, traverse the promoted MIR.
-                        let promoted = self.tcx.promoted_mir(def.did);
+                        let promoted = self.tcx.promoted_mir(def);
                         self.visit_body(&promoted[p]);
                     }
                 }
@@ -305,9 +305,9 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for MarkUsedGenericParams<'a, 'tcx> {
                 ControlFlow::Continue(())
             }
             ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs })
-                if matches!(self.tcx.def_kind(def.did), DefKind::AnonConst) =>
+                if matches!(self.tcx.def_kind(def), DefKind::AnonConst) =>
             {
-                self.visit_child_body(def.did, substs);
+                self.visit_child_body(def, substs);
                 ControlFlow::Continue(())
             }
             _ => c.super_visit_with(self),
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 5cfe691df17..3ae5b45d330 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -237,6 +237,37 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         }
     }
 
+    fn handle_offset_of(&mut self, expr: &'tcx hir::Expr<'tcx>) {
+        let data = self.typeck_results().offset_of_data();
+        let &(container, ref indices) =
+            data.get(expr.hir_id).expect("no offset_of_data for offset_of");
+
+        let body_did = self.typeck_results().hir_owner.to_def_id();
+        let param_env = self.tcx.param_env(body_did);
+
+        let mut current_ty = container;
+
+        for &index in indices {
+            match current_ty.kind() {
+                ty::Adt(def, subst) => {
+                    let field = &def.non_enum_variant().fields[index];
+
+                    self.insert_def_id(field.did);
+                    let field_ty = field.ty(self.tcx, subst);
+
+                    current_ty = self.tcx.normalize_erasing_regions(param_env, field_ty);
+                }
+                // we don't need to mark tuple fields as live,
+                // but we may need to mark subfields
+                ty::Tuple(tys) => {
+                    current_ty =
+                        self.tcx.normalize_erasing_regions(param_env, tys[index.as_usize()]);
+                }
+                _ => span_bug!(expr.span, "named field access on non-ADT"),
+            }
+        }
+    }
+
     fn mark_live_symbols(&mut self) {
         let mut scanned = LocalDefIdSet::default();
         while let Some(id) = self.worklist.pop() {
@@ -405,6 +436,9 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
             hir::ExprKind::Closure(cls) => {
                 self.insert_def_id(cls.def_id.to_def_id());
             }
+            hir::ExprKind::OffsetOf(..) => {
+                self.handle_offset_of(expr);
+            }
             _ => (),
         }
 
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index 47e032758f2..dc5e454074d 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -302,7 +302,8 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
             [
                 ConstBlock, Array, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type,
                 DropTemps, Let, If, Loop, Match, Closure, Block, Assign, AssignOp, Field, Index,
-                Path, AddrOf, Break, Continue, Ret, InlineAsm, Struct, Repeat, Yield, Err
+                Path, AddrOf, Break, Continue, Ret, InlineAsm, OffsetOf, Struct, Repeat, Yield,
+                Err
             ]
         );
         hir_visit::walk_expr(self, e)
@@ -568,7 +569,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
                 Array, ConstBlock, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, Let,
                 If, While, ForLoop, Loop, Match, Closure, Block, Async, Await, TryBlock, Assign,
                 AssignOp, Field, Index, Range, Underscore, Path, AddrOf, Break, Continue, Ret,
-                InlineAsm, FormatArgs, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, IncludedBytes, Err
+                InlineAsm, FormatArgs, OffsetOf, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, IncludedBytes, Err
             ]
         );
         ast_visit::walk_expr(self, e)
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index a8471ce3b6f..b39a8c5598f 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -473,6 +473,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
             | hir::ExprKind::Struct(..)
             | hir::ExprKind::Repeat(..)
             | hir::ExprKind::InlineAsm(..)
+            | hir::ExprKind::OffsetOf(..)
             | hir::ExprKind::Type(..)
             | hir::ExprKind::Err(_)
             | hir::ExprKind::Path(hir::QPath::TypeRelative(..))
@@ -1129,7 +1130,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             | hir::ExprKind::ConstBlock(..)
             | hir::ExprKind::Err(_)
             | hir::ExprKind::Path(hir::QPath::TypeRelative(..))
-            | hir::ExprKind::Path(hir::QPath::LangItem(..)) => succ,
+            | hir::ExprKind::Path(hir::QPath::LangItem(..))
+            | hir::ExprKind::OffsetOf(..) => succ,
 
             // Note that labels have been resolved, so we don't need to look
             // at the label ident
@@ -1418,6 +1420,7 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) {
         | hir::ExprKind::ConstBlock(..)
         | hir::ExprKind::Block(..)
         | hir::ExprKind::AddrOf(..)
+        | hir::ExprKind::OffsetOf(..)
         | hir::ExprKind::Struct(..)
         | hir::ExprKind::Repeat(..)
         | hir::ExprKind::Closure { .. }
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index c398467f03e..cf8d9300a11 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -203,6 +203,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
             | ExprKind::Break(..)
             | ExprKind::Continue(..)
             | ExprKind::Ret(..)
+            | ExprKind::OffsetOf(..)
             | ExprKind::Struct(..)
             | ExprKind::Repeat(..)
             | ExprKind::Yield(..) => {
diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs
index 40869fdc467..c05323c2d6c 100644
--- a/compiler/rustc_query_impl/src/on_disk_cache.rs
+++ b/compiler/rustc_query_impl/src/on_disk_cache.rs
@@ -300,7 +300,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
                     interpret_alloc_index.reserve(new_n - n);
                     for idx in n..new_n {
                         let id = encoder.interpret_allocs[idx];
-                        let pos = encoder.position() as u32;
+                        let pos: u32 = encoder.position().try_into().unwrap();
                         interpret_alloc_index.push(pos);
                         interpret::specialized_encode_alloc_id(&mut encoder, tcx, id);
                     }
diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs
index 579a789244b..08b588a8c94 100644
--- a/compiler/rustc_query_impl/src/profiling_support.rs
+++ b/compiler/rustc_query_impl/src/profiling_support.rs
@@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::profiling::SelfProfiler;
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathData;
-use rustc_middle::ty::{TyCtxt, WithOptConstParam};
+use rustc_middle::ty::TyCtxt;
 use rustc_query_system::query::QueryCache;
 use std::fmt::Debug;
 use std::io::Write;
@@ -151,37 +151,6 @@ impl SpecIntoSelfProfilingString for LocalDefId {
     }
 }
 
-impl<T: SpecIntoSelfProfilingString> SpecIntoSelfProfilingString for WithOptConstParam<T> {
-    fn spec_to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId {
-        // We print `WithOptConstParam` values as tuples to make them shorter
-        // and more readable, without losing information:
-        //
-        // "WithOptConstParam { did: foo::bar, const_param_did: Some(foo::baz) }"
-        // becomes "(foo::bar, foo::baz)" and
-        // "WithOptConstParam { did: foo::bar, const_param_did: None }"
-        // becomes "(foo::bar, _)".
-
-        let did = StringComponent::Ref(self.did.to_self_profile_string(builder));
-
-        let const_param_did = if let Some(const_param_did) = self.const_param_did {
-            let const_param_did = builder.def_id_to_string_id(const_param_did);
-            StringComponent::Ref(const_param_did)
-        } else {
-            StringComponent::Value("_")
-        };
-
-        let components = [
-            StringComponent::Value("("),
-            did,
-            StringComponent::Value(", "),
-            const_param_did,
-            StringComponent::Value(")"),
-        ];
-
-        builder.profiler.alloc_string(&components[..])
-    }
-}
-
 impl<T0, T1> SpecIntoSelfProfilingString for (T0, T1)
 where
     T0: SpecIntoSelfProfilingString,
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 4a6d07a03cc..bce01debc53 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -410,9 +410,28 @@ where
         // as its feeding query had. So if the fed query is red, so is its feeder, which will
         // get evaluated first, and re-feed the query.
         if let Some((cached_result, _)) = cache.lookup(&key) {
-            panic!(
-                "fed query later has its value computed. The already cached value: {}",
-                (query.format_value())(&cached_result)
+            let Some(hasher) = query.hash_result() else {
+                panic!(
+                    "no_hash fed query later has its value computed.\n\
+                    Remove `no_hash` modifier to allow recomputation.\n\
+                    The already cached value: {}",
+                    (query.format_value())(&cached_result)
+                );
+            };
+
+            let (old_hash, new_hash) = qcx.dep_context().with_stable_hashing_context(|mut hcx| {
+                (hasher(&mut hcx, &cached_result), hasher(&mut hcx, &result))
+            });
+            let formatter = query.format_value();
+            debug_assert_eq!(
+                old_hash,
+                new_hash,
+                "Computed query value for {:?}({:?}) is inconsistent with fed value,\n\
+                computed={:#?}\nfed={:#?}",
+                query.dep_kind(),
+                key,
+                formatter(&result),
+                formatter(&cached_result),
             );
         }
     }
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index f905cec1011..967c9e22fb2 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -197,10 +197,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     }
 
     pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'a>) {
-        // Query `module_children` is not used because hashing spans in its result is expensive.
-        let children =
-            Vec::from_iter(self.cstore().module_children_untracked(module.def_id(), self.tcx.sess));
-        for child in children {
+        for child in self.tcx.module_children(module.def_id()) {
             let parent_scope = ParentScope::module(module, self);
             BuildReducedGraphVisitor { r: self, parent_scope }
                 .build_reduced_graph_for_external_crate_res(child);
@@ -929,9 +926,9 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
     }
 
     /// Builds the reduced graph for a single item in an external crate.
-    fn build_reduced_graph_for_external_crate_res(&mut self, child: ModChild) {
+    fn build_reduced_graph_for_external_crate_res(&mut self, child: &ModChild) {
         let parent = self.parent_scope.module;
-        let ModChild { ident, res, vis, reexport_chain } = child;
+        let ModChild { ident, res, vis, ref reexport_chain } = *child;
         let span = self.r.def_span(
             reexport_chain
                 .first()
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index 9eae99be2e9..d433391f272 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -367,6 +367,7 @@ fn preprocess_link(link: &str) -> Box<str> {
     let link = link.strip_suffix("{}").unwrap_or(link);
     let link = link.strip_suffix("[]").unwrap_or(link);
     let link = if link != "!" { link.strip_suffix('!').unwrap_or(link) } else { link };
+    let link = link.trim();
     strip_generics_from_path(link).unwrap_or_else(|_| link.into())
 }
 
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 631dd0a2146..8e8ad72ec8a 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1452,9 +1452,9 @@ options! {
     fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
         (default: no)"),
-    flatten_format_args: bool = (false, parse_bool, [TRACKED],
+    flatten_format_args: bool = (true, parse_bool, [TRACKED],
         "flatten nested format_args!() and literals into a simplified format_args!() call \
-        (default: no)"),
+        (default: yes)"),
     force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
         "force all crates to be `rustc_private` unstable (default: no)"),
     fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 4dad3c6bce7..09cb6fd22d5 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -128,6 +128,18 @@ fn rustc_place_to_place(place: &rustc_middle::mir::Place<'_>) -> stable_mir::mir
     stable_mir::mir::Place { local: place.local.as_usize() }
 }
 
+fn rustc_unwind_to_unwind(
+    unwind: &rustc_middle::mir::UnwindAction,
+) -> stable_mir::mir::UnwindAction {
+    use rustc_middle::mir::UnwindAction;
+    match unwind {
+        UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue,
+        UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable,
+        UnwindAction::Terminate => stable_mir::mir::UnwindAction::Terminate,
+        UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()),
+    }
+}
+
 fn rustc_terminator_to_terminator(
     terminator: &rustc_middle::mir::Terminator<'_>,
 ) -> stable_mir::mir::Terminator {
@@ -151,7 +163,15 @@ fn rustc_terminator_to_terminator(
         Return => Terminator::Return,
         Unreachable => Terminator::Unreachable,
         Drop { .. } => todo!(),
-        Call { .. } => todo!(),
+        Call { func, args, destination, target, unwind, from_hir_call: _, fn_span: _ } => {
+            Terminator::Call {
+                func: rustc_op_to_op(func),
+                args: args.iter().map(|arg| rustc_op_to_op(arg)).collect(),
+                destination: rustc_place_to_place(destination),
+                target: target.map(|t| t.as_usize()),
+                unwind: rustc_unwind_to_unwind(unwind),
+            }
+        }
         Assert { .. } => todo!(),
         Yield { .. } => todo!(),
         GeneratorDrop => todo!(),
diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs
index c504065c993..bd5e6b68a12 100644
--- a/compiler/rustc_smir/src/stable_mir/mir/body.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs
@@ -33,7 +33,7 @@ pub enum Terminator {
         args: Vec<Operand>,
         destination: Place,
         target: Option<usize>,
-        cleanup: Option<usize>,
+        unwind: UnwindAction,
     },
     Assert {
         cond: Operand,
@@ -45,6 +45,14 @@ pub enum Terminator {
 }
 
 #[derive(Clone, Debug)]
+pub enum UnwindAction {
+    Continue,
+    Unreachable,
+    Terminate,
+    Cleanup(usize),
+}
+
+#[derive(Clone, Debug)]
 pub enum Statement {
     Assign(Place, Operand),
     Nop,
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 83f4907d517..8a900ca427e 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -1044,17 +1044,26 @@ impl fmt::Debug for Span {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // Use the global `SourceMap` to print the span. If that's not
         // available, fall back to printing the raw values.
-        with_session_globals(|session_globals| {
-            if let Some(source_map) = &*session_globals.source_map.borrow() {
-                write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt())
-            } else {
-                f.debug_struct("Span")
-                    .field("lo", &self.lo())
-                    .field("hi", &self.hi())
-                    .field("ctxt", &self.ctxt())
-                    .finish()
-            }
-        })
+
+        fn fallback(span: Span, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            f.debug_struct("Span")
+                .field("lo", &span.lo())
+                .field("hi", &span.hi())
+                .field("ctxt", &span.ctxt())
+                .finish()
+        }
+
+        if SESSION_GLOBALS.is_set() {
+            with_session_globals(|session_globals| {
+                if let Some(source_map) = &*session_globals.source_map.borrow() {
+                    write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt())
+                } else {
+                    fallback(*self, f)
+                }
+            })
+        } else {
+            fallback(*self, f)
+        }
     }
 }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index d6ee7ac34aa..9891915d076 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1037,6 +1037,7 @@ symbols! {
         object_safe_for_dispatch,
         of,
         offset,
+        offset_of,
         omit_gdb_pretty_printer_section,
         on,
         on_unimplemented,
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index 262e8546a5d..a9152b8113f 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -814,16 +814,10 @@ fn transform_substs<'tcx>(
     substs: SubstsRef<'tcx>,
     options: TransformTyOptions,
 ) -> SubstsRef<'tcx> {
-    let substs = substs.iter().map(|subst| {
-        if let GenericArgKind::Type(ty) = subst.unpack() {
-            if is_c_void_ty(tcx, ty) {
-                tcx.mk_unit().into()
-            } else {
-                transform_ty(tcx, ty, options).into()
-            }
-        } else {
-            subst
-        }
+    let substs = substs.iter().map(|subst| match subst.unpack() {
+        GenericArgKind::Type(ty) if is_c_void_ty(tcx, ty) => tcx.mk_unit().into(),
+        GenericArgKind::Type(ty) => transform_ty(tcx, ty, options).into(),
+        _ => subst,
     });
     tcx.mk_substs_from_iter(substs)
 }
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index 8d2e92cc76c..589cd3cf96b 100644
--- a/compiler/rustc_target/src/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
@@ -124,6 +124,21 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
     {
         Ty::is_unit(self)
     }
+
+    pub fn offset_of_subfield<C>(self, cx: &C, indices: impl Iterator<Item = usize>) -> Size
+    where
+        Ty: TyAbiInterface<'a, C>,
+    {
+        let mut layout = self;
+        let mut offset = Size::ZERO;
+
+        for index in indices {
+            offset += layout.fields.offset(index);
+            layout = layout.field(cx, index);
+        }
+
+        offset
+    }
 }
 
 impl<'a, Ty> TyAndLayout<'a, Ty> {
diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
index 5c6dcc0aba9..4c7f64b2078 100644
--- a/compiler/rustc_target/src/spec/apple_base.rs
+++ b/compiler/rustc_target/src/spec/apple_base.rs
@@ -19,6 +19,7 @@ pub enum Arch {
     I386,
     I686,
     X86_64,
+    X86_64h,
     X86_64_sim,
     X86_64_macabi,
     Arm64_macabi,
@@ -36,6 +37,7 @@ impl Arch {
             I386 => "i386",
             I686 => "i686",
             X86_64 | X86_64_sim | X86_64_macabi => "x86_64",
+            X86_64h => "x86_64h",
         }
     }
 
@@ -44,13 +46,13 @@ impl Arch {
             Armv7 | Armv7k | Armv7s => "arm",
             Arm64 | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64",
             I386 | I686 => "x86",
-            X86_64 | X86_64_sim | X86_64_macabi => "x86_64",
+            X86_64 | X86_64_sim | X86_64_macabi | X86_64h => "x86_64",
         })
     }
 
     fn target_abi(self) -> &'static str {
         match self {
-            Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 => "",
+            Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "",
             X86_64_macabi | Arm64_macabi => "macabi",
             // x86_64-apple-ios is a simulator target, even though it isn't
             // declared that way in the target like the other ones...
@@ -67,6 +69,10 @@ impl Arch {
             Arm64_32 => "apple-s4",
             I386 | I686 => "yonah",
             X86_64 | X86_64_sim => "core2",
+            // Note: `core-avx2` is slightly more advanced than `x86_64h`, see
+            // comments (and disabled features) in `x86_64h_apple_darwin` for
+            // details.
+            X86_64h => "core-avx2",
             X86_64_macabi => "core2",
             Arm64_macabi => "apple-a12",
             Arm64_sim => "apple-a12",
@@ -182,8 +188,13 @@ fn deployment_target(var_name: &str) -> Option<(u32, u32)> {
 }
 
 fn macos_default_deployment_target(arch: Arch) -> (u32, u32) {
-    // Note: Arm64_sim is not included since macOS has no simulator.
-    if matches!(arch, Arm64 | Arm64_macabi) { (11, 0) } else { (10, 7) }
+    match arch {
+        // Note: Arm64_sim is not included since macOS has no simulator.
+        Arm64 | Arm64_macabi => (11, 0),
+        // x86_64h-apple-darwin only supports macOS 10.8 and later
+        X86_64h => (10, 8),
+        _ => (10, 7),
+    }
 }
 
 fn macos_deployment_target(arch: Arch) -> (u32, u32) {
@@ -227,7 +238,7 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow<str>]>
         // of the linking environment that's wrong and reversed.
         match arch {
             Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim
-            | Arm64_sim => {
+            | X86_64h | Arm64_sim => {
                 cvs!["MACOSX_DEPLOYMENT_TARGET"]
             }
             X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"],
diff --git a/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs
index ebd74012dcd..9bcd56bed00 100644
--- a/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs
@@ -3,6 +3,7 @@ use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::linux_gnu_base::opts();
+    base.cpu = "M68020".into();
     base.max_atomic_width = Some(32);
 
     Target {
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 3ee3a8ea227..10d38c34919 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1112,6 +1112,7 @@ supported_targets! {
 
     ("aarch64-apple-darwin", aarch64_apple_darwin),
     ("x86_64-apple-darwin", x86_64_apple_darwin),
+    ("x86_64h-apple-darwin", x86_64h_apple_darwin),
     ("i686-apple-darwin", i686_apple_darwin),
 
     // FIXME(#106649): Remove aarch64-fuchsia in favor of aarch64-unknown-fuchsia
diff --git a/compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs
new file mode 100644
index 00000000000..54f7490b2c0
--- /dev/null
+++ b/compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs
@@ -0,0 +1,44 @@
+use super::apple_base::{macos_llvm_target, opts, Arch};
+use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet};
+use crate::spec::{StackProbeType, Target, TargetOptions};
+
+pub fn target() -> Target {
+    let arch = Arch::X86_64h;
+    let mut base = opts("macos", arch);
+    base.max_atomic_width = Some(128);
+    base.frame_pointer = FramePointer::Always;
+    base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
+    base.stack_probes = StackProbeType::X86;
+    base.supported_sanitizers =
+        SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;
+
+    // x86_64h is core2-avx without a few of the features which would otherwise
+    // be guaranteed, so we need to disable those. This imitates clang's logic:
+    // - https://github.com/llvm/llvm-project/blob/bd1f7c417/clang/lib/Driver/ToolChains/Arch/X86.cpp#L77-L78
+    // - https://github.com/llvm/llvm-project/blob/bd1f7c417/clang/lib/Driver/ToolChains/Arch/X86.cpp#L133-L141
+    //
+    // FIXME: Sadly, turning these off here disables them in such a way that they
+    // aren't re-enabled by `-Ctarget-cpu=native` (on a machine that has them).
+    // It would be nice if this were not the case, but fixing it seems tricky
+    // (and given that the main use-case for this target is for use in universal
+    // binaries, probably not that important).
+    base.features = "-rdrnd,-aes,-pclmul,-rtm,-fsgsbase".into();
+    // Double-check that the `cpu` is what we expect (if it's not the list above
+    // may need updating).
+    assert_eq!(
+        base.cpu, "core-avx2",
+        "you need to adjust the feature list in x86_64h-apple-darwin if you change this",
+    );
+
+    Target {
+        // Clang automatically chooses a more specific target based on
+        // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
+        // correctly, we do too.
+        llvm_target: macos_llvm_target(arch).into(),
+        pointer_width: 64,
+        data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+            .into(),
+        arch: arch.target_arch(),
+        options: TargetOptions { mcount: "\u{1}mcount".into(), ..base },
+    }
+}
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index bb574954587..bd52957d162 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -57,6 +57,14 @@ pub struct EvalCtxt<'a, 'tcx> {
     pub(super) search_graph: &'a mut SearchGraph<'tcx>,
 
     pub(super) nested_goals: NestedGoals<'tcx>,
+
+    // Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`?
+    //
+    // If so, then it can no longer be used to make a canonical query response,
+    // since subsequent calls to `try_evaluate_added_goals` have possibly dropped
+    // ambiguous goals. Instead, a probe needs to be introduced somewhere in the
+    // evaluation code.
+    tainted: Result<(), NoSolution>,
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -121,6 +129,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
             max_input_universe: ty::UniverseIndex::ROOT,
             var_values: CanonicalVarValues::dummy(),
             nested_goals: NestedGoals::new(),
+            tainted: Ok(()),
         };
         let result = ecx.evaluate_goal(IsNormalizesToHack::No, goal);
 
@@ -172,6 +181,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
                 max_input_universe: canonical_goal.max_universe,
                 search_graph,
                 nested_goals: NestedGoals::new(),
+                tainted: Ok(()),
             };
             ecx.compute_goal(goal)
         })
@@ -391,6 +401,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
             },
         );
 
+        if response.is_err() {
+            self.tainted = Err(NoSolution);
+        }
+
         self.nested_goals = goals;
         response
     }
@@ -404,6 +418,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             max_input_universe: self.max_input_universe,
             search_graph: self.search_graph,
             nested_goals: self.nested_goals.clone(),
+            tainted: self.tainted,
         };
         self.infcx.probe(|_| f(&mut ecx))
     }
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index 23cf0f0c724..2dea36811d8 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -51,6 +51,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         certainty: Certainty,
     ) -> QueryResult<'tcx> {
         let goals_certainty = self.try_evaluate_added_goals()?;
+        assert_eq!(
+            self.tainted,
+            Ok(()),
+            "EvalCtxt is tainted -- nested goals may have been dropped in a \
+            previous call to `try_evaluate_added_goals!`"
+        );
+
         let certainty = certainty.unify_with(goals_certainty);
 
         let external_constraints = self.compute_external_query_constraints()?;
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index 14cb43b89c3..3a2acbeb32e 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -198,7 +198,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
             let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const {
                 let identity_substs =
                     ty::InternalSubsts::identity_for_item(tcx, assoc_def.item.def_id);
-                let did = ty::WithOptConstParam::unknown(assoc_def.item.def_id);
+                let did = assoc_def.item.def_id;
                 let kind =
                     ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(did, identity_substs));
                 ty.map_bound(|ty| tcx.mk_const(kind, ty).into())
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 182d995c4eb..222af4c2ace 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -796,10 +796,9 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                                 Ok(Some(valtree)) => Ok(selcx.tcx().mk_const(valtree, c.ty())),
                                 Ok(None) => {
                                     let tcx = self.tcx;
-                                    let def_id = unevaluated.def.did;
                                     let reported =
                                         tcx.sess.emit_err(UnableToConstructConstantValue {
-                                            span: tcx.def_span(def_id),
+                                            span: tcx.def_span(unevaluated.def),
                                             unevaluated: unevaluated,
                                         });
                                     Err(ErrorHandled::Reported(reported))
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 345e84990ed..9d99d30d45c 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -44,7 +44,7 @@ pub fn is_const_evaluatable<'tcx>(
         let ct = tcx.expand_abstract_consts(unexpanded_ct);
 
         let is_anon_ct = if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
-            tcx.def_kind(uv.def.did) == DefKind::AnonConst
+            tcx.def_kind(uv.def) == DefKind::AnonConst
         } else {
             false
         };
@@ -119,7 +119,7 @@ pub fn is_const_evaluatable<'tcx>(
                 tcx.sess
                     .struct_span_fatal(
                         // Slightly better span than just using `span` alone
-                        if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def.did) } else { span },
+                        if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def) } else { span },
                         "failed to evaluate generic const expression",
                     )
                     .note("the crate this constant originates from uses `#![feature(generic_const_exprs)]`")
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 726b08dc7d7..ae21dcd2a36 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1476,7 +1476,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         };
                         let mut err =
                             self.tcx.sess.struct_span_err(span, "unconstrained generic constant");
-                        let const_span = self.tcx.def_span(uv.def.did);
+                        let const_span = self.tcx.def_span(uv.def);
                         match self.tcx.sess.source_map().span_to_snippet(const_span) {
                             Ok(snippet) => err.help(&format!(
                                 "try adding a `where` bound using this expression: `where [(); {}]:`",
@@ -1771,7 +1771,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         .tcx
                         .mk_const(
                             ty::UnevaluatedConst {
-                                def: ty::WithOptConstParam::unknown(data.projection_ty.def_id),
+                                def: data.projection_ty.def_id,
                                 substs: data.projection_ty.substs,
                             },
                             ct.ty(),
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 26cadab3e9f..43196d1e629 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -540,8 +540,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                         use ty::ConstKind::Unevaluated;
                         match (c1.kind(), c2.kind()) {
                             (Unevaluated(a), Unevaluated(b))
-                                if a.def.did == b.def.did
-                                    && tcx.def_kind(a.def.did) == DefKind::AssocConst =>
+                                if a.def == b.def && tcx.def_kind(a.def) == DefKind::AssocConst =>
                             {
                                 if let Ok(new_obligations) = infcx
                                     .at(&obligation.cause, obligation.param_env)
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 5e042ffc603..6ba05387173 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -2131,9 +2131,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
     let ty = tcx.type_of(assoc_ty.item.def_id);
     let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
     let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const {
-        let identity_substs =
-            crate::traits::InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
-        let did = ty::WithOptConstParam::unknown(assoc_ty.item.def_id);
+        let did = assoc_ty.item.def_id;
+        let identity_substs = crate::traits::InternalSubsts::identity_for_item(tcx, did);
         let kind = ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(did, identity_substs));
         ty.map_bound(|ty| tcx.mk_const(kind, ty).into())
     } else {
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 0fdba524e25..081e4d7cfa4 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -896,8 +896,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         use ty::ConstKind::Unevaluated;
                         match (c1.kind(), c2.kind()) {
                             (Unevaluated(a), Unevaluated(b))
-                                if a.def.did == b.def.did
-                                    && tcx.def_kind(a.def.did) == DefKind::AssocConst =>
+                                if a.def == b.def && tcx.def_kind(a.def) == DefKind::AssocConst =>
                             {
                                 if let Ok(InferOk { obligations, value: () }) = self
                                     .infcx
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 6808861d643..40e19abc0d0 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -478,7 +478,7 @@ impl<'tcx> WfPredicates<'tcx> {
                     match ct.kind() {
                         ty::ConstKind::Unevaluated(uv) => {
                             if !ct.has_escaping_bound_vars() {
-                                let obligations = self.nominal_obligations(uv.def.did, uv.substs);
+                                let obligations = self.nominal_obligations(uv.def, uv.substs);
                                 self.out.extend(obligations);
 
                                 let predicate =
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index b67607a4db6..b08a92570ed 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -132,7 +132,7 @@ fn recurse_build<'tcx>(
             tcx.mk_const(val, node.ty)
         }
         &ExprKind::NamedConst { def_id, substs, user_ty: _ } => {
-            let uneval = ty::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs);
+            let uneval = ty::UnevaluatedConst::new(def_id, substs);
             tcx.mk_const(uneval, node.ty)
         }
         ExprKind::ConstParam { param, .. } => tcx.mk_const(*param, node.ty),
@@ -256,6 +256,7 @@ fn recurse_build<'tcx>(
         ExprKind::VarRef { .. }
         | ExprKind::UpvarRef { .. }
         | ExprKind::StaticRef { .. }
+        | ExprKind::OffsetOf { .. }
         | ExprKind::ThreadLocalRef(_) => {
             error(GenericConstantTooComplexSub::OperationNotSupported(node.span))?
         }
@@ -347,6 +348,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
             | thir::ExprKind::ZstLiteral { .. }
             | thir::ExprKind::StaticRef { .. }
             | thir::ExprKind::InlineAsm(_)
+            | thir::ExprKind::OffsetOf { .. }
             | thir::ExprKind::ThreadLocalRef(_)
             | thir::ExprKind::Yield { .. } => false,
         }
@@ -391,52 +393,36 @@ impl<'a, 'tcx> visit::Visitor<'a, 'tcx> for IsThirPolymorphic<'a, 'tcx> {
 /// Builds an abstract const, do not use this directly, but use `AbstractConst::new` instead.
 pub fn thir_abstract_const(
     tcx: TyCtxt<'_>,
-    def: ty::WithOptConstParam<LocalDefId>,
+    def: LocalDefId,
 ) -> Result<Option<ty::Const<'_>>, ErrorGuaranteed> {
-    if tcx.features().generic_const_exprs {
-        match tcx.def_kind(def.did) {
-            // FIXME(generic_const_exprs): We currently only do this for anonymous constants,
-            // meaning that we do not look into associated constants. I(@lcnr) am not yet sure whether
-            // we want to look into them or treat them as opaque projections.
-            //
-            // Right now we do neither of that and simply always fail to unify them.
-            DefKind::AnonConst | DefKind::InlineConst => (),
-            _ => return Ok(None),
-        }
-
-        let body = tcx.thir_body(def)?;
-        let (body, body_id) = (&*body.0.borrow(), body.1);
+    if !tcx.features().generic_const_exprs {
+        return Ok(None);
+    }
 
-        let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body };
-        visit::walk_expr(&mut is_poly_vis, &body[body_id]);
-        if !is_poly_vis.is_poly {
-            return Ok(None);
-        }
+    match tcx.def_kind(def) {
+        // FIXME(generic_const_exprs): We currently only do this for anonymous constants,
+        // meaning that we do not look into associated constants. I(@lcnr) am not yet sure whether
+        // we want to look into them or treat them as opaque projections.
+        //
+        // Right now we do neither of that and simply always fail to unify them.
+        DefKind::AnonConst | DefKind::InlineConst => (),
+        _ => return Ok(None),
+    }
 
-        let root_span = body.exprs[body_id].span;
+    let body = tcx.thir_body(def)?;
+    let (body, body_id) = (&*body.0.borrow(), body.1);
 
-        Some(recurse_build(tcx, body, body_id, root_span)).transpose()
-    } else {
-        Ok(None)
+    let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body };
+    visit::walk_expr(&mut is_poly_vis, &body[body_id]);
+    if !is_poly_vis.is_poly {
+        return Ok(None);
     }
+
+    let root_span = body.exprs[body_id].span;
+
+    Some(recurse_build(tcx, body, body_id, root_span)).transpose()
 }
 
 pub fn provide(providers: &mut ty::query::Providers) {
-    *providers = ty::query::Providers {
-        destructure_const,
-        thir_abstract_const: |tcx, def_id| {
-            if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
-                tcx.thir_abstract_const_of_const_arg(def)
-            } else {
-                thir_abstract_const(tcx, ty::WithOptConstParam::unknown(def_id))
-            }
-        },
-        thir_abstract_const_of_const_arg: |tcx, (did, param_did)| {
-            thir_abstract_const(
-                tcx,
-                ty::WithOptConstParam { did, const_param_did: Some(param_did) },
-            )
-        },
-        ..*providers
-    };
+    *providers = ty::query::Providers { destructure_const, thir_abstract_const, ..*providers };
 }
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 47cd7af221d..21cc3c9517e 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -1,5 +1,5 @@
 use rustc_errors::ErrorGuaranteed;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::DefId;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::traits::CodegenObligationError;
 use rustc_middle::ty::subst::SubstsRef;
@@ -14,54 +14,26 @@ fn resolve_instance<'tcx>(
     tcx: TyCtxt<'tcx>,
     key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>,
 ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
-    let (param_env, (did, substs)) = key.into_parts();
-    if let Some(did) = did.as_local() {
-        if let Some(param_did) = tcx.opt_const_param_of(did) {
-            return tcx.resolve_instance_of_const_arg(param_env.and((did, param_did, substs)));
-        }
-    }
-
-    inner_resolve_instance(tcx, param_env.and((ty::WithOptConstParam::unknown(did), substs)))
-}
-
-fn resolve_instance_of_const_arg<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)>,
-) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
-    let (param_env, (did, const_param_did, substs)) = key.into_parts();
-    inner_resolve_instance(
-        tcx,
-        param_env.and((
-            ty::WithOptConstParam { did: did.to_def_id(), const_param_did: Some(const_param_did) },
-            substs,
-        )),
-    )
-}
-
-fn inner_resolve_instance<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    key: ty::ParamEnvAnd<'tcx, (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>)>,
-) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
     let (param_env, (def, substs)) = key.into_parts();
 
-    let result = if let Some(trait_def_id) = tcx.trait_of_item(def.did) {
+    let result = if let Some(trait_def_id) = tcx.trait_of_item(def) {
         debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
         resolve_associated_item(
             tcx,
-            def.did,
+            def,
             param_env,
             trait_def_id,
             tcx.normalize_erasing_regions(param_env, substs),
         )
     } else {
-        let ty = tcx.type_of(def.def_id_for_type_of());
+        let ty = tcx.type_of(def);
         let item_type =
             tcx.subst_and_normalize_erasing_regions(substs, param_env, ty.skip_binder());
 
         let def = match *item_type.kind() {
             ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => {
                 debug!(" => intrinsic");
-                ty::InstanceDef::Intrinsic(def.did)
+                ty::InstanceDef::Intrinsic(def)
             }
             ty::FnDef(def_id, substs) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => {
                 let ty = substs.type_at(0);
@@ -206,15 +178,11 @@ fn resolve_associated_item<'tcx>(
             Some(ty::Instance::new(leaf_def.item.def_id, substs))
         }
         traits::ImplSource::Generator(generator_data) => Some(Instance {
-            def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown(
-                generator_data.generator_def_id,
-            )),
+            def: ty::InstanceDef::Item(generator_data.generator_def_id),
             substs: generator_data.substs,
         }),
         traits::ImplSource::Future(future_data) => Some(Instance {
-            def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown(
-                future_data.generator_def_id,
-            )),
+            def: ty::InstanceDef::Item(future_data.generator_def_id),
             substs: future_data.substs,
         }),
         traits::ImplSource::Closure(closure_data) => {
@@ -298,6 +266,5 @@ fn resolve_associated_item<'tcx>(
 }
 
 pub fn provide(providers: &mut ty::query::Providers) {
-    *providers =
-        ty::query::Providers { resolve_instance, resolve_instance_of_const_arg, ..*providers };
+    *providers = ty::query::Providers { resolve_instance, ..*providers };
 }
diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs
index 62e699eefd7..4c1f2dd0e53 100644
--- a/compiler/rustc_type_ir/src/sty.rs
+++ b/compiler/rustc_type_ir/src/sty.rs
@@ -203,6 +203,10 @@ pub enum TyKind<I: Interner> {
     /// `for<'a, T> &'a (): Trait<T>` and then convert the introduced bound variables
     /// back to inference variables in a new inference context when inside of the query.
     ///
+    /// It is conventional to render anonymous bound types like `^N` or `^D_N`,
+    /// where `N` is the bound variable's anonymous index into the binder, and
+    /// `D` is the debruijn index, or totally omitted if the debruijn index is zero.
+    ///
     /// See the `rustc-dev-guide` for more details about
     /// [higher-ranked trait bounds][1] and [canonical queries][2].
     ///
@@ -212,6 +216,12 @@ pub enum TyKind<I: Interner> {
 
     /// A placeholder type, used during higher ranked subtyping to instantiate
     /// bound variables.
+    ///
+    /// It is conventional to render anonymous placeholer types like `!N` or `!U_N`,
+    /// where `N` is the placeholder variable's anonymous index (which corresponds
+    /// to the bound variable's index from the binder from which it was instantiated),
+    /// and `U` is the universe index in which it is instantiated, or totally omitted
+    /// if the universe index is zero.
     Placeholder(I::PlaceholderType),
 
     /// A type variable used during type checking.
diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs
index ad48315fd70..f83c8f83cc9 100644
--- a/library/alloc/src/boxed/thin.rs
+++ b/library/alloc/src/boxed/thin.rs
@@ -7,7 +7,7 @@ use core::fmt::{self, Debug, Display, Formatter};
 use core::marker::PhantomData;
 #[cfg(not(no_global_oom_handling))]
 use core::marker::Unsize;
-use core::mem;
+use core::mem::{self, SizedTypeProperties};
 use core::ops::{Deref, DerefMut};
 use core::ptr::Pointee;
 use core::ptr::{self, NonNull};
@@ -202,9 +202,7 @@ impl<H> WithHeader<H> {
             let ptr = if layout.size() == 0 {
                 // Some paranoia checking, mostly so that the ThinBox tests are
                 // more able to catch issues.
-                debug_assert!(
-                    value_offset == 0 && mem::size_of::<T>() == 0 && mem::size_of::<H>() == 0
-                );
+                debug_assert!(value_offset == 0 && T::IS_ZST && H::IS_ZST);
                 layout.dangling()
             } else {
                 let ptr = alloc::alloc(layout);
@@ -249,9 +247,7 @@ impl<H> WithHeader<H> {
                         alloc::dealloc(self.ptr.as_ptr().sub(value_offset), layout);
                     } else {
                         debug_assert!(
-                            value_offset == 0
-                                && mem::size_of::<H>() == 0
-                                && self.value_layout.size() == 0
+                            value_offset == 0 && H::IS_ZST && self.value_layout.size() == 0
                         );
                     }
                 }
diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs
index 1da86e1a46a..e03b501ae4d 100644
--- a/library/alloc/src/fmt.rs
+++ b/library/alloc/src/fmt.rs
@@ -551,8 +551,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-#[unstable(feature = "fmt_internals", issue = "none")]
-pub use core::fmt::rt;
 #[stable(feature = "fmt_flags_align", since = "1.28.0")]
 pub use core::fmt::Alignment;
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs
index 2b1a787cc54..3091efabd68 100644
--- a/library/alloc/src/vec/drain.rs
+++ b/library/alloc/src/vec/drain.rs
@@ -112,9 +112,7 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> {
             let unyielded_ptr = this.iter.as_slice().as_ptr();
 
             // ZSTs have no identity, so we don't need to move them around.
-            let needs_move = mem::size_of::<T>() != 0;
-
-            if needs_move {
+            if !T::IS_ZST {
                 let start_ptr = source_vec.as_mut_ptr().add(start);
 
                 // memmove back unyielded elements
@@ -197,7 +195,7 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> {
             }
         }
 
-        let iter = mem::replace(&mut self.iter, (&mut []).iter());
+        let iter = mem::take(&mut self.iter);
         let drop_len = iter.len();
 
         let mut vec = self.vec;
diff --git a/library/alloc/src/vec/drain_filter.rs b/library/alloc/src/vec/drain_filter.rs
index 8c03f1692d9..650f9213890 100644
--- a/library/alloc/src/vec/drain_filter.rs
+++ b/library/alloc/src/vec/drain_filter.rs
@@ -1,5 +1,5 @@
 use crate::alloc::{Allocator, Global};
-use core::mem::{self, ManuallyDrop};
+use core::mem::{ManuallyDrop, SizedTypeProperties};
 use core::ptr;
 use core::slice;
 
@@ -96,9 +96,7 @@ where
 
         unsafe {
             // ZSTs have no identity, so we don't need to move them around.
-            let needs_move = mem::size_of::<T>() != 0;
-
-            if needs_move && this.idx < this.old_len && this.del > 0 {
+            if !T::IS_ZST && this.idx < this.old_len && this.del > 0 {
                 let ptr = this.vec.as_mut_ptr();
                 let src = ptr.add(this.idx);
                 let dst = src.sub(this.del);
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 90825c4ce32..87ec35c040f 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -321,14 +321,11 @@ pub struct AssertParamIsEq<T: Eq + ?Sized> {
 /// ```
 /// use std::cmp::Ordering;
 ///
-/// let result = 1.cmp(&2);
-/// assert_eq!(Ordering::Less, result);
+/// assert_eq!(1.cmp(&2), Ordering::Less);
 ///
-/// let result = 1.cmp(&1);
-/// assert_eq!(Ordering::Equal, result);
+/// assert_eq!(1.cmp(&1), Ordering::Equal);
 ///
-/// let result = 2.cmp(&1);
-/// assert_eq!(Ordering::Greater, result);
+/// assert_eq!(2.cmp(&1), Ordering::Greater);
 /// ```
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -784,8 +781,8 @@ pub trait Ord: Eq + PartialOrd<Self> {
     /// # Examples
     ///
     /// ```
-    /// assert_eq!(2, 1.max(2));
-    /// assert_eq!(2, 2.max(2));
+    /// assert_eq!(1.max(2), 2);
+    /// assert_eq!(2.max(2), 2);
     /// ```
     #[stable(feature = "ord_max_min", since = "1.21.0")]
     #[inline]
@@ -804,8 +801,8 @@ pub trait Ord: Eq + PartialOrd<Self> {
     /// # Examples
     ///
     /// ```
-    /// assert_eq!(1, 1.min(2));
-    /// assert_eq!(2, 2.min(2));
+    /// assert_eq!(1.min(2), 1);
+    /// assert_eq!(2.min(2), 2);
     /// ```
     #[stable(feature = "ord_max_min", since = "1.21.0")]
     #[inline]
@@ -829,9 +826,9 @@ pub trait Ord: Eq + PartialOrd<Self> {
     /// # Examples
     ///
     /// ```
-    /// assert!((-3).clamp(-2, 1) == -2);
-    /// assert!(0.clamp(-2, 1) == 0);
-    /// assert!(2.clamp(-2, 1) == 1);
+    /// assert_eq!((-3).clamp(-2, 1), -2);
+    /// assert_eq!(0.clamp(-2, 1), 0);
+    /// assert_eq!(2.clamp(-2, 1), 1);
     /// ```
     #[must_use]
     #[stable(feature = "clamp", since = "1.50.0")]
@@ -1060,11 +1057,9 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     /// # Examples
     ///
     /// ```
-    /// let result = 1.0 < 2.0;
-    /// assert_eq!(result, true);
-    ///
-    /// let result = 2.0 < 1.0;
-    /// assert_eq!(result, false);
+    /// assert_eq!(1.0 < 1.0, false);
+    /// assert_eq!(1.0 < 2.0, true);
+    /// assert_eq!(2.0 < 1.0, false);
     /// ```
     #[inline]
     #[must_use]
@@ -1079,11 +1074,9 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     /// # Examples
     ///
     /// ```
-    /// let result = 1.0 <= 2.0;
-    /// assert_eq!(result, true);
-    ///
-    /// let result = 2.0 <= 2.0;
-    /// assert_eq!(result, true);
+    /// assert_eq!(1.0 <= 1.0, true);
+    /// assert_eq!(1.0 <= 2.0, true);
+    /// assert_eq!(2.0 <= 1.0, false);
     /// ```
     #[inline]
     #[must_use]
@@ -1097,11 +1090,9 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     /// # Examples
     ///
     /// ```
-    /// let result = 1.0 > 2.0;
-    /// assert_eq!(result, false);
-    ///
-    /// let result = 2.0 > 2.0;
-    /// assert_eq!(result, false);
+    /// assert_eq!(1.0 > 1.0, false);
+    /// assert_eq!(1.0 > 2.0, false);
+    /// assert_eq!(2.0 > 1.0, true);
     /// ```
     #[inline]
     #[must_use]
@@ -1116,11 +1107,9 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     /// # Examples
     ///
     /// ```
-    /// let result = 2.0 >= 1.0;
-    /// assert_eq!(result, true);
-    ///
-    /// let result = 2.0 >= 2.0;
-    /// assert_eq!(result, true);
+    /// assert_eq!(1.0 >= 1.0, true);
+    /// assert_eq!(1.0 >= 2.0, false);
+    /// assert_eq!(2.0 >= 1.0, true);
     /// ```
     #[inline]
     #[must_use]
@@ -1150,8 +1139,8 @@ pub macro PartialOrd($item:item) {
 /// ```
 /// use std::cmp;
 ///
-/// assert_eq!(1, cmp::min(1, 2));
-/// assert_eq!(2, cmp::min(2, 2));
+/// assert_eq!(cmp::min(1, 2), 1);
+/// assert_eq!(cmp::min(2, 2), 2);
 /// ```
 #[inline]
 #[must_use]
@@ -1170,8 +1159,11 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// assert_eq!(cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 1);
-/// assert_eq!(cmp::min_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
+/// let result = cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
+/// assert_eq!(result, 1);
+///
+/// let result = cmp::min_by(-2, 3, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
+/// assert_eq!(result, -2);
 /// ```
 #[inline]
 #[must_use]
@@ -1192,8 +1184,11 @@ pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// assert_eq!(cmp::min_by_key(-2, 1, |x: &i32| x.abs()), 1);
-/// assert_eq!(cmp::min_by_key(-2, 2, |x: &i32| x.abs()), -2);
+/// let result = cmp::min_by_key(-2, 1, |x: &i32| x.abs());
+/// assert_eq!(result, 1);
+///
+/// let result = cmp::min_by_key(-2, 2, |x: &i32| x.abs());
+/// assert_eq!(result, -2);
 /// ```
 #[inline]
 #[must_use]
@@ -1213,8 +1208,8 @@ pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// assert_eq!(2, cmp::max(1, 2));
-/// assert_eq!(2, cmp::max(2, 2));
+/// assert_eq!(cmp::max(1, 2), 2);
+/// assert_eq!(cmp::max(2, 2), 2);
 /// ```
 #[inline]
 #[must_use]
@@ -1233,8 +1228,11 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// assert_eq!(cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
-/// assert_eq!(cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 2);
+/// let result = cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
+/// assert_eq!(result, -2);
+///
+/// let result = cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())) ;
+/// assert_eq!(result, 2);
 /// ```
 #[inline]
 #[must_use]
@@ -1255,8 +1253,11 @@ pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
 /// ```
 /// use std::cmp;
 ///
-/// assert_eq!(cmp::max_by_key(-2, 1, |x: &i32| x.abs()), -2);
-/// assert_eq!(cmp::max_by_key(-2, 2, |x: &i32| x.abs()), 2);
+/// let result = cmp::max_by_key(-2, 1, |x: &i32| x.abs());
+/// assert_eq!(result, -2);
+///
+/// let result = cmp::max_by_key(-2, 2, |x: &i32| x.abs());
+/// assert_eq!(result, 2);
 /// ```
 #[inline]
 #[must_use]
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index fcda097f01f..a901ae72669 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -18,6 +18,7 @@ mod float;
 #[cfg(no_fp_fmt_parse)]
 mod nofloat;
 mod num;
+mod rt;
 
 #[stable(feature = "fmt_flags_align", since = "1.28.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "Alignment")]
@@ -38,12 +39,6 @@ pub enum Alignment {
 #[stable(feature = "debug_builders", since = "1.2.0")]
 pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
 
-#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
-#[doc(hidden)]
-pub mod rt {
-    pub mod v1;
-}
-
 /// The type returned by formatter methods.
 ///
 /// # Examples
@@ -227,7 +222,7 @@ impl<W: Write + ?Sized> Write for &mut W {
 pub struct Formatter<'a> {
     flags: u32,
     fill: char,
-    align: rt::v1::Alignment,
+    align: rt::Alignment,
     width: Option<usize>,
     precision: Option<usize>,
 
@@ -248,7 +243,7 @@ impl<'a> Formatter<'a> {
         Formatter {
             flags: 0,
             fill: ' ',
-            align: rt::v1::Alignment::Unknown,
+            align: rt::Alignment::Unknown,
             width: None,
             precision: None,
             buf,
@@ -433,17 +428,15 @@ impl<'a> Arguments<'a> {
     /// An `UnsafeArg` is required because the following invariants must be held
     /// in order for this function to be safe:
     /// 1. The `pieces` slice must be at least as long as `fmt`.
-    /// 2. Every [`rt::v1::Argument::position`] value within `fmt` must be a
-    ///    valid index of `args`.
-    /// 3. Every [`rt::v1::Count::Param`] within `fmt` must contain a valid index of
-    ///    `args`.
+    /// 2. Every `rt::Placeholder::position` value within `fmt` must be a valid index of `args`.
+    /// 3. Every `rt::Count::Param` within `fmt` must contain a valid index of `args`.
     #[doc(hidden)]
     #[inline]
     #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
     pub fn new_v1_formatted(
         pieces: &'a [&'static str],
         args: &'a [ArgumentV1<'a>],
-        fmt: &'a [rt::v1::Argument],
+        fmt: &'a [rt::Placeholder],
         _unsafe_arg: UnsafeArg,
     ) -> Arguments<'a> {
         Arguments { pieces, fmt: Some(fmt), args }
@@ -505,7 +498,7 @@ pub struct Arguments<'a> {
     pieces: &'a [&'static str],
 
     // Placeholder specs, or `None` if all specs are default (as in "{}{}").
-    fmt: Option<&'a [rt::v1::Argument]>,
+    fmt: Option<&'a [rt::Placeholder]>,
 
     // Dynamic arguments for interpolation, to be interleaved with string
     // pieces. (Every argument is preceded by a string piece.)
@@ -1281,15 +1274,15 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
     Ok(())
 }
 
-unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument, args: &[ArgumentV1<'_>]) -> Result {
-    fmt.fill = arg.format.fill;
-    fmt.align = arg.format.align;
-    fmt.flags = arg.format.flags;
+unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[ArgumentV1<'_>]) -> Result {
+    fmt.fill = arg.fill;
+    fmt.align = arg.align;
+    fmt.flags = arg.flags;
     // SAFETY: arg and args come from the same Arguments,
     // which guarantees the indexes are always within bounds.
     unsafe {
-        fmt.width = getcount(args, &arg.format.width);
-        fmt.precision = getcount(args, &arg.format.precision);
+        fmt.width = getcount(args, &arg.width);
+        fmt.precision = getcount(args, &arg.precision);
     }
 
     // Extract the correct argument
@@ -1302,11 +1295,11 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument, args: &[ArgumentV
     (value.formatter)(value.value, fmt)
 }
 
-unsafe fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::v1::Count) -> Option<usize> {
+unsafe fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::Count) -> Option<usize> {
     match *cnt {
-        rt::v1::Count::Is(n) => Some(n),
-        rt::v1::Count::Implied => None,
-        rt::v1::Count::Param(i) => {
+        rt::Count::Is(n) => Some(n),
+        rt::Count::Implied => None,
+        rt::Count::Param(i) => {
             debug_assert!(i < args.len());
             // SAFETY: cnt and args come from the same Arguments,
             // which guarantees this index is always within bounds.
@@ -1449,9 +1442,9 @@ impl<'a> Formatter<'a> {
             // is zero
             Some(min) if self.sign_aware_zero_pad() => {
                 let old_fill = crate::mem::replace(&mut self.fill, '0');
-                let old_align = crate::mem::replace(&mut self.align, rt::v1::Alignment::Right);
+                let old_align = crate::mem::replace(&mut self.align, rt::Alignment::Right);
                 write_prefix(self, sign, prefix)?;
-                let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?;
+                let post_padding = self.padding(min - width, Alignment::Right)?;
                 self.buf.write_str(buf)?;
                 post_padding.write(self)?;
                 self.fill = old_fill;
@@ -1460,7 +1453,7 @@ impl<'a> Formatter<'a> {
             }
             // Otherwise, the sign and prefix goes after the padding
             Some(min) => {
-                let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?;
+                let post_padding = self.padding(min - width, Alignment::Right)?;
                 write_prefix(self, sign, prefix)?;
                 self.buf.write_str(buf)?;
                 post_padding.write(self)
@@ -1535,7 +1528,7 @@ impl<'a> Formatter<'a> {
                 // If we're under both the maximum and the minimum width, then fill
                 // up the minimum width with the specified string + some alignment.
                 else {
-                    let align = rt::v1::Alignment::Left;
+                    let align = Alignment::Left;
                     let post_padding = self.padding(width - chars_count, align)?;
                     self.buf.write_str(s)?;
                     post_padding.write(self)
@@ -1550,17 +1543,19 @@ impl<'a> Formatter<'a> {
     pub(crate) fn padding(
         &mut self,
         padding: usize,
-        default: rt::v1::Alignment,
+        default: Alignment,
     ) -> result::Result<PostPadding, Error> {
         let align = match self.align {
-            rt::v1::Alignment::Unknown => default,
-            _ => self.align,
+            rt::Alignment::Unknown => default,
+            rt::Alignment::Left => Alignment::Left,
+            rt::Alignment::Right => Alignment::Right,
+            rt::Alignment::Center => Alignment::Center,
         };
 
         let (pre_pad, post_pad) = match align {
-            rt::v1::Alignment::Left => (0, padding),
-            rt::v1::Alignment::Right | rt::v1::Alignment::Unknown => (padding, 0),
-            rt::v1::Alignment::Center => (padding / 2, (padding + 1) / 2),
+            Alignment::Left => (0, padding),
+            Alignment::Right => (padding, 0),
+            Alignment::Center => (padding / 2, (padding + 1) / 2),
         };
 
         for _ in 0..pre_pad {
@@ -1580,7 +1575,6 @@ impl<'a> Formatter<'a> {
             let mut formatted = formatted.clone();
             let old_fill = self.fill;
             let old_align = self.align;
-            let mut align = old_align;
             if self.sign_aware_zero_pad() {
                 // a sign always goes first
                 let sign = formatted.sign;
@@ -1589,9 +1583,8 @@ impl<'a> Formatter<'a> {
                 // remove the sign from the formatted parts
                 formatted.sign = "";
                 width = width.saturating_sub(sign.len());
-                align = rt::v1::Alignment::Right;
                 self.fill = '0';
-                self.align = rt::v1::Alignment::Right;
+                self.align = rt::Alignment::Right;
             }
 
             // remaining parts go through the ordinary padding process.
@@ -1600,7 +1593,7 @@ impl<'a> Formatter<'a> {
                 // no padding
                 self.write_formatted_parts(&formatted)
             } else {
-                let post_padding = self.padding(width - len, align)?;
+                let post_padding = self.padding(width - len, Alignment::Right)?;
                 self.write_formatted_parts(&formatted)?;
                 post_padding.write(self)
             };
@@ -1788,10 +1781,10 @@ impl<'a> Formatter<'a> {
     #[stable(feature = "fmt_flags_align", since = "1.28.0")]
     pub fn align(&self) -> Option<Alignment> {
         match self.align {
-            rt::v1::Alignment::Left => Some(Alignment::Left),
-            rt::v1::Alignment::Right => Some(Alignment::Right),
-            rt::v1::Alignment::Center => Some(Alignment::Center),
-            rt::v1::Alignment::Unknown => None,
+            rt::Alignment::Left => Some(Alignment::Left),
+            rt::Alignment::Right => Some(Alignment::Right),
+            rt::Alignment::Center => Some(Alignment::Center),
+            rt::Alignment::Unknown => None,
         }
     }
 
diff --git a/library/core/src/fmt/rt/v1.rs b/library/core/src/fmt/rt.rs
index 6d70796f707..2c1a767691b 100644
--- a/library/core/src/fmt/rt/v1.rs
+++ b/library/core/src/fmt/rt.rs
@@ -1,20 +1,12 @@
-//! This is an internal module used by the ifmt! runtime. These structures are
-//! emitted to static arrays to precompile format strings ahead of time.
-//!
-//! These definitions are similar to their `ct` equivalents, but differ in that
-//! these can be statically allocated and are slightly optimized for the runtime
 #![allow(missing_debug_implementations)]
+#![unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
+
+//! These are the lang items used by format_args!().
 
 #[lang = "format_placeholder"]
 #[derive(Copy, Clone)]
-// FIXME: Rename this to Placeholder
-pub struct Argument {
+pub struct Placeholder {
     pub position: usize,
-    pub format: FormatSpec,
-}
-
-#[derive(Copy, Clone)]
-pub struct FormatSpec {
     pub fill: char,
     pub align: Alignment,
     pub flags: u32,
@@ -22,7 +14,7 @@ pub struct FormatSpec {
     pub width: Count,
 }
 
-impl Argument {
+impl Placeholder {
     #[inline(always)]
     pub const fn new(
         position: usize,
@@ -32,7 +24,7 @@ impl Argument {
         precision: Count,
         width: Count,
     ) -> Self {
-        Self { position, format: FormatSpec { fill, align, flags, precision, width } }
+        Self { position, fill, align, flags, precision, width }
     }
 }
 
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 30ec73cabf8..7d2f2971523 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -1279,3 +1279,45 @@ pub trait SizedTypeProperties: Sized {
 #[doc(hidden)]
 #[unstable(feature = "sized_type_properties", issue = "none")]
 impl<T> SizedTypeProperties for T {}
+
+/// Expands to the offset in bytes of a field from the beginning of the given type.
+///
+/// Only structs, unions and tuples are supported.
+///
+/// Nested field accesses may be used, but not array indexes like in `C`'s `offsetof`.
+///
+/// Note that the output of this macro is not stable, except for `#[repr(C)]` types.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(offset_of)]
+///
+/// use std::mem;
+/// #[repr(C)]
+/// struct FieldStruct {
+///     first: u8,
+///     second: u16,
+///     third: u8
+/// }
+///
+/// assert_eq!(mem::offset_of!(FieldStruct, first), 0);
+/// assert_eq!(mem::offset_of!(FieldStruct, second), 2);
+/// assert_eq!(mem::offset_of!(FieldStruct, third), 4);
+///
+/// #[repr(C)]
+/// struct NestedA {
+///     b: NestedB
+/// }
+///
+/// #[repr(C)]
+/// struct NestedB(u8);
+///
+/// assert_eq!(mem::offset_of!(NestedA, b.0), 0);
+/// ```
+#[unstable(feature = "offset_of", issue = "106655")]
+#[rustc_builtin_macro]
+#[cfg(not(bootstrap))]
+pub macro offset_of($Container:ty, $($fields:tt).+ $(,)?) {
+    /* compiler built-in */
+}
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 54e03067d1c..fc9b07d29e2 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -1,7 +1,7 @@
 //! Definitions of integer that is known not to equal zero.
 
 use crate::fmt;
-use crate::ops::{BitOr, BitOrAssign, Div, Rem};
+use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem};
 use crate::str::FromStr;
 
 use super::from_str_radix;
@@ -664,8 +664,7 @@ macro_rules! nonzero_signed_operations {
                 /// assert_eq!(pos, pos.wrapping_abs());
                 /// assert_eq!(pos, neg.wrapping_abs());
                 /// assert_eq!(min, min.wrapping_abs());
-                /// # // FIXME: add once Neg is implemented?
-                /// # // assert_eq!(max, (-max).wrapping_abs());
+                /// assert_eq!(max, (-max).wrapping_abs());
                 /// # Some(())
                 /// # }
                 /// ```
@@ -868,6 +867,20 @@ macro_rules! nonzero_signed_operations {
                     unsafe { $Ty::new_unchecked(result) }
                 }
             }
+
+            #[stable(feature = "signed_nonzero_neg", since = "CURRENT_RUSTC_VERSION")]
+            impl Neg for $Ty {
+                type Output = $Ty;
+
+                #[inline]
+                fn neg(self) -> $Ty {
+                    // SAFETY: negation of nonzero cannot yield zero values.
+                    unsafe { $Ty::new_unchecked(self.get().neg()) }
+                }
+            }
+
+            forward_ref_unop! { impl Neg, neg for $Ty,
+                #[stable(feature = "signed_nonzero_neg", since = "CURRENT_RUSTC_VERSION")] }
         )+
     }
 }
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 88b84bd1352..b2dd92a2379 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -685,7 +685,7 @@ where
             None
         } else {
             self.finished = true;
-            Some(mem::replace(&mut self.v, &mut []))
+            Some(mem::take(&mut self.v))
         }
     }
 }
@@ -749,7 +749,7 @@ where
         match idx_opt {
             None => self.finish(),
             Some(idx) => {
-                let tmp = mem::replace(&mut self.v, &mut []);
+                let tmp = mem::take(&mut self.v);
                 let (head, tail) = tmp.split_at_mut(idx);
                 self.v = head;
                 Some(&mut tail[1..])
@@ -830,7 +830,7 @@ where
         if idx == self.v.len() {
             self.finished = true;
         }
-        let tmp = mem::replace(&mut self.v, &mut []);
+        let tmp = mem::take(&mut self.v);
         let (head, tail) = tmp.split_at_mut(idx);
         self.v = tail;
         Some(head)
@@ -876,7 +876,7 @@ where
         if idx == 0 {
             self.finished = true;
         }
-        let tmp = mem::replace(&mut self.v, &mut []);
+        let tmp = mem::take(&mut self.v);
         let (head, tail) = tmp.split_at_mut(idx);
         self.v = head;
         Some(tail)
diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs
index b73e35f1e91..b1ca872b845 100644
--- a/library/core/src/slice/iter/macros.rs
+++ b/library/core/src/slice/iter/macros.rs
@@ -73,7 +73,7 @@ macro_rules! iterator {
             // Unsafe because the offset must not exceed `self.len()`.
             #[inline(always)]
             unsafe fn post_inc_start(&mut self, offset: usize) -> * $raw_mut T {
-                if mem::size_of::<T>() == 0 {
+                if T::IS_ZST {
                     zst_shrink!(self, offset);
                     self.ptr.as_ptr()
                 } else {
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index b74fe013665..b08d5782ab6 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -1172,7 +1172,7 @@ impl fmt::Debug for Duration {
                         emit_without_padding(f)
                     } else {
                         // We need to add padding. Use the `Formatter::padding` helper function.
-                        let default_align = crate::fmt::rt::v1::Alignment::Left;
+                        let default_align = fmt::Alignment::Left;
                         let post_padding = f.padding(requested_w - actual_w, default_align)?;
                         emit_without_padding(f)?;
                         post_padding.write(f)
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index f460da35dd3..84859a54c26 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -109,6 +109,7 @@
 #![feature(utf8_chunks)]
 #![feature(is_ascii_octdigit)]
 #![feature(get_many_mut)]
+#![cfg_attr(not(bootstrap), feature(offset_of))]
 #![deny(unsafe_op_in_unsafe_fn)]
 #![deny(fuzzy_provenance_casts)]
 
diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs
index f7740a114e7..7f033816901 100644
--- a/library/core/tests/mem.rs
+++ b/library/core/tests/mem.rs
@@ -364,3 +364,193 @@ fn const_maybe_uninit() {
 
     assert_eq!(FIELD_BY_FIELD, Foo { x: 1, y: 2 });
 }
+
+#[test]
+#[cfg(not(bootstrap))]
+fn offset_of() {
+    #[repr(C)]
+    struct Foo {
+        x: u8,
+        y: u16,
+        z: Bar,
+    }
+
+    #[repr(C)]
+    struct Bar(u8, u8);
+
+    assert_eq!(offset_of!(Foo, x), 0);
+    assert_eq!(offset_of!(Foo, y), 2);
+    assert_eq!(offset_of!(Foo, z.0), 4);
+    assert_eq!(offset_of!(Foo, z.1), 5);
+
+    // Layout of tuples is unstable
+    assert!(offset_of!((u8, u16), 0) <= size_of::<(u8, u16)>() - 1);
+    assert!(offset_of!((u8, u16), 1) <= size_of::<(u8, u16)>() - 2);
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn offset_of_union() {
+    #[repr(C)]
+    union Foo {
+        x: u8,
+        y: u16,
+        z: Bar,
+    }
+
+    #[repr(C)]
+    #[derive(Copy, Clone)]
+    struct Bar(u8, u8);
+
+    assert_eq!(offset_of!(Foo, x), 0);
+    assert_eq!(offset_of!(Foo, y), 0);
+    assert_eq!(offset_of!(Foo, z.0), 0);
+    assert_eq!(offset_of!(Foo, z.1), 1);
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn offset_of_dst() {
+    #[repr(C)]
+    struct Alpha {
+        x: u8,
+        y: u16,
+        z: [u8],
+    }
+
+    trait Trait {}
+
+    #[repr(C)]
+    struct Beta {
+        x: u8,
+        y: u16,
+        z: dyn Trait,
+    }
+
+    extern "C" {
+        type Extern;
+    }
+
+    #[repr(C)]
+    struct Gamma {
+        x: u8,
+        y: u16,
+        z: Extern,
+    }
+
+    assert_eq!(offset_of!(Alpha, x), 0);
+    assert_eq!(offset_of!(Alpha, y), 2);
+
+    assert_eq!(offset_of!(Beta, x), 0);
+    assert_eq!(offset_of!(Beta, y), 2);
+
+    assert_eq!(offset_of!(Gamma, x), 0);
+    assert_eq!(offset_of!(Gamma, y), 2);
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn offset_of_packed() {
+    #[repr(C, packed)]
+    struct Foo {
+        x: u8,
+        y: u16,
+    }
+
+    assert_eq!(offset_of!(Foo, x), 0);
+    assert_eq!(offset_of!(Foo, y), 1);
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn offset_of_projection() {
+    #[repr(C)]
+    struct Foo {
+        x: u8,
+        y: u16,
+    }
+
+    trait Projector {
+        type Type;
+    }
+
+    impl Projector for () {
+        type Type = Foo;
+    }
+
+    assert_eq!(offset_of!(<() as Projector>::Type, x), 0);
+    assert_eq!(offset_of!(<() as Projector>::Type, y), 2);
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn offset_of_alias() {
+    #[repr(C)]
+    struct Foo {
+        x: u8,
+        y: u16,
+    }
+
+    type Bar = Foo;
+
+    assert_eq!(offset_of!(Bar, x), 0);
+    assert_eq!(offset_of!(Bar, y), 2);
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn const_offset_of() {
+    #[repr(C)]
+    struct Foo {
+        x: u8,
+        y: u16,
+    }
+
+    const X_OFFSET: usize = offset_of!(Foo, x);
+    const Y_OFFSET: usize = offset_of!(Foo, y);
+
+    assert_eq!(X_OFFSET, 0);
+    assert_eq!(Y_OFFSET, 2);
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn offset_of_without_const_promotion() {
+    #[repr(C)]
+    struct Foo<SuppressConstPromotion> {
+        x: u8,
+        y: u16,
+        _scp: SuppressConstPromotion,
+    }
+
+    // Normally, offset_of is always const promoted.
+    // The generic parameter prevents this from happening.
+    // This is needed to test the codegen impl of offset_of
+    fn inner<SuppressConstPromotion>() {
+        assert_eq!(offset_of!(Foo<SuppressConstPromotion>, x), 0);
+        assert_eq!(offset_of!(Foo<SuppressConstPromotion>, y), 2);
+    }
+
+    inner::<()>();
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn offset_of_addr() {
+    #[repr(C)]
+    struct Foo {
+        x: u8,
+        y: u16,
+        z: Bar,
+    }
+
+    #[repr(C)]
+    struct Bar(u8, u8);
+
+    let base = Foo { x: 0, y: 0, z: Bar(0, 0) };
+
+    assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, x), ptr::addr_of!(base.x).addr());
+    assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, y), ptr::addr_of!(base.y).addr());
+    assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, z.0), ptr::addr_of!(base.z.0).addr());
+    assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, z.1), ptr::addr_of!(base.z.1).addr());
+}
diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs
index 96356b728e9..007f8442533 100644
--- a/library/core/tests/nonzero.rs
+++ b/library/core/tests/nonzero.rs
@@ -336,3 +336,21 @@ fn test_nonzero_uint_rem() {
     let x: u32 = 42u32 % nz;
     assert_eq!(x, 2u32);
 }
+
+#[test]
+fn test_signed_nonzero_neg() {
+    assert_eq!((-NonZeroI8::new(1).unwrap()).get(), -1);
+    assert_eq!((-NonZeroI8::new(-1).unwrap()).get(), 1);
+
+    assert_eq!((-NonZeroI16::new(1).unwrap()).get(), -1);
+    assert_eq!((-NonZeroI16::new(-1).unwrap()).get(), 1);
+
+    assert_eq!((-NonZeroI32::new(1).unwrap()).get(), -1);
+    assert_eq!((-NonZeroI32::new(-1).unwrap()).get(), 1);
+
+    assert_eq!((-NonZeroI64::new(1).unwrap()).get(), -1);
+    assert_eq!((-NonZeroI64::new(-1).unwrap()).get(), 1);
+
+    assert_eq!((-NonZeroI128::new(1).unwrap()).get(), -1);
+    assert_eq!((-NonZeroI128::new(-1).unwrap()).get(), 1);
+}
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index 4c1e196b5ad..54b11c543f1 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -14,6 +14,7 @@ use std::hash::Hash;
 use std::marker;
 use std::mem;
 use std::ops::Bound;
+use std::ops::Range;
 use std::panic;
 use std::sync::atomic::AtomicUsize;
 use std::sync::Once;
@@ -93,6 +94,7 @@ macro_rules! with_api {
                 fn source_file($self: $S::Span) -> $S::SourceFile;
                 fn parent($self: $S::Span) -> Option<$S::Span>;
                 fn source($self: $S::Span) -> $S::Span;
+                fn byte_range($self: $S::Span) -> Range<usize>;
                 fn start($self: $S::Span) -> LineColumn;
                 fn end($self: $S::Span) -> LineColumn;
                 fn before($self: $S::Span) -> $S::Span;
@@ -519,3 +521,7 @@ pub struct ExpnGlobals<Span> {
 compound_traits!(
     struct ExpnGlobals<Span> { def_site, call_site, mixed_site }
 );
+
+compound_traits!(
+    struct Range<T> { start, end }
+);
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 9d081c8b842..c64665b6ae0 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -44,7 +44,7 @@ mod diagnostic;
 pub use diagnostic::{Diagnostic, Level, MultiSpan};
 
 use std::cmp::Ordering;
-use std::ops::RangeBounds;
+use std::ops::{Range, RangeBounds};
 use std::path::PathBuf;
 use std::str::FromStr;
 use std::{error, fmt};
@@ -488,6 +488,12 @@ impl Span {
         Span(self.0.source())
     }
 
+    /// Returns the span's byte position range in the source file.
+    #[unstable(feature = "proc_macro_span", issue = "54725")]
+    pub fn byte_range(&self) -> Range<usize> {
+        self.0.byte_range()
+    }
+
     /// Gets the starting line/column in the source file for this span.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn start(&self) -> LineColumn {
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index e5048dcc8ac..a7428776d8f 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -9,6 +9,7 @@ use crate::io::{
     self, BorrowedCursor, BufRead, ErrorKind, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write,
 };
 use crate::mem;
+use crate::str;
 
 // =============================================================================
 // Forwarding implementations
@@ -307,6 +308,17 @@ impl Read for &[u8] {
         *self = &self[len..];
         Ok(len)
     }
+
+    #[inline]
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
+        let content = str::from_utf8(self).map_err(|_| {
+            io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8")
+        })?;
+        buf.push_str(content);
+        let len = self.len();
+        *self = &self[len..];
+        Ok(len)
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -336,7 +348,7 @@ impl Write for &mut [u8] {
     #[inline]
     fn write(&mut self, data: &[u8]) -> io::Result<usize> {
         let amt = cmp::min(data.len(), self.len());
-        let (a, b) = mem::replace(self, &mut []).split_at_mut(amt);
+        let (a, b) = mem::take(self).split_at_mut(amt);
         a.copy_from_slice(&data[..amt]);
         *self = b;
         Ok(amt)
@@ -434,6 +446,33 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
         self.drain(..n);
         Ok(())
     }
+
+    #[inline]
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        // The total len is known upfront so we can reserve it in a single call.
+        let len = self.len();
+        buf.reserve(len);
+
+        let (front, back) = self.as_slices();
+        buf.extend_from_slice(front);
+        buf.extend_from_slice(back);
+        self.clear();
+        Ok(len)
+    }
+
+    #[inline]
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
+        // We have to use a single contiguous slice because the `VecDequeue` might be split in the
+        // middle of an UTF-8 character.
+        let len = self.len();
+        let content = self.make_contiguous();
+        let string = str::from_utf8(content).map_err(|_| {
+            io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8")
+        })?;
+        buf.push_str(string);
+        self.clear();
+        Ok(len)
+    }
 }
 
 /// Write is implemented for `VecDeque<u8>` by appending to the `VecDeque`, growing it as needed.
@@ -446,6 +485,21 @@ impl<A: Allocator> Write for VecDeque<u8, A> {
     }
 
     #[inline]
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        let len = bufs.iter().map(|b| b.len()).sum();
+        self.reserve(len);
+        for buf in bufs {
+            self.extend(&**buf);
+        }
+        Ok(len)
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
+    }
+
+    #[inline]
     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
         self.extend(buf);
         Ok(())
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 020c723925a..8c1c8cac0ef 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -253,7 +253,7 @@ mod tests;
 
 use crate::cmp;
 use crate::fmt;
-use crate::mem::replace;
+use crate::mem::take;
 use crate::ops::{Deref, DerefMut};
 use crate::slice;
 use crate::str;
@@ -1186,7 +1186,7 @@ impl<'a> IoSliceMut<'a> {
             }
         }
 
-        *bufs = &mut replace(bufs, &mut [])[remove..];
+        *bufs = &mut take(bufs)[remove..];
         if bufs.is_empty() {
             assert!(n == accumulated_len, "advancing io slices beyond their length");
         } else {
@@ -1329,7 +1329,7 @@ impl<'a> IoSlice<'a> {
             }
         }
 
-        *bufs = &mut replace(bufs, &mut [])[remove..];
+        *bufs = &mut take(bufs)[remove..];
         if bufs.is_empty() {
             assert!(n == accumulated_len, "advancing io slices beyond their length");
         } else {
diff --git a/library/std/src/sys/unsupported/io.rs b/library/std/src/sys/unsupported/io.rs
index 82610ffab7e..6372fca74e0 100644
--- a/library/std/src/sys/unsupported/io.rs
+++ b/library/std/src/sys/unsupported/io.rs
@@ -30,7 +30,7 @@ impl<'a> IoSliceMut<'a> {
 
     #[inline]
     pub fn advance(&mut self, n: usize) {
-        let slice = mem::replace(&mut self.0, &mut []);
+        let slice = mem::take(&mut self.0);
         let (_, remaining) = slice.split_at_mut(n);
         self.0 = remaining;
     }
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index a158d1f718e..19d67e80a61 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -374,9 +374,9 @@ checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.3.1"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
+checksum = "3f508063cc7bb32987c71511216bd5a32be15bccb6a80b52df8b9d7f01fc3aa2"
 
 [[package]]
 name = "log"
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 3d3f991bffa..0d2d512b4b2 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1589,8 +1589,8 @@ impl<'a> Builder<'a> {
         // which adds to the runtime dynamic loader path when looking for
         // dynamic libraries. We use this by default on Unix platforms to ensure
         // that our nightlies behave the same on Windows, that is they work out
-        // of the box. This can be disabled, of course, but basically that's why
-        // we're gated on RUSTC_RPATH here.
+        // of the box. This can be disabled by setting `rpath = false` in `[rust]`
+        // table of `config.toml`
         //
         // Ok, so the astute might be wondering "why isn't `-C rpath` used
         // here?" and that is indeed a good question to ask. This codegen
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 8af5927e27f..ab307d4d038 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -1328,7 +1328,6 @@ impl Step for Sysroot {
                     true
                 }
             });
-            return INTERNER.intern_path(sysroot);
         }
 
         // Symlink the source root into the same location inside the sysroot,
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 79eec6f848c..f8da6df0c7c 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -748,6 +748,7 @@ macro_rules! tool_extended {
        stable = $stable:expr
        $(,tool_std = $tool_std:literal)?
        $(,allow_features = $allow_features:expr)?
+       $(,add_bins_to_sysroot = $add_bins_to_sysroot:expr)?
        ;)+) => {
         $(
             #[derive(Debug, Clone, Hash, PartialEq, Eq)]
@@ -790,7 +791,7 @@ macro_rules! tool_extended {
 
             #[allow(unused_mut)]
             fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> {
-                $builder.ensure(ToolBuild {
+                let tool = $builder.ensure(ToolBuild {
                     compiler: $sel.compiler,
                     target: $sel.target,
                     tool: $tool_name,
@@ -800,7 +801,27 @@ macro_rules! tool_extended {
                     is_optional_tool: true,
                     source_type: SourceType::InTree,
                     allow_features: concat!($($allow_features)*),
-                })
+                })?;
+
+                if (false $(|| !$add_bins_to_sysroot.is_empty())?) && $sel.compiler.stage > 0 {
+                    let bindir = $builder.sysroot($sel.compiler).join("bin");
+                    t!(fs::create_dir_all(&bindir));
+
+                    #[allow(unused_variables)]
+                    let tools_out = $builder
+                        .cargo_out($sel.compiler, Mode::ToolRustc, $sel.target);
+
+                    $(for add_bin in $add_bins_to_sysroot {
+                        let bin_source = tools_out.join(exe(add_bin, $sel.target));
+                        let bin_destination = bindir.join(exe(add_bin, $sel.compiler.host));
+                        $builder.copy(&bin_source, &bin_destination);
+                    })?
+
+                    let tool = bindir.join(exe($tool_name, $sel.compiler.host));
+                    Some(tool)
+                } else {
+                    Some(tool)
+                }
             }
         }
         )+
@@ -814,15 +835,15 @@ macro_rules! tool_extended {
 tool_extended!((self, builder),
     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;
+    Clippy, "src/tools/clippy", "clippy-driver", stable=true, add_bins_to_sysroot = ["clippy-driver", "cargo-clippy"];
+    Miri, "src/tools/miri", "miri", stable=false, add_bins_to_sysroot = ["miri"];
+    CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true, add_bins_to_sysroot = ["cargo-miri"];
     // 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, tool_std=true;
     RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, tool_std=true;
-    Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true;
+    Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, add_bins_to_sysroot = ["rustfmt", "cargo-fmt"];
 );
 
 impl<'a> Builder<'a> {
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 8ded2ee59dd..48efa67191a 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -42,6 +42,7 @@
     - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
     - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md)
     - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
+    - [x86_64h-apple-darwin](platform-support/x86_64h-apple-darwin.md)
 - [Targets](targets/index.md)
     - [Built-in Targets](targets/built-in.md)
     - [Custom Targets](targets/custom.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index c378532dbf6..75f97c1fc1e 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -327,5 +327,6 @@ target | std | host | notes
 `x86_64-uwp-windows-gnu` | ✓ |  |
 `x86_64-uwp-windows-msvc` | ✓ |  |
 `x86_64-wrs-vxworks` | ? |  |
+`x86_64h-apple-darwin` | ✓ | ✓ | macOS with late-gen Intel (at least Haswell)
 
 [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets
diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md
index d7d31d8724c..16ccaf46b2f 100644
--- a/src/doc/rustc/src/platform-support/loongarch-linux.md
+++ b/src/doc/rustc/src/platform-support/loongarch-linux.md
@@ -15,6 +15,8 @@ While the integer base ABI is implied by the machine field, the floating po
 |          f32           | The base ABI uses 32-bit FPRs for parameter passing. (lp64f)|
 |          sf            | The base ABI uses no FPR for parameter passing. (lp64s)     |
 
+<br>
+
 |`ABI type(Base ABI/ABI extension)`| `C library` | `kernel` |          `target tuple`          |
 |----------------------------------|-------------|----------|----------------------------------|
 |           lp64d/base             |   glibc     |  linux   | loongarch64-unknown-linux-gnu |
diff --git a/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md
new file mode 100644
index 00000000000..1a6f7bb834c
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md
@@ -0,0 +1,57 @@
+# `x86_64h-apple-darwin`
+
+**Tier: 3**
+
+Target for macOS on late-generation `x86_64` Apple chips, usable as the
+`x86_64h` entry in universal binaries, and equivalent to LLVM's
+`x86_64h-apple-macosx*` targets.
+
+## Target maintainers
+
+- Thom Chiovoloni `thom@shift.click` <https://github.com/thomcc>
+
+## Requirements
+
+This target is an `x86_64` target that only supports Apple's late-gen
+(Haswell-compatible) Intel chips. It enables a set of target features available
+on these chips (AVX2 and similar), and MachO binaries built with this target may
+be used as the `x86_64h` entry in universal binaries ("fat" MachO binaries), and
+will fail to load on machines that do not support this.
+
+It should support the full standard library (`std` and `alloc` either with
+default or user-defined allocators). This target is probably most useful when
+targetted via cross-compilation (including from `x86_64-apple-darwin`), but if
+built manually, the host tools work.
+
+It is similar to `x86_64-apple-darwin` in nearly all respects, although the
+minimum supported OS version is slightly higher (it requires 10.8 rather than
+`x86_64-apple-darwin`'s 10.7).
+
+## Building the target
+
+Users on Apple targets can build this by adding it to the `target` list in
+`config.toml`, or with `-Zbuild-std`.
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target. To compile for
+this target, you will either need to build Rust with the target enabled (see
+"Building the target" above), or build your own copy of `core` by using
+`build-std` or similar.
+
+## Testing
+
+Code built with this target can be run on the set of Intel macOS machines that
+support running `x86_64h` binaries (relatively recent Intel macs). The Rust test
+suite seems to work.
+
+## Cross-compilation toolchains and C code
+
+Cross-compilation to this target from Apple hosts should generally work without
+much configuration, so long as XCode and the CommandLineTools are installed.
+Targetting it from non-Apple hosts is difficult, but no moreso than targetting
+`x86_64-apple-darwin`.
+
+When compiling C code for this target, either the "`x86_64h-apple-macosx*`" LLVM
+targets should be used, or an argument like `-arch x86_64h` should be passed to
+the C compiler.
diff --git a/src/etc/installer/pkg/Distribution.xml b/src/etc/installer/pkg/Distribution.xml
index 1643fc8364b..395814e7488 100644
--- a/src/etc/installer/pkg/Distribution.xml
+++ b/src/etc/installer/pkg/Distribution.xml
@@ -23,7 +23,7 @@
     </choices-outline>
     <!--
     These 'selected' scripts ensure that install and uninstall can never be selected at
-    the same time. Exectly how they work is pretty mysterious, tied to the unspecified algorithm
+    the same time. Exactly how they work is pretty mysterious, tied to the unspecified algorithm
     the installer uses to traverse the options after one is toggled.
       -->
     <choice id="install" visible="true"
diff --git a/src/etc/lldb_lookup.py b/src/etc/lldb_lookup.py
index bca9c2ae192..36c7d82b34a 100644
--- a/src/etc/lldb_lookup.py
+++ b/src/etc/lldb_lookup.py
@@ -115,4 +115,4 @@ def synthetic_lookup(valobj, dict):
     if rust_type == RustType.STD_REF_CELL:
         return StdRefSyntheticProvider(valobj, dict, is_cell=True)
 
-    return DefaultSynthteticProvider(valobj, dict)
+    return DefaultSyntheticProvider(valobj, dict)
diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py
index 697ad4293c3..4f73746f817 100644
--- a/src/etc/lldb_providers.py
+++ b/src/etc/lldb_providers.py
@@ -69,9 +69,9 @@ def unwrap_unique_or_non_null(unique_or_nonnull):
     return ptr if ptr.TypeIsPointerType() else ptr.GetChildAtIndex(0)
 
 
-class DefaultSynthteticProvider:
+class DefaultSyntheticProvider:
     def __init__(self, valobj, dict):
-        # type: (SBValue, dict) -> DefaultSynthteticProvider
+        # type: (SBValue, dict) -> DefaultSyntheticProvider
         # logger = Logger.Logger()
         # logger >> "Default synthetic provider for " + str(valobj.GetName())
         self.valobj = valobj
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index cca50df0db2..b802fd065fe 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -243,9 +243,9 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
     match n.kind() {
         ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs: _ }) => {
             let s = if let Some(def) = def.as_local() {
-                print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def.did))
+                print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def))
             } else {
-                inline::print_inlined_const(cx.tcx, def.did)
+                inline::print_inlined_const(cx.tcx, def)
             };
 
             s
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 463184acaa1..a5f08fdac11 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -32,6 +32,7 @@ mod context;
 mod print_item;
 mod sidebar;
 mod span_map;
+mod type_layout;
 mod write_shared;
 
 pub(crate) use self::context::*;
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 9a968e48b27..3e71d41ec96 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -6,16 +6,14 @@ use rustc_hir as hir;
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::DefId;
 use rustc_middle::middle::stability;
-use rustc_middle::span_bug;
-use rustc_middle::ty::layout::LayoutError;
-use rustc_middle::ty::{self, Adt, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_target::abi::{LayoutS, Primitive, TagEncoding, Variants};
 use std::cmp::Ordering;
 use std::fmt;
 use std::rc::Rc;
 
+use super::type_layout::document_type_layout;
 use super::{
     collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference,
     item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls,
@@ -1933,118 +1931,6 @@ fn document_non_exhaustive<'a>(item: &'a clean::Item) -> impl fmt::Display + 'a
     })
 }
 
-fn document_type_layout<'a, 'cx: 'a>(
-    cx: &'a Context<'cx>,
-    ty_def_id: DefId,
-) -> impl fmt::Display + 'a + Captures<'cx> {
-    fn write_size_of_layout(mut w: impl fmt::Write, layout: &LayoutS, tag_size: u64) {
-        if layout.abi.is_unsized() {
-            write!(w, "(unsized)").unwrap();
-        } else {
-            let size = layout.size.bytes() - tag_size;
-            write!(w, "{size} byte{pl}", pl = if size == 1 { "" } else { "s" }).unwrap();
-            if layout.abi.is_uninhabited() {
-                write!(
-                    w,
-                    " (<a href=\"https://doc.rust-lang.org/stable/reference/glossary.html#uninhabited\">uninhabited</a>)"
-                ).unwrap();
-            }
-        }
-    }
-
-    display_fn(move |mut f| {
-        if !cx.shared.show_type_layout {
-            return Ok(());
-        }
-
-        writeln!(
-            f,
-            "<h2 id=\"layout\" class=\"small-section-header\"> \
-            Layout<a href=\"#layout\" class=\"anchor\">§</a></h2>"
-        )?;
-        writeln!(f, "<div class=\"docblock\">")?;
-
-        let tcx = cx.tcx();
-        let param_env = tcx.param_env(ty_def_id);
-        let ty = tcx.type_of(ty_def_id).subst_identity();
-        match tcx.layout_of(param_env.and(ty)) {
-            Ok(ty_layout) => {
-                writeln!(
-                    f,
-                    "<div class=\"warning\"><p><strong>Note:</strong> Most layout information is \
-                    <strong>completely unstable</strong> and may even differ between compilations. \
-                    The only exception is types with certain <code>repr(...)</code> attributes. \
-                    Please see the Rust Reference’s \
-                    <a href=\"https://doc.rust-lang.org/reference/type-layout.html\">“Type Layout”</a> \
-                    chapter for details on type layout guarantees.</p></div>"
-                )?;
-                f.write_str("<p><strong>Size:</strong> ")?;
-                write_size_of_layout(&mut f, &ty_layout.layout.0, 0);
-                writeln!(f, "</p>")?;
-                if let Variants::Multiple { variants, tag, tag_encoding, .. } =
-                    &ty_layout.layout.variants()
-                {
-                    if !variants.is_empty() {
-                        f.write_str(
-                            "<p><strong>Size for each variant:</strong></p>\
-                                <ul>",
-                        )?;
-
-                        let Adt(adt, _) = ty_layout.ty.kind() else {
-                            span_bug!(tcx.def_span(ty_def_id), "not an adt")
-                        };
-
-                        let tag_size = if let TagEncoding::Niche { .. } = tag_encoding {
-                            0
-                        } else if let Primitive::Int(i, _) = tag.primitive() {
-                            i.size().bytes()
-                        } else {
-                            span_bug!(tcx.def_span(ty_def_id), "tag is neither niche nor int")
-                        };
-
-                        for (index, layout) in variants.iter_enumerated() {
-                            let name = adt.variant(index).name;
-                            write!(&mut f, "<li><code>{name}</code>: ")?;
-                            write_size_of_layout(&mut f, layout, tag_size);
-                            writeln!(&mut f, "</li>")?;
-                        }
-                        f.write_str("</ul>")?;
-                    }
-                }
-            }
-            // This kind of layout error can occur with valid code, e.g. if you try to
-            // get the layout of a generic type such as `Vec<T>`.
-            Err(LayoutError::Unknown(_)) => {
-                writeln!(
-                    f,
-                    "<p><strong>Note:</strong> Unable to compute type layout, \
-                    possibly due to this type having generic parameters. \
-                    Layout can only be computed for concrete, fully-instantiated types.</p>"
-                )?;
-            }
-            // This kind of error probably can't happen with valid code, but we don't
-            // want to panic and prevent the docs from building, so we just let the
-            // user know that we couldn't compute the layout.
-            Err(LayoutError::SizeOverflow(_)) => {
-                writeln!(
-                    f,
-                    "<p><strong>Note:</strong> Encountered an error during type layout; \
-                    the type was too big.</p>"
-                )?;
-            }
-            Err(LayoutError::NormalizationFailure(_, _)) => {
-                writeln!(
-                    f,
-                    "<p><strong>Note:</strong> Encountered an error during type layout; \
-                    the type failed to be normalized.</p>"
-                )?;
-            }
-        }
-
-        writeln!(f, "</div>")
-    })
-}
-
 fn pluralize(count: usize) -> &'static str {
     if count > 1 { "s" } else { "" }
 }
diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs
new file mode 100644
index 00000000000..22aec623335
--- /dev/null
+++ b/src/librustdoc/html/render/type_layout.rs
@@ -0,0 +1,86 @@
+use askama::Template;
+
+use rustc_data_structures::captures::Captures;
+use rustc_hir::def_id::DefId;
+use rustc_middle::span_bug;
+use rustc_middle::ty::layout::LayoutError;
+use rustc_middle::ty::Adt;
+use rustc_span::symbol::Symbol;
+use rustc_target::abi::{Primitive, TagEncoding, Variants};
+
+use std::fmt;
+
+use crate::html::format::display_fn;
+use crate::html::render::Context;
+
+#[derive(Template)]
+#[template(path = "type_layout.html")]
+struct TypeLayout<'cx> {
+    variants: Vec<(Symbol, TypeLayoutSize)>,
+    type_layout_size: Result<TypeLayoutSize, LayoutError<'cx>>,
+}
+
+#[derive(Template)]
+#[template(path = "type_layout_size.html")]
+struct TypeLayoutSize {
+    is_unsized: bool,
+    is_uninhabited: bool,
+    size: u64,
+}
+
+pub(crate) fn document_type_layout<'a, 'cx: 'a>(
+    cx: &'a Context<'cx>,
+    ty_def_id: DefId,
+) -> impl fmt::Display + 'a + Captures<'cx> {
+    display_fn(move |f| {
+        if !cx.shared.show_type_layout {
+            return Ok(());
+        }
+
+        let tcx = cx.tcx();
+        let param_env = tcx.param_env(ty_def_id);
+        let ty = tcx.type_of(ty_def_id).subst_identity();
+        let type_layout = tcx.layout_of(param_env.and(ty));
+
+        let variants =
+            if let Ok(type_layout) = type_layout &&
+                let Variants::Multiple { variants, tag, tag_encoding, .. } =
+                    type_layout.layout.variants() &&
+                !variants.is_empty()
+            {
+                let tag_size =
+                    if let TagEncoding::Niche { .. } = tag_encoding {
+                        0
+                    } else if let Primitive::Int(i, _) = tag.primitive() {
+                        i.size().bytes()
+                    } else {
+                        span_bug!(cx.tcx().def_span(ty_def_id), "tag is neither niche nor int")
+                    };
+                variants
+                    .iter_enumerated()
+                    .map(|(variant_idx, variant_layout)| {
+                        let Adt(adt, _) = type_layout.ty.kind() else {
+                            span_bug!(cx.tcx().def_span(ty_def_id), "not an adt")
+                        };
+                        let name = adt.variant(variant_idx).name;
+                        let is_unsized = variant_layout.abi.is_unsized();
+                        let is_uninhabited = variant_layout.abi.is_uninhabited();
+                        let size = variant_layout.size.bytes() - tag_size;
+                        let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size };
+                        (name, type_layout_size)
+                    })
+                    .collect()
+            } else {
+                Vec::new()
+            };
+
+        let type_layout_size = tcx.layout_of(param_env.and(ty)).map(|layout| {
+            let is_unsized = layout.abi.is_unsized();
+            let is_uninhabited = layout.abi.is_uninhabited();
+            let size = layout.size.bytes();
+            TypeLayoutSize { is_unsized, is_uninhabited, size }
+        });
+
+        Ok(TypeLayout { variants, type_layout_size }.render_into(f).unwrap())
+    })
+}
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 93d657fd605..bccf675c14b 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -375,10 +375,7 @@ function preLoadCss(cssUrl) {
 
     function handleEscape(ev) {
         searchState.clearInputTimeout();
-        switchDisplayedElement(null);
-        if (browserSupportsHistoryApi()) {
-            history.replaceState(null, "", getNakedUrl() + window.location.hash);
-        }
+        searchState.hideResults();
         ev.preventDefault();
         searchState.defocus();
         window.hideAllModals(true); // true = reset focus for tooltips
@@ -533,9 +530,11 @@ function preLoadCss(cssUrl) {
         // ignored are included in the attribute `data-ignore-extern-crates`.
         const script = document
             .querySelector("script[data-ignore-extern-crates]");
-        const ignoreExternCrates = script ? script.getAttribute("data-ignore-extern-crates") : "";
+        const ignoreExternCrates = new Set(
+            (script ? script.getAttribute("data-ignore-extern-crates") : "").split(",")
+        );
         for (const lib of libs) {
-            if (lib === window.currentCrate || ignoreExternCrates.indexOf(lib) !== -1) {
+            if (lib === window.currentCrate || ignoreExternCrates.has(lib)) {
                 continue;
             }
             const structs = imp[lib];
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 929dae81c8d..3dc4f2149b8 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -2412,10 +2412,6 @@ function initSearch(rawSearchIndex) {
         const searchAfter500ms = () => {
             searchState.clearInputTimeout();
             if (searchState.input.value.length === 0) {
-                if (browserSupportsHistoryApi()) {
-                    history.replaceState(null, window.currentCrate + " - Rust",
-                        getNakedUrl() + window.location.hash);
-                }
                 searchState.hideResults();
             } else {
                 searchState.timeout = setTimeout(search, 500);
diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js
index 9aa75517330..d999f3b36fd 100644
--- a/src/librustdoc/html/static/js/source-script.js
+++ b/src/librustdoc/html/static/js/source-script.js
@@ -52,12 +52,12 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) {
     const files = document.createElement("div");
     files.className = "files";
     if (elem[FILES_OFFSET]) {
+        const w = window.location.href.split("#")[0];
         for (const file_text of elem[FILES_OFFSET]) {
             const file = document.createElement("a");
             file.innerText = file_text;
             file.href = rootPath + "src/" + fullPath + file_text + ".html";
             file.addEventListener("click", closeSidebarIfMobile);
-            const w = window.location.href.split("#")[0];
             if (!hasFoundFile && w === file.href) {
                 file.className = "selected";
                 dirEntry.open = true;
diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html
new file mode 100644
index 00000000000..58b220c7428
--- /dev/null
+++ b/src/librustdoc/html/templates/type_layout.html
@@ -0,0 +1,53 @@
+<h2 id="layout" class="small-section-header">  {# #}
+    Layout<a href="#layout" class="anchor">§</a> {# #}
+</h2> {# #}
+<div class="docblock"> {# #}
+    {% match type_layout_size %}
+        {% when Ok(type_layout_size) %}
+            <div class="warning"> {# #}
+                <p> {# #}
+                    <strong>Note:</strong> Most layout information is <strong>completely {#+ #}
+                    unstable</strong> and may even differ between compilations. {#+ #}
+                    The only exception is types with certain <code>repr(...)</code> {#+ #}
+                    attributes. Please see the Rust Reference’s {#+ #}
+                    <a href="https://doc.rust-lang.org/reference/type-layout.html">“Type Layout”</a> {#+ #}
+                    chapter for details on type layout guarantees. {# #}
+                </p> {# #}
+            </div> {# #}
+            <p><strong>Size:</strong> {{ type_layout_size|safe }}</p> {# #}
+            {% if !variants.is_empty() %}
+                <p> {# #}
+                    <strong>Size for each variant:</strong> {# #}
+                </p> {# #}
+                <ul> {# #}
+                    {% for (name, layout_size) in variants %}
+                        <li> {# #}
+                            <code>{{ name }}</code>: {#+ #}
+                            {{ layout_size|safe }}
+                        </li> {# #}
+                    {% endfor %}
+                </ul> {# #}
+            {% endif %}
+        {# This kind of layout error can occur with valid code, e.g. if you try to
+           get the layout of a generic type such as `Vec<T>`. #}
+        {% when Err(LayoutError::Unknown(_)) %}
+            <p> {# #}
+                <strong>Note:</strong> Unable to compute type layout, {#+ #}
+                possibly due to this type having generic parameters. {#+ #}
+                Layout can only be computed for concrete, fully-instantiated types. {# #}
+            </p> {# #}
+        {# This kind of error probably can't happen with valid code, but we don't
+           want to panic and prevent the docs from building, so we just let the
+           user know that we couldn't compute the layout. #}
+        {% when Err(LayoutError::SizeOverflow(_)) %}
+            <p> {# #}
+                <strong>Note:</strong> Encountered an error during type layout; {#+ #}
+                the type was too big. {# #}
+            </p> {# #}
+        {% when Err(LayoutError::NormalizationFailure(_, _)) %}
+            <p> {# #}
+                <strong>Note:</strong> Encountered an error during type layout; {#+ #}
+                the type failed to be normalized. {# #}
+            </p> {# #}
+    {% endmatch %}
+</div> {# #}
diff --git a/src/librustdoc/html/templates/type_layout_size.html b/src/librustdoc/html/templates/type_layout_size.html
new file mode 100644
index 00000000000..9c2b39edc9f
--- /dev/null
+++ b/src/librustdoc/html/templates/type_layout_size.html
@@ -0,0 +1,12 @@
+{% if is_unsized %}
+  (unsized)
+{% else %}
+  {% if size == 1 %}
+    1 byte
+  {% else %}
+    {{ size +}} bytes
+  {% endif %}
+  {% if is_uninhabited %}
+    {# +#} (<a href="https://doc.rust-lang.org/stable/reference/glossary.html#uninhabited">uninhabited</a>)
+  {% endif %}
+{% endif %}
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 585a6eb3ebf7c40fd7c1b23e3ece557b3cc2aa3
+Subproject ea6fa9c2d43aaf0f11559719eda9b54d356d541
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject d0a4cbcee614fdb7ba66e860e603a00a644d71f
+Subproject de80432f04da61d98dcbbc1572598071718ccfd
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index f0a1b1dfe56..5f1fdf00be8 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -226,7 +226,8 @@ fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec<HirId>, main_loop_id: H
                 | InlineAsmOperand::SymStatic { .. } => NeverLoopResult::Otherwise,
             })
             .fold(NeverLoopResult::Otherwise, combine_seq),
-        ExprKind::Yield(_, _)
+        ExprKind::OffsetOf(_, _)
+        | ExprKind::Yield(_, _)
         | ExprKind::Closure { .. }
         | ExprKind::Path(_)
         | ExprKind::ConstBlock(_)
diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index 04225beeb70..7945275393c 100644
--- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -342,6 +342,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> {
             ExprKind::DropTemps(_) |
             ExprKind::Err(_) |
             ExprKind::InlineAsm(_) |
+            ExprKind::OffsetOf(_, _) |
             ExprKind::Let(_) |
             ExprKind::Lit(_) |
             ExprKind::Loop(_, _, _, _) |
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 0bedab05eec..eed0f1f1991 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -196,11 +196,9 @@ fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<
 fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
     let substs = cx.typeck_results().node_substs(hir_id);
 
-    let result = cx.tcx.const_eval_resolve(
-        cx.param_env,
-        mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs),
-        None,
-    );
+    let result = cx
+        .tcx
+        .const_eval_resolve(cx.param_env, mir::UnevaluatedConst::new(def_id, substs), None);
     is_value_unfrozen_raw(cx, result, ty)
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 2dac807c420..01927b6b5f1 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -558,6 +558,10 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                 kind!("InlineAsm(_)");
                 out!("// unimplemented: `ExprKind::InlineAsm` is not further destructured at the moment");
             },
+            ExprKind::OffsetOf(container, ref fields) => {
+                bind!(self, container, fields);
+                kind!("OffsetOf({container}, {fields})");
+            }
             ExprKind::Struct(qpath, fields, base) => {
                 bind!(self, qpath, fields);
                 opt_bind!(self, base);
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index bb8890dcaf9..99bfc4b5717 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -450,11 +450,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
                 let result = self
                     .lcx
                     .tcx
-                    .const_eval_resolve(
-                        self.param_env,
-                        mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs),
-                        None,
-                    )
+                    .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, substs), None)
                     .ok()
                     .map(|val| rustc_middle::mir::ConstantKind::from_value(val, ty))?;
                 let result = miri_to_const(self.lcx.tcx, result);
diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
index 28c85717061..3df40942e7b 100644
--- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
+++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
@@ -218,7 +218,8 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
                 | ExprKind::AddrOf(..)
                 | ExprKind::Struct(..)
                 | ExprKind::Repeat(..)
-                | ExprKind::Block(Block { stmts: [], .. }, _) => (),
+                | ExprKind::Block(Block { stmts: [], .. }, _)
+                | ExprKind::OffsetOf(..) => (),
 
                 // Assignment might be to a local defined earlier, so don't eagerly evaluate.
                 // Blocks with multiple statements might be expensive, so don't eagerly evaluate.
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 3ee7147828b..d972ed82c25 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -301,6 +301,9 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&ExprKind::Unary(l_op, le), &ExprKind::Unary(r_op, re)) => l_op == r_op && self.eq_expr(le, re),
             (&ExprKind::Array(l), &ExprKind::Array(r)) => self.eq_exprs(l, r),
             (&ExprKind::DropTemps(le), &ExprKind::DropTemps(re)) => self.eq_expr(le, re),
+            (&ExprKind::OffsetOf(l_container, ref l_fields), &ExprKind::OffsetOf(r_container, ref r_fields)) => {
+                self.eq_ty(l_container, r_container) && over(l_fields, r_fields, |l, r| l.name == r.name)
+            },
             _ => false,
         };
         (is_eq && (!self.should_ignore(left) || !self.should_ignore(right)))
@@ -701,6 +704,12 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                     }
                 }
             },
+            ExprKind::OffsetOf(container, fields) => {
+                self.hash_ty(container);
+                for field in fields {
+                    self.hash_name(field.name);
+                }
+            },
             ExprKind::Let(Let { pat, init, ty, .. }) => {
                 self.hash_expr(init);
                 if let Some(ty) = ty {
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 354b6d71aa4..ecd712f32dc 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -194,7 +194,7 @@ fn check_rvalue<'tcx>(
                 ))
             }
         },
-        Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) | Rvalue::ShallowInitBox(_, _) => Ok(()),
+        Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) | Rvalue::ShallowInitBox(_, _) => Ok(()),
         Rvalue::UnaryOp(_, operand) => {
             let ty = operand.ty(body, tcx);
             if ty.is_integral() || ty.is_bool() {
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index a5a4a921d94..e81eadceec0 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -139,6 +139,7 @@ impl<'a> Sugg<'a> {
             | hir::ExprKind::Field(..)
             | hir::ExprKind::Index(..)
             | hir::ExprKind::InlineAsm(..)
+            | hir::ExprKind::OffsetOf(..)
             | hir::ExprKind::ConstBlock(..)
             | hir::ExprKind::Lit(..)
             | hir::ExprKind::Loop(..)
@@ -197,6 +198,7 @@ impl<'a> Sugg<'a> {
             | ast::ExprKind::ForLoop(..)
             | ast::ExprKind::Index(..)
             | ast::ExprKind::InlineAsm(..)
+            | ast::ExprKind::OffsetOf(..)
             | ast::ExprKind::ConstBlock(..)
             | ast::ExprKind::Lit(..)
             | ast::ExprKind::IncludedBytes(..)
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index 1dc19bac984..5dcd71cef12 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -662,6 +662,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
             | ExprKind::Path(_)
             | ExprKind::Continue(_)
             | ExprKind::InlineAsm(_)
+            | ExprKind::OffsetOf(..)
             | ExprKind::Err(_) => (),
         }
         ControlFlow::Continue(())
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index 718bc41fb99..205905d5091 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -160,6 +160,9 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
         // MIR passes can be enabled / disabled separately, we should figure out, what passes to
         // use for Clippy.
         config.opts.unstable_opts.mir_opt_level = Some(0);
+
+        // Disable flattening and inlining of format_args!(), so the HIR matches with the AST.
+        config.opts.unstable_opts.flatten_format_args = false;
     }
 }
 
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index aaa70bf19b2..ccce62bd5b0 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -102,6 +102,9 @@ pub struct TestProps {
     pub dont_check_compiler_stdout: bool,
     // For UI tests, allows compiler to generate arbitrary output to stderr
     pub dont_check_compiler_stderr: bool,
+    // When checking the output of stdout or stderr check
+    // that the lines of expected output are a subset of the actual output.
+    pub compare_output_lines_by_subset: bool,
     // Don't force a --crate-type=dylib flag on the command line
     //
     // Set this for example if you have an auxiliary test file that contains
@@ -209,6 +212,7 @@ mod directives {
     pub const KNOWN_BUG: &'static str = "known-bug";
     pub const MIR_UNIT_TEST: &'static str = "unit-test";
     pub const REMAP_SRC_BASE: &'static str = "remap-src-base";
+    pub const COMPARE_OUTPUT_LINES_BY_SUBSET: &'static str = "compare-output-lines-by-subset";
     // This isn't a real directive, just one that is probably mistyped often
     pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags";
 }
@@ -233,6 +237,7 @@ impl TestProps {
             check_run_results: false,
             dont_check_compiler_stdout: false,
             dont_check_compiler_stderr: false,
+            compare_output_lines_by_subset: false,
             no_prefer_dynamic: false,
             pretty_expanded: false,
             pretty_mode: "normal".to_string(),
@@ -467,6 +472,11 @@ impl TestProps {
                     s.trim().to_string()
                 });
                 config.set_name_directive(ln, REMAP_SRC_BASE, &mut self.remap_src_base);
+                config.set_name_directive(
+                    ln,
+                    COMPARE_OUTPUT_LINES_BY_SUBSET,
+                    &mut self.compare_output_lines_by_subset,
+                );
             });
         }
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 1a4e9b58383..f6597c72938 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1900,8 +1900,11 @@ impl<'test> TestCx<'test> {
         // Use a single thread for efficiency and a deterministic error message order
         rustc.arg("-Zthreads=1");
 
-        // In stage 0, make sure we use `stage0-sysroot` instead of the bootstrap sysroot.
-        rustc.arg("--sysroot").arg(&self.config.sysroot_base);
+        // Optionally prevent default --sysroot if specified in test compile-flags.
+        if !self.props.compile_flags.iter().any(|flag| flag.starts_with("--sysroot")) {
+            // In stage 0, make sure we use `stage0-sysroot` instead of the bootstrap sysroot.
+            rustc.arg("--sysroot").arg(&self.config.sysroot_base);
+        }
 
         // Optionally prevent default --target if specified in test compile-flags.
         let custom_target = self.props.compile_flags.iter().any(|x| x.starts_with("--target"));
@@ -3241,17 +3244,35 @@ impl<'test> TestCx<'test> {
         match output_kind {
             TestOutput::Compile => {
                 if !self.props.dont_check_compiler_stdout {
-                    errors +=
-                        self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout);
+                    errors += self.compare_output(
+                        stdout_kind,
+                        &normalized_stdout,
+                        &expected_stdout,
+                        self.props.compare_output_lines_by_subset,
+                    );
                 }
                 if !self.props.dont_check_compiler_stderr {
-                    errors +=
-                        self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr);
+                    errors += self.compare_output(
+                        stderr_kind,
+                        &normalized_stderr,
+                        &expected_stderr,
+                        self.props.compare_output_lines_by_subset,
+                    );
                 }
             }
             TestOutput::Run => {
-                errors += self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout);
-                errors += self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr);
+                errors += self.compare_output(
+                    stdout_kind,
+                    &normalized_stdout,
+                    &expected_stdout,
+                    self.props.compare_output_lines_by_subset,
+                );
+                errors += self.compare_output(
+                    stderr_kind,
+                    &normalized_stderr,
+                    &expected_stderr,
+                    self.props.compare_output_lines_by_subset,
+                );
             }
         }
         errors
@@ -3335,7 +3356,12 @@ impl<'test> TestCx<'test> {
                 )
             });
 
-            errors += self.compare_output("fixed", &fixed_code, &expected_fixed);
+            errors += self.compare_output(
+                "fixed",
+                &fixed_code,
+                &expected_fixed,
+                self.props.compare_output_lines_by_subset,
+            );
         } else if !expected_fixed.is_empty() {
             panic!(
                 "the `// run-rustfix` directive wasn't found but a `*.fixed` \
@@ -3793,11 +3819,38 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    fn compare_output(&self, kind: &str, actual: &str, expected: &str) -> usize {
+    fn compare_output(
+        &self,
+        kind: &str,
+        actual: &str,
+        expected: &str,
+        compare_output_by_lines: bool,
+    ) -> usize {
         if actual == expected {
             return 0;
         }
 
+        let tmp;
+        let (expected, actual): (&str, &str) = if compare_output_by_lines {
+            let actual_lines: HashSet<_> = actual.lines().collect();
+            let expected_lines: Vec<_> = expected.lines().collect();
+            let mut used = expected_lines.clone();
+            used.retain(|line| actual_lines.contains(line));
+            // check if `expected` contains a subset of the lines of `actual`
+            if used.len() == expected_lines.len() && (expected.is_empty() == actual.is_empty()) {
+                return 0;
+            }
+            if expected_lines.is_empty() {
+                // if we have no lines to check, force a full overwite
+                ("", actual)
+            } else {
+                tmp = (expected_lines.join("\n"), used.join("\n"));
+                (&tmp.0, &tmp.1)
+            }
+        } else {
+            (expected, actual)
+        };
+
         if !self.config.bless {
             if expected.is_empty() {
                 println!("normalized {}:\n{}\n", kind, actual);
diff --git a/src/tools/linkchecker/linkcheck.sh b/src/tools/linkchecker/linkcheck.sh
index 9eeebf444a4..6c1e668a7f0 100755
--- a/src/tools/linkchecker/linkcheck.sh
+++ b/src/tools/linkchecker/linkcheck.sh
@@ -16,15 +16,13 @@
 #
 # --all     Check all books. This can help make sure you don't break links
 #           from other books into your book.
+#
+# --path <book-path>
+#           Path to the root directory for the book. Default to the current
+#           working directory if omitted.
 
 set -e
 
-if [ ! -f book.toml ] && [ ! -f src/SUMMARY.md ]
-then
-    echo "Run command in root directory of the book."
-    exit 1
-fi
-
 html_dir="$(rustc +nightly --print sysroot)/share/doc/rust/html"
 
 if [ ! -d "$html_dir" ]
@@ -38,6 +36,8 @@ fi
 export MDBOOK_OUTPUT__HTML__INPUT_404=""
 
 book_name=""
+# Default to the current directory
+book_path="."
 # Iterative will avoid cleaning up, so you can quickly run it repeatedly.
 iterative=0
 # If "1", test all books, else only this book.
@@ -52,6 +52,10 @@ do
         --all)
             all_books=1
             ;;
+        --path)
+            book_path="${2:-.}"
+            shift
+            ;;
         *)
             if [ -n "$book_name" ]
             then
@@ -70,6 +74,12 @@ then
     exit 1
 fi
 
+if [ ! -f "$book_path/book.toml" ] && [ ! -f "$book_path/src/SUMMARY.md" ]
+then
+    echo "Run command in root directory of the book or provide a path to the book"
+    exit 1
+fi
+
 if [ ! -d "$html_dir/$book_name" ]
 then
     echo "book name \"$book_name\" not found in sysroot \"$html_dir\""
@@ -93,11 +103,11 @@ then
 fi
 
 echo "Building book \"$book_name\"..."
-mdbook build
+mdbook build "$book_path"
 
 cp -R "$html_dir" linkcheck
 rm -rf "linkcheck/$book_name"
-cp -R book "linkcheck/$book_name"
+cp -R "$book_path/book" "linkcheck/$book_name"
 
 if [ "$all_books" = "1" ]
 then
diff --git a/src/tools/miri/tests/fail/const-ub-checks.stderr b/src/tools/miri/tests/fail/const-ub-checks.stderr
index a8b7ea242b9..596a6bb4ca8 100644
--- a/src/tools/miri/tests/fail/const-ub-checks.stderr
+++ b/src/tools/miri/tests/fail/const-ub-checks.stderr
@@ -4,6 +4,12 @@ error[E0080]: evaluation of constant value failed
 LL |     ptr.read();
    |     ^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required
 
+note: erroneous constant used
+  --> $DIR/const-ub-checks.rs:LL:CC
+   |
+LL |     let _x = UNALIGNED_READ;
+   |              ^^^^^^^^^^^^^^
+
 error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/tools/miri/tests/fail/erroneous_const2.stderr b/src/tools/miri/tests/fail/erroneous_const2.stderr
index d41fcfd2302..9aad1fc9b02 100644
--- a/src/tools/miri/tests/fail/erroneous_const2.stderr
+++ b/src/tools/miri/tests/fail/erroneous_const2.stderr
@@ -4,6 +4,20 @@ error[E0080]: evaluation of constant value failed
 LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
    |                   ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow
 
+note: erroneous constant used
+  --> $DIR/erroneous_const2.rs:LL:CC
+   |
+LL |     println!("{}", FOO);
+   |                    ^^^
+
+note: erroneous constant used
+  --> $DIR/erroneous_const2.rs:LL:CC
+   |
+LL |     println!("{}", FOO);
+   |                    ^^^
+   |
+   = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
 error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/tools/miri/tests/pass/track-alloc-1.rs b/src/tools/miri/tests/pass/track-alloc-1.rs
deleted file mode 100644
index 427c800dc51..00000000000
--- a/src/tools/miri/tests/pass/track-alloc-1.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-// Ensure that tracking early allocations doesn't ICE Miri.
-// Early allocations are probably part of the runtime and therefore uninteresting, but they
-// shouldn't cause a crash.
-//@compile-flags: -Zmiri-track-alloc-id=1
-//@normalize-stderr-test: "[48] bytes" -> "SIZE bytes"
-fn main() {}
diff --git a/src/tools/miri/tests/pass/track-alloc-1.stderr b/src/tools/miri/tests/pass/track-alloc-1.stderr
deleted file mode 100644
index 7206edbb701..00000000000
--- a/src/tools/miri/tests/pass/track-alloc-1.stderr
+++ /dev/null
@@ -1,5 +0,0 @@
-note: tracking was triggered
-   |
-   = note: created extern static allocation of SIZE bytes (alignment ALIGN bytes) with id 1
-   = note: (no span available)
-
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
index d258a024729..a9cd8e705a4 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
@@ -20,7 +20,7 @@ use token_stream::TokenStreamBuilder;
 mod symbol;
 pub use symbol::*;
 
-use std::ops::Bound;
+use std::ops::{Bound, Range};
 
 use crate::tt;
 
@@ -298,6 +298,10 @@ impl server::Span for RustAnalyzer {
         // FIXME handle span
         span
     }
+    fn byte_range(&mut self, _span: Self::Span) -> Range<usize> {
+        // FIXME handle span
+        Range { start: 0, end: 0 }
+    }
     fn start(&mut self, _span: Self::Span) -> LineColumn {
         // FIXME handle span
         LineColumn { line: 0, column: 0 }
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index ac96bedf2fe..824e4219136 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -399,7 +399,9 @@ pub(crate) fn format_expr(
             }
         }
         ast::ExprKind::Underscore => Some("_".to_owned()),
-        ast::ExprKind::FormatArgs(..) | ast::ExprKind::IncludedBytes(..) => {
+        ast::ExprKind::FormatArgs(..)
+        | ast::ExprKind::IncludedBytes(..)
+        | ast::ExprKind::OffsetOf(..) => {
             // These do not occur in the AST because macros aren't expanded.
             unreachable!()
         }
diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs
index a26375ee643..ca171657407 100644
--- a/src/tools/rustfmt/src/utils.rs
+++ b/src/tools/rustfmt/src/utils.rs
@@ -499,6 +499,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
         | ast::ExprKind::Field(..)
         | ast::ExprKind::IncludedBytes(..)
         | ast::ExprKind::InlineAsm(..)
+        | ast::ExprKind::OffsetOf(..)
         | ast::ExprKind::Let(..)
         | ast::ExprKind::Path(..)
         | ast::ExprKind::Range(..)
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index b1385edf13e..c19fa8e9656 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -10,7 +10,7 @@ use std::path::{Path, PathBuf};
 // FIXME: The following limits should be reduced eventually.
 const ENTRY_LIMIT: usize = 885;
 const ROOT_ENTRY_LIMIT: usize = 894;
-const ISSUES_ENTRY_LIMIT: usize = 1977;
+const ISSUES_ENTRY_LIMIT: usize = 1953;
 
 fn check_entries(tests_path: &Path, bad: &mut bool) {
     let mut directories: HashMap<PathBuf, usize> = HashMap::new();
diff --git a/tests/codegen/intrinsics/transmute-niched.rs b/tests/codegen/intrinsics/transmute-niched.rs
new file mode 100644
index 00000000000..69e9b1d1206
--- /dev/null
+++ b/tests/codegen/intrinsics/transmute-niched.rs
@@ -0,0 +1,184 @@
+// revisions: OPT DBG
+// [OPT] compile-flags: -C opt-level=3 -C no-prepopulate-passes
+// [DBG] compile-flags: -C opt-level=0 -C no-prepopulate-passes
+// only-64bit (so I don't need to worry about usize)
+// min-llvm-version: 15.0 # this test assumes `ptr`s
+
+#![crate_type = "lib"]
+
+use std::mem::transmute;
+use std::num::NonZeroU32;
+
+#[repr(u8)]
+pub enum SmallEnum {
+    A = 10,
+    B = 11,
+    C = 12,
+}
+
+// CHECK-LABEL: @check_to_enum(
+#[no_mangle]
+pub unsafe fn check_to_enum(x: i8) -> SmallEnum {
+    // OPT: %0 = icmp uge i8 %x, 10
+    // OPT: call void @llvm.assume(i1 %0)
+    // OPT: %1 = icmp ule i8 %x, 12
+    // OPT: call void @llvm.assume(i1 %1)
+    // DBG-NOT: icmp
+    // DBG-NOT: assume
+    // CHECK: ret i8 %x
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_from_enum(
+#[no_mangle]
+pub unsafe fn check_from_enum(x: SmallEnum) -> i8 {
+    // OPT: %0 = icmp uge i8 %x, 10
+    // OPT: call void @llvm.assume(i1 %0)
+    // OPT: %1 = icmp ule i8 %x, 12
+    // OPT: call void @llvm.assume(i1 %1)
+    // DBG-NOT: icmp
+    // DBG-NOT: assume
+    // CHECK: ret i8 %x
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_to_ordering(
+#[no_mangle]
+pub unsafe fn check_to_ordering(x: u8) -> std::cmp::Ordering {
+    // OPT: %0 = icmp uge i8 %x, -1
+    // OPT: %1 = icmp ule i8 %x, 1
+    // OPT: %2 = or i1 %0, %1
+    // OPT: call void @llvm.assume(i1 %2)
+    // DBG-NOT: icmp
+    // DBG-NOT: assume
+    // CHECK: ret i8 %x
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_from_ordering(
+#[no_mangle]
+pub unsafe fn check_from_ordering(x: std::cmp::Ordering) -> u8 {
+    // OPT: %0 = icmp uge i8 %x, -1
+    // OPT: %1 = icmp ule i8 %x, 1
+    // OPT: %2 = or i1 %0, %1
+    // OPT: call void @llvm.assume(i1 %2)
+    // DBG-NOT: icmp
+    // DBG-NOT: assume
+    // CHECK: ret i8 %x
+
+    transmute(x)
+}
+
+#[repr(i32)]
+pub enum Minus100ToPlus100 {
+    A = -100,
+    B = -90,
+    C = -80,
+    D = -70,
+    E = -60,
+    F = -50,
+    G = -40,
+    H = -30,
+    I = -20,
+    J = -10,
+    K = 0,
+    L = 10,
+    M = 20,
+    N = 30,
+    O = 40,
+    P = 50,
+    Q = 60,
+    R = 70,
+    S = 80,
+    T = 90,
+    U = 100,
+}
+
+// CHECK-LABEL: @check_enum_from_char(
+#[no_mangle]
+pub unsafe fn check_enum_from_char(x: char) -> Minus100ToPlus100 {
+    // OPT: %0 = icmp ule i32 %x, 1114111
+    // OPT: call void @llvm.assume(i1 %0)
+    // OPT: %1 = icmp uge i32 %x, -100
+    // OPT: %2 = icmp ule i32 %x, 100
+    // OPT: %3 = or i1 %1, %2
+    // OPT: call void @llvm.assume(i1 %3)
+    // DBG-NOT: icmp
+    // DBG-NOT: assume
+    // CHECK: ret i32 %x
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_enum_to_char(
+#[no_mangle]
+pub unsafe fn check_enum_to_char(x: Minus100ToPlus100) -> char {
+    // OPT: %0 = icmp uge i32 %x, -100
+    // OPT: %1 = icmp ule i32 %x, 100
+    // OPT: %2 = or i1 %0, %1
+    // OPT: call void @llvm.assume(i1 %2)
+    // OPT: %3 = icmp ule i32 %x, 1114111
+    // OPT: call void @llvm.assume(i1 %3)
+    // DBG-NOT: icmp
+    // DBG-NOT: assume
+    // CHECK: ret i32 %x
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_swap_pair(
+#[no_mangle]
+pub unsafe fn check_swap_pair(x: (char, NonZeroU32)) -> (NonZeroU32, char) {
+    // OPT: %0 = icmp ule i32 %x.0, 1114111
+    // OPT: call void @llvm.assume(i1 %0)
+    // OPT: %1 = icmp uge i32 %x.0, 1
+    // OPT: call void @llvm.assume(i1 %1)
+    // OPT: %2 = icmp uge i32 %x.1, 1
+    // OPT: call void @llvm.assume(i1 %2)
+    // OPT: %3 = icmp ule i32 %x.1, 1114111
+    // OPT: call void @llvm.assume(i1 %3)
+    // DBG-NOT: icmp
+    // DBG-NOT: assume
+    // CHECK: %[[P1:.+]] = insertvalue { i32, i32 } poison, i32 %x.0, 0
+    // CHECK: %[[P2:.+]] = insertvalue { i32, i32 } %[[P1]], i32 %x.1, 1
+    // CHECK: ret { i32, i32 } %[[P2]]
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_bool_from_ordering(
+#[no_mangle]
+pub unsafe fn check_bool_from_ordering(x: std::cmp::Ordering) -> bool {
+    // OPT: %0 = icmp uge i8 %x, -1
+    // OPT: %1 = icmp ule i8 %x, 1
+    // OPT: %2 = or i1 %0, %1
+    // OPT: call void @llvm.assume(i1 %2)
+    // OPT: %3 = icmp ule i8 %x, 1
+    // OPT: call void @llvm.assume(i1 %3)
+    // DBG-NOT: icmp
+    // DBG-NOT: assume
+    // CHECK: %[[R:.+]] = trunc i8 %x to i1
+    // CHECK: ret i1 %[[R]]
+
+    transmute(x)
+}
+
+// CHECK-LABEL: @check_bool_to_ordering(
+#[no_mangle]
+pub unsafe fn check_bool_to_ordering(x: bool) -> std::cmp::Ordering {
+    // CHECK: %0 = zext i1 %x to i8
+    // OPT: %1 = icmp ule i8 %0, 1
+    // OPT: call void @llvm.assume(i1 %1)
+    // OPT: %2 = icmp uge i8 %0, -1
+    // OPT: %3 = icmp ule i8 %0, 1
+    // OPT: %4 = or i1 %2, %3
+    // OPT: call void @llvm.assume(i1 %4)
+    // DBG-NOT: icmp
+    // DBG-NOT: assume
+    // CHECK: ret i8 %0
+
+    transmute(x)
+}
diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs
index 57f901c6719..51c000b82ea 100644
--- a/tests/codegen/intrinsics/transmute.rs
+++ b/tests/codegen/intrinsics/transmute.rs
@@ -169,8 +169,8 @@ pub unsafe fn check_aggregate_from_bool(x: bool) -> Aggregate8 {
 #[no_mangle]
 pub unsafe fn check_byte_to_bool(x: u8) -> bool {
     // CHECK-NOT: alloca
-    // CHECK: %0 = trunc i8 %x to i1
-    // CHECK: ret i1 %0
+    // CHECK: %[[R:.+]] = trunc i8 %x to i1
+    // CHECK: ret i1 %[[R]]
     transmute(x)
 }
 
@@ -178,8 +178,8 @@ pub unsafe fn check_byte_to_bool(x: u8) -> bool {
 #[no_mangle]
 pub unsafe fn check_byte_from_bool(x: bool) -> u8 {
     // CHECK-NOT: alloca
-    // CHECK: %0 = zext i1 %x to i8
-    // CHECK: ret i8 %0
+    // CHECK: %[[R:.+]] = zext i1 %x to i8
+    // CHECK: ret i8 %[[R:.+]]
     transmute(x)
 }
 
diff --git a/tests/codegen/transmute-optimized.rs b/tests/codegen/transmute-optimized.rs
new file mode 100644
index 00000000000..461dd550cd7
--- /dev/null
+++ b/tests/codegen/transmute-optimized.rs
@@ -0,0 +1,109 @@
+// compile-flags: -O -Z merge-functions=disabled
+// min-llvm-version: 15.0 # this test uses `ptr`s
+// ignore-debug
+
+#![crate_type = "lib"]
+
+// This tests that LLVM can optimize based on the niches in the source or
+// destination types for transmutes.
+
+#[repr(u32)]
+pub enum AlwaysZero32 { X = 0 }
+
+// CHECK-LABEL: i32 @issue_109958(i32
+#[no_mangle]
+pub fn issue_109958(x: AlwaysZero32) -> i32 {
+    // CHECK: ret i32 0
+    unsafe { std::mem::transmute(x) }
+}
+
+// CHECK-LABEL: i1 @reference_is_null(ptr
+#[no_mangle]
+pub fn reference_is_null(x: &i32) -> bool {
+    // CHECK: ret i1 false
+    let p: *const i32 = unsafe { std::mem::transmute(x) };
+    p.is_null()
+}
+
+// CHECK-LABEL: i1 @non_null_is_null(ptr
+#[no_mangle]
+pub fn non_null_is_null(x: std::ptr::NonNull<i32>) -> bool {
+    // CHECK: ret i1 false
+    let p: *const i32 = unsafe { std::mem::transmute(x) };
+    p.is_null()
+}
+
+// CHECK-LABEL: i1 @non_zero_is_null(
+#[no_mangle]
+pub fn non_zero_is_null(x: std::num::NonZeroUsize) -> bool {
+    // CHECK: ret i1 false
+    let p: *const i32 = unsafe { std::mem::transmute(x) };
+    p.is_null()
+}
+
+// CHECK-LABEL: i1 @non_null_is_zero(ptr
+#[no_mangle]
+pub fn non_null_is_zero(x: std::ptr::NonNull<i32>) -> bool {
+    // CHECK: ret i1 false
+    let a: isize = unsafe { std::mem::transmute(x) };
+    a == 0
+}
+
+// CHECK-LABEL: i1 @bool_ordering_is_ge(i1
+#[no_mangle]
+pub fn bool_ordering_is_ge(x: bool) -> bool {
+    // CHECK: ret i1 true
+    let y: std::cmp::Ordering = unsafe { std::mem::transmute(x) };
+    y.is_ge()
+}
+
+// CHECK-LABEL: i1 @ordering_is_ge_then_transmute_to_bool(i8
+#[no_mangle]
+pub fn ordering_is_ge_then_transmute_to_bool(x: std::cmp::Ordering) -> bool {
+    let r = x.is_ge();
+    let _: bool = unsafe { std::mem::transmute(x) };
+    r
+}
+
+// CHECK-LABEL: i32 @normal_div(i32
+#[no_mangle]
+pub fn normal_div(a: u32, b: u32) -> u32 {
+    // CHECK: call core::panicking::panic
+    a / b
+}
+
+// CHECK-LABEL: i32 @div_transmute_nonzero(i32
+#[no_mangle]
+pub fn div_transmute_nonzero(a: u32, b: std::num::NonZeroI32) -> u32 {
+    // CHECK-NOT: call core::panicking::panic
+    // CHECK: %[[R:.+]] = udiv i32 %a, %b
+    // CHECK-NEXT: ret i32 %[[R]]
+    // CHECK-NOT: call core::panicking::panic
+    let d: u32 = unsafe { std::mem::transmute(b) };
+    a / d
+}
+
+#[repr(i8)]
+pub enum OneTwoThree { One = 1, Two = 2, Three = 3 }
+
+// CHECK-LABEL: i8 @ordering_transmute_onetwothree(i8
+#[no_mangle]
+pub unsafe fn ordering_transmute_onetwothree(x: std::cmp::Ordering) -> OneTwoThree {
+    // CHECK: ret i8 1
+    std::mem::transmute(x)
+}
+
+// CHECK-LABEL: i8 @onetwothree_transmute_ordering(i8
+#[no_mangle]
+pub unsafe fn onetwothree_transmute_ordering(x: OneTwoThree) -> std::cmp::Ordering {
+    // CHECK: ret i8 1
+    std::mem::transmute(x)
+}
+
+// CHECK-LABEL: i1 @char_is_negative(i32
+#[no_mangle]
+pub fn char_is_negative(c: char) -> bool {
+    // CHECK: ret i1 false
+    let x: i32 = unsafe { std::mem::transmute(c) };
+    x < 0
+}
diff --git a/tests/codegen/transmute-scalar.rs b/tests/codegen/transmute-scalar.rs
index af2cef472ec..a0894a505c7 100644
--- a/tests/codegen/transmute-scalar.rs
+++ b/tests/codegen/transmute-scalar.rs
@@ -1,4 +1,4 @@
-// compile-flags: -O -C no-prepopulate-passes
+// compile-flags: -C opt-level=0 -C no-prepopulate-passes
 // min-llvm-version: 15.0 # this test assumes `ptr`s and thus no `pointercast`s
 
 #![crate_type = "lib"]
@@ -10,7 +10,7 @@
 // However, `bitcast`s and `ptrtoint`s and `inttoptr`s are still worth doing when
 // that allows us to avoid the `alloca`s entirely; see `rvalue_creates_operand`.
 
-// CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float noundef %x)
+// CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float %x)
 // CHECK: %0 = bitcast float %x to i32
 // CHECK-NEXT: ret i32 %0
 #[no_mangle]
@@ -18,7 +18,7 @@ pub fn f32_to_bits(x: f32) -> u32 {
     unsafe { std::mem::transmute(x) }
 }
 
-// CHECK-LABEL: define{{.*}}i8 @bool_to_byte(i1 noundef zeroext %b)
+// CHECK-LABEL: define{{.*}}i8 @bool_to_byte(i1 zeroext %b)
 // CHECK: %0 = zext i1 %b to i8
 // CHECK-NEXT: ret i8 %0
 #[no_mangle]
@@ -26,7 +26,7 @@ pub fn bool_to_byte(b: bool) -> u8 {
     unsafe { std::mem::transmute(b) }
 }
 
-// CHECK-LABEL: define{{.*}}noundef zeroext i1 @byte_to_bool(i8 noundef %byte)
+// CHECK-LABEL: define{{.*}}zeroext i1 @byte_to_bool(i8 %byte)
 // CHECK: %0 = trunc i8 %byte to i1
 // CHECK-NEXT: ret i1 %0
 #[no_mangle]
@@ -34,14 +34,14 @@ pub unsafe fn byte_to_bool(byte: u8) -> bool {
     std::mem::transmute(byte)
 }
 
-// CHECK-LABEL: define{{.*}}ptr @ptr_to_ptr(ptr noundef %p)
+// CHECK-LABEL: define{{.*}}ptr @ptr_to_ptr(ptr %p)
 // CHECK: ret ptr %p
 #[no_mangle]
 pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 {
     unsafe { std::mem::transmute(p) }
 }
 
-// CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int(ptr noundef %p)
+// CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int(ptr %p)
 // CHECK: %0 = ptrtoint ptr %p to [[USIZE]]
 // CHECK-NEXT: ret [[USIZE]] %0
 #[no_mangle]
@@ -49,7 +49,7 @@ pub fn ptr_to_int(p: *mut u16) -> usize {
     unsafe { std::mem::transmute(p) }
 }
 
-// CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] noundef %i)
+// CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] %i)
 // CHECK: %0 = inttoptr [[USIZE]] %i to ptr
 // CHECK-NEXT: ret ptr %0
 #[no_mangle]
diff --git a/tests/incremental/const-generics/change-const-param-gat.rs b/tests/incremental/const-generics/change-const-param-gat.rs
new file mode 100644
index 00000000000..f1449d5681e
--- /dev/null
+++ b/tests/incremental/const-generics/change-const-param-gat.rs
@@ -0,0 +1,29 @@
+// revisions: rpass1 rpass2 rpass3
+// compile-flags: -Zincremental-ignore-spans
+#![feature(generic_associated_types)]
+
+// This test unsures that with_opt_const_param returns the
+// def_id of the N param in the Foo::Assoc GAT.
+
+trait Foo {
+    type Assoc<const N: usize>;
+    fn foo(
+        &self,
+    ) -> Self::Assoc<{ if cfg!(rpass2) { 3 } else { 2 } }>;
+}
+
+impl Foo for () {
+    type Assoc<const N: usize> = [(); N];
+    fn foo(
+        &self,
+    ) -> Self::Assoc<{ if cfg!(rpass2) { 3 } else { 2 } }> {
+        [(); { if cfg!(rpass2) { 3 } else { 2 } }]
+    }
+}
+
+fn main() {
+    assert_eq!(
+        ().foo(),
+        [(); { if cfg!(rpass2) { 3 } else { 2 } }]
+    );
+}
diff --git a/tests/incremental/const-generics/change-const-param-type.rs b/tests/incremental/const-generics/change-const-param-type.rs
new file mode 100644
index 00000000000..1aac1bc7d72
--- /dev/null
+++ b/tests/incremental/const-generics/change-const-param-type.rs
@@ -0,0 +1,68 @@
+// revisions: rpass1 rpass2 rpass3
+// compile-flags: -Zincremental-ignore-spans
+
+enum Foo<const N: usize> {
+    Variant,
+    Variant2(),
+    Variant3 {},
+}
+
+impl Foo<1> {
+    fn foo<const N: usize>(&self) -> [(); N] { [(); N] }
+}
+
+impl Foo<2> {
+    fn foo<const N: u32>(self) -> usize { N as usize }
+}
+
+struct Bar<const N: usize>;
+struct Bar2<const N: usize>();
+struct Bar3<const N: usize> {}
+
+#[cfg(rpass1)]
+struct ChangingStruct<const N: usize>;
+
+#[cfg(any(rpass2, rpass3))]
+struct ChangingStruct<const N: u32>;
+
+struct S;
+
+impl S {
+    #[cfg(rpass1)]
+    fn changing_method<const N: usize>(self) {}
+
+    #[cfg(any(rpass2, rpass3))]
+    fn changing_method<const N: u32>(self) {}
+}
+
+// We want to verify that all goes well when the value of the const argument change.
+// To avoid modifying `main`'s HIR, we use a separate constant, and use `{ FOO_ARG + 1 }`
+// inside the body to keep having an `AnonConst` to compute.
+const FOO_ARG: usize = if cfg!(rpass2) { 1 } else { 0 };
+
+fn main() {
+    let foo = Foo::Variant::<{ FOO_ARG + 1 }>;
+    foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>();
+
+    let foo = Foo::Variant2::<{ FOO_ARG + 1 }>();
+    foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>();
+
+    let foo = Foo::Variant3::<{ FOO_ARG + 1 }> {};
+    foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>();
+
+    let foo = Foo::<{ FOO_ARG + 1 }>::Variant;
+    foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>();
+
+    let foo = Foo::<{ FOO_ARG + 1 }>::Variant2();
+    foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>();
+
+    let foo = Foo::<{ FOO_ARG + 1 }>::Variant3 {};
+    foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>();
+
+    let _ = Bar::<{ FOO_ARG + 1 }>;
+    let _ = Bar2::<{ FOO_ARG + 1 }>();
+    let _ = Bar3::<{ FOO_ARG + 1 }> {};
+
+    let _ = ChangingStruct::<{ 5 }>;
+    let _ = S.changing_method::<{ 5 }>();
+}
diff --git a/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff
new file mode 100644
index 00000000000..4e2f1b39d2b
--- /dev/null
+++ b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff
@@ -0,0 +1,43 @@
+- // MIR for `concrete` before ConstProp
++ // MIR for `concrete` after ConstProp
+  
+  fn concrete() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/offset_of.rs:+0:15: +0:15
+      let _1: usize;                       // in scope 0 at $DIR/offset_of.rs:+1:9: +1:10
+      scope 1 {
+          debug x => _1;                   // in scope 1 at $DIR/offset_of.rs:+1:9: +1:10
+          let _2: usize;                   // in scope 1 at $DIR/offset_of.rs:+2:9: +2:10
+          scope 2 {
+              debug y => _2;               // in scope 2 at $DIR/offset_of.rs:+2:9: +2:10
+              let _3: usize;               // in scope 2 at $DIR/offset_of.rs:+3:9: +3:11
+              scope 3 {
+                  debug z0 => _3;          // in scope 3 at $DIR/offset_of.rs:+3:9: +3:11
+                  let _4: usize;           // in scope 3 at $DIR/offset_of.rs:+4:9: +4:11
+                  scope 4 {
+                      debug z1 => _4;      // in scope 4 at $DIR/offset_of.rs:+4:9: +4:11
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/offset_of.rs:+1:9: +1:10
+-         _1 = OffsetOf(Alpha, [0]);       // scope 0 at $DIR/offset_of.rs:+1:13: +1:33
++         _1 = const 4_usize;              // scope 0 at $DIR/offset_of.rs:+1:13: +1:33
+          StorageLive(_2);                 // scope 1 at $DIR/offset_of.rs:+2:9: +2:10
+-         _2 = OffsetOf(Alpha, [1]);       // scope 1 at $DIR/offset_of.rs:+2:13: +2:33
++         _2 = const 0_usize;              // scope 1 at $DIR/offset_of.rs:+2:13: +2:33
+          StorageLive(_3);                 // scope 2 at $DIR/offset_of.rs:+3:9: +3:11
+-         _3 = OffsetOf(Alpha, [2, 0]);    // scope 2 at $DIR/offset_of.rs:+3:14: +3:36
++         _3 = const 2_usize;              // scope 2 at $DIR/offset_of.rs:+3:14: +3:36
+          StorageLive(_4);                 // scope 3 at $DIR/offset_of.rs:+4:9: +4:11
+-         _4 = OffsetOf(Alpha, [2, 1]);    // scope 3 at $DIR/offset_of.rs:+4:14: +4:36
++         _4 = const 3_usize;              // scope 3 at $DIR/offset_of.rs:+4:14: +4:36
+          StorageDead(_4);                 // scope 3 at $DIR/offset_of.rs:+5:1: +5:2
+          StorageDead(_3);                 // scope 2 at $DIR/offset_of.rs:+5:1: +5:2
+          StorageDead(_2);                 // scope 1 at $DIR/offset_of.rs:+5:1: +5:2
+          StorageDead(_1);                 // scope 0 at $DIR/offset_of.rs:+5:1: +5:2
+          return;                          // scope 0 at $DIR/offset_of.rs:+5:2: +5:2
+      }
+  }
+  
diff --git a/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff
new file mode 100644
index 00000000000..5c6cb47089e
--- /dev/null
+++ b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff
@@ -0,0 +1,39 @@
+- // MIR for `generic` before ConstProp
++ // MIR for `generic` after ConstProp
+  
+  fn generic() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/offset_of.rs:+0:17: +0:17
+      let _1: usize;                       // in scope 0 at $DIR/offset_of.rs:+1:9: +1:11
+      scope 1 {
+          debug gx => _1;                  // in scope 1 at $DIR/offset_of.rs:+1:9: +1:11
+          let _2: usize;                   // in scope 1 at $DIR/offset_of.rs:+2:9: +2:11
+          scope 2 {
+              debug gy => _2;              // in scope 2 at $DIR/offset_of.rs:+2:9: +2:11
+              let _3: usize;               // in scope 2 at $DIR/offset_of.rs:+3:9: +3:11
+              scope 3 {
+                  debug dx => _3;          // in scope 3 at $DIR/offset_of.rs:+3:9: +3:11
+                  let _4: usize;           // in scope 3 at $DIR/offset_of.rs:+4:9: +4:11
+                  scope 4 {
+                      debug dy => _4;      // in scope 4 at $DIR/offset_of.rs:+4:9: +4:11
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/offset_of.rs:+1:9: +1:11
+          _1 = OffsetOf(Gamma<T>, [0]);    // scope 0 at $DIR/offset_of.rs:+1:14: +1:37
+          StorageLive(_2);                 // scope 1 at $DIR/offset_of.rs:+2:9: +2:11
+          _2 = OffsetOf(Gamma<T>, [1]);    // scope 1 at $DIR/offset_of.rs:+2:14: +2:37
+          StorageLive(_3);                 // scope 2 at $DIR/offset_of.rs:+3:9: +3:11
+          _3 = OffsetOf(Delta<T>, [1]);    // scope 2 at $DIR/offset_of.rs:+3:14: +3:37
+          StorageLive(_4);                 // scope 3 at $DIR/offset_of.rs:+4:9: +4:11
+          _4 = OffsetOf(Delta<T>, [2]);    // scope 3 at $DIR/offset_of.rs:+4:14: +4:37
+          StorageDead(_4);                 // scope 3 at $DIR/offset_of.rs:+5:1: +5:2
+          StorageDead(_3);                 // scope 2 at $DIR/offset_of.rs:+5:1: +5:2
+          StorageDead(_2);                 // scope 1 at $DIR/offset_of.rs:+5:1: +5:2
+          StorageDead(_1);                 // scope 0 at $DIR/offset_of.rs:+5:1: +5:2
+          return;                          // scope 0 at $DIR/offset_of.rs:+5:2: +5:2
+      }
+  }
+  
diff --git a/tests/mir-opt/const_prop/offset_of.rs b/tests/mir-opt/const_prop/offset_of.rs
new file mode 100644
index 00000000000..eabdf848079
--- /dev/null
+++ b/tests/mir-opt/const_prop/offset_of.rs
@@ -0,0 +1,49 @@
+// unit-test
+// compile-flags: -O
+
+#![feature(offset_of)]
+
+use std::marker::PhantomData;
+use std::mem::offset_of;
+
+struct Alpha {
+    x: u8,
+    y: u16,
+    z: Beta,
+}
+
+struct Beta(u8, u8);
+
+struct Gamma<T> {
+    x: u8,
+    y: u16,
+    _t: T,
+}
+
+#[repr(C)]
+struct Delta<T> {
+    _phantom: PhantomData<T>,
+    x: u8,
+    y: u16,
+}
+
+// EMIT_MIR offset_of.concrete.ConstProp.diff
+fn concrete() {
+    let x = offset_of!(Alpha, x);
+    let y = offset_of!(Alpha, y);
+    let z0 = offset_of!(Alpha, z.0);
+    let z1 = offset_of!(Alpha, z.1);
+}
+
+// EMIT_MIR offset_of.generic.ConstProp.diff
+fn generic<T>() {
+    let gx = offset_of!(Gamma<T>, x);
+    let gy = offset_of!(Gamma<T>, y);
+    let dx = offset_of!(Delta<T>, x);
+    let dy = offset_of!(Delta<T>, y);
+}
+
+fn main() {
+    concrete();
+    generic::<()>();
+}
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff
index 543ddcfc44c..8a8cd896e85 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff
@@ -34,7 +34,7 @@
 -                                          // + literal: Const { ty: unsafe fn(Option<T>) -> T {Option::<T>::unwrap_unchecked}, val: Value(<ZST>) }
 +         StorageLive(_3);                 // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27
 +         _4 = discriminant(_2);           // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
-+         switchInt(move _4) -> [0: bb1, 1: bb2, otherwise: bb1]; // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
++         switchInt(move _4) -> [1: bb2, otherwise: bb1]; // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL
       }
   
       bb1: {
diff --git a/tests/mir-opt/instcombine_duplicate_switch_targets_e2e.rs b/tests/mir-opt/instcombine_duplicate_switch_targets_e2e.rs
new file mode 100644
index 00000000000..09779d789e5
--- /dev/null
+++ b/tests/mir-opt/instcombine_duplicate_switch_targets_e2e.rs
@@ -0,0 +1,16 @@
+// compile-flags: -Zmir-opt-level=2 -Zinline-mir
+// ignore-debug: standard library debug assertions add a panic that breaks this optimization
+#![crate_type = "lib"]
+
+pub enum Thing {
+    A,
+    B,
+}
+
+// EMIT_MIR instcombine_duplicate_switch_targets_e2e.ub_if_b.PreCodegen.after.mir
+pub unsafe fn ub_if_b(t: Thing) -> Thing {
+    match t {
+        Thing::A => t,
+        Thing::B => std::hint::unreachable_unchecked(),
+    }
+}
diff --git a/tests/mir-opt/instcombine_duplicate_switch_targets_e2e.ub_if_b.PreCodegen.after.mir b/tests/mir-opt/instcombine_duplicate_switch_targets_e2e.ub_if_b.PreCodegen.after.mir
new file mode 100644
index 00000000000..acb7297310f
--- /dev/null
+++ b/tests/mir-opt/instcombine_duplicate_switch_targets_e2e.ub_if_b.PreCodegen.after.mir
@@ -0,0 +1,27 @@
+// MIR for `ub_if_b` after PreCodegen
+
+fn ub_if_b(_1: Thing) -> Thing {
+    debug t => _1;                       // in scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+0:23: +0:24
+    let mut _0: Thing;                   // return place in scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+0:36: +0:41
+    let mut _2: isize;                   // in scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+2:9: +2:17
+    scope 1 (inlined unreachable_unchecked) { // at $DIR/instcombine_duplicate_switch_targets_e2e.rs:14:21: 14:55
+        scope 2 {
+            scope 3 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+            }
+        }
+    }
+
+    bb0: {
+        _2 = discriminant(_1);           // scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+1:11: +1:12
+        switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+1:5: +1:12
+    }
+
+    bb1: {
+        unreachable;                     // scope 2 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+    }
+
+    bb2: {
+        _0 = move _1;                    // scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+2:21: +2:22
+        return;                          // scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+5:2: +5:2
+    }
+}
diff --git a/tests/mir-opt/issue_99325.main.built.after.mir b/tests/mir-opt/issue_99325.main.built.after.mir
index 2324f53566c..f0c9ef419bd 100644
--- a/tests/mir-opt/issue_99325.main.built.after.mir
+++ b/tests/mir-opt/issue_99325.main.built.after.mir
@@ -2,7 +2,7 @@
 
 | User Type Annotations
 | 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::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 }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
-| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[22bb]::function_with_bytes::BYTES)) }, substs: [] }) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), substs: [] }) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
 |
 fn main() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/issue_99325.rs:+0:15: +0:15
diff --git a/tests/run-make-fulldeps/obtain-borrowck/driver.rs b/tests/run-make-fulldeps/obtain-borrowck/driver.rs
index 9cd504f004d..7bd7bb7c1ea 100644
--- a/tests/run-make-fulldeps/obtain-borrowck/driver.rs
+++ b/tests/run-make-fulldeps/obtain-borrowck/driver.rs
@@ -20,13 +20,13 @@ extern crate rustc_session;
 
 use rustc_borrowck::consumers::BodyWithBorrowckFacts;
 use rustc_driver::Compilation;
-use rustc_hir::def_id::LocalDefId;
 use rustc_hir::def::DefKind;
+use rustc_hir::def_id::LocalDefId;
 use rustc_interface::interface::Compiler;
 use rustc_interface::{Config, Queries};
 use rustc_middle::ty::query::query_values::mir_borrowck;
 use rustc_middle::ty::query::{ExternProviders, Providers};
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
 use std::cell::RefCell;
 use std::collections::HashMap;
@@ -127,10 +127,7 @@ thread_local! {
 }
 
 fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> mir_borrowck<'tcx> {
-    let body_with_facts = rustc_borrowck::consumers::get_body_with_borrowck_facts(
-        tcx,
-        ty::WithOptConstParam::unknown(def_id),
-    );
+    let body_with_facts = rustc_borrowck::consumers::get_body_with_borrowck_facts(tcx, def_id);
     // SAFETY: The reader casts the 'static lifetime to 'tcx before using it.
     let body_with_facts: BodyWithBorrowckFacts<'static> =
         unsafe { std::mem::transmute(body_with_facts) };
diff --git a/tests/run-make/const-prop-lint/Makefile b/tests/run-make/const-prop-lint/Makefile
new file mode 100644
index 00000000000..f29f282f787
--- /dev/null
+++ b/tests/run-make/const-prop-lint/Makefile
@@ -0,0 +1,9 @@
+include ../tools.mk
+
+# Test that emitting an error because of arithmetic
+# overflow lint does not leave .o files around
+# because of interrupted codegen.
+
+all:
+	$(RUSTC) input.rs; test $$? -eq 1
+	ls *.o; test $$? -ne 0
diff --git a/tests/run-make/const-prop-lint/input.rs b/tests/run-make/const-prop-lint/input.rs
new file mode 100644
index 00000000000..ccbdfb8d50b
--- /dev/null
+++ b/tests/run-make/const-prop-lint/input.rs
@@ -0,0 +1,5 @@
+#![deny(arithmetic_overflow)]
+
+fn main() {
+    let x = 255u8 + 1;
+}
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.generics.txt b/tests/run-make/coverage-reports/expected_show_coverage.generics.txt
index 48983ba4358..7eb33a29a92 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.generics.txt
+++ b/tests/run-make/coverage-reports/expected_show_coverage.generics.txt
@@ -11,16 +11,16 @@
    11|      3|        self.strength = new_strength;
    12|      3|    }
   ------------------
-  | <generics::Firework<i32>>::set_strength:
-  |   10|      1|    fn set_strength(&mut self, new_strength: T) {
-  |   11|      1|        self.strength = new_strength;
-  |   12|      1|    }
-  ------------------
   | <generics::Firework<f64>>::set_strength:
   |   10|      2|    fn set_strength(&mut self, new_strength: T) {
   |   11|      2|        self.strength = new_strength;
   |   12|      2|    }
   ------------------
+  | <generics::Firework<i32>>::set_strength:
+  |   10|      1|    fn set_strength(&mut self, new_strength: T) {
+  |   11|      1|        self.strength = new_strength;
+  |   12|      1|    }
+  ------------------
    13|       |}
    14|       |
    15|       |impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display {
diff --git a/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs
new file mode 100644
index 00000000000..ef9c56f7592
--- /dev/null
+++ b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs
@@ -0,0 +1,6 @@
+// this test used to ICE
+#![deny(rustdoc::broken_intra_doc_links)]
+//! [Clone ()]. //~ ERROR unresolved
+//! [Clone !]. //~ ERROR incompatible
+//! [`Clone ()`]. //~ ERROR unresolved
+//! [`Clone !`]. //~ ERROR incompatible
diff --git a/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr
new file mode 100644
index 00000000000..8669b0c2086
--- /dev/null
+++ b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr
@@ -0,0 +1,54 @@
+error: unresolved link to `Clone`
+  --> $DIR/issue-110495-suffix-with-space.rs:3:6
+   |
+LL | //! [Clone ()].
+   |      ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
+   |
+note: the lint level is defined here
+  --> $DIR/issue-110495-suffix-with-space.rs:2:9
+   |
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: to link to the trait, prefix with `trait@`
+   |
+LL - //! [Clone ()].
+LL + //! [trait@Clone ].
+   |
+
+error: incompatible link kind for `Clone`
+  --> $DIR/issue-110495-suffix-with-space.rs:4:6
+   |
+LL | //! [Clone !].
+   |      ^^^^^^^ this link resolved to a derive macro, which is not a macro
+   |
+help: to link to the derive macro, prefix with `derive@`
+   |
+LL - //! [Clone !].
+LL + //! [derive@Clone ].
+   |
+
+error: unresolved link to `Clone`
+  --> $DIR/issue-110495-suffix-with-space.rs:5:7
+   |
+LL | //! [`Clone ()`].
+   |       ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
+   |
+help: to link to the trait, prefix with `trait@`
+   |
+LL - //! [`Clone ()`].
+LL + //! [`trait@Clone (`].
+   |
+
+error: incompatible link kind for `Clone`
+  --> $DIR/issue-110495-suffix-with-space.rs:6:7
+   |
+LL | //! [`Clone !`].
+   |       ^^^^^^^ this link resolved to a derive macro, which is not a macro
+   |
+help: to link to the derive macro, prefix with `derive@`
+   |
+LL | //! [`derive@Clone !`].
+   |       +++++++
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs b/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs
new file mode 100644
index 00000000000..d8953eaf597
--- /dev/null
+++ b/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs
@@ -0,0 +1,24 @@
+// This is a regression test for <https://github.com/rust-lang/rust/issues/46506>.
+// This test ensures that if public re-exported is re-exported, it won't be inlined.
+
+#![crate_name = "foo"]
+
+// @has 'foo/associations/index.html'
+// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
+// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits'
+// @has - '//*[@id="main-content"]//a[@href="trait.GroupedBy.html"]' 'GroupedBy'
+// @has 'foo/associations/trait.GroupedBy.html'
+pub mod associations {
+    mod belongs_to {
+        pub trait GroupedBy {}
+    }
+    pub use self::belongs_to::GroupedBy;
+}
+
+// @has 'foo/prelude/index.html'
+// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
+// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports'
+// @has - '//*[@id="main-content"]//*[@id="reexport.GroupedBy"]' 'pub use associations::GroupedBy;'
+pub mod prelude {
+    pub use associations::GroupedBy;
+}
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index dfde8c97ec2..95f27efa771 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -33,7 +33,6 @@ fn test_stable_mir(tcx: TyCtxt<'_>) {
 
     // Find items in the local crate.
     let items = stable_mir::all_local_items();
-    assert!(get_item(tcx, &items, (DefKind::Fn, "foo_bar")).is_some());
     assert!(get_item(tcx, &items, (DefKind::Fn, "foo::bar")).is_some());
 
     // Find the `std` crate.
@@ -52,6 +51,15 @@ fn test_stable_mir(tcx: TyCtxt<'_>) {
         stable_mir::mir::Terminator::Return => {}
         other => panic!("{other:?}"),
     }
+
+    let foo_bar = get_item(tcx, &items, (DefKind::Fn, "foo_bar")).unwrap();
+    let body = foo_bar.body();
+    assert_eq!(body.blocks.len(), 4);
+    let block = &body.blocks[0];
+    match &block.terminator {
+        stable_mir::mir::Terminator::Call { .. } => {}
+        other => panic!("{other:?}"),
+    }
 }
 
 // Use internal API to find a function in a crate.
diff --git a/tests/ui/issues/issue-27901.rs b/tests/ui/associated-types/issue-27901.rs
index ffd90b68983..ffd90b68983 100644
--- a/tests/ui/issues/issue-27901.rs
+++ b/tests/ui/associated-types/issue-27901.rs
diff --git a/tests/ui/async-await/feature-self-return-type.stderr b/tests/ui/async-await/feature-self-return-type.stderr
index 8924683684f..747c54b6694 100644
--- a/tests/ui/async-await/feature-self-return-type.stderr
+++ b/tests/ui/async-await/feature-self-return-type.stderr
@@ -4,6 +4,7 @@ error[E0597]: `bar` does not live long enough
 LL |     let x = {
    |         - borrow later stored here
 LL |         let bar = 22;
+   |             --- binding `bar` declared here
 LL |         Foo::new(&bar).await
    |                  ^^^^ borrowed value does not live long enough
 LL |
diff --git a/tests/ui/async-await/issue-61949-self-return-type.stderr b/tests/ui/async-await/issue-61949-self-return-type.stderr
index 638b197bc02..ac85ed2887a 100644
--- a/tests/ui/async-await/issue-61949-self-return-type.stderr
+++ b/tests/ui/async-await/issue-61949-self-return-type.stderr
@@ -13,6 +13,7 @@ error[E0597]: `bar` does not live long enough
 LL |     let x = {
    |         - borrow later stored here
 LL |         let bar = 22;
+   |             --- binding `bar` declared here
 LL |         Foo::new(&bar).await
    |                  ^^^^ borrowed value does not live long enough
 LL |
diff --git a/tests/ui/async-await/issue-74047.stderr b/tests/ui/async-await/issue-74047.stderr
index 28174825d8b..6bdb9ded482 100644
--- a/tests/ui/async-await/issue-74047.stderr
+++ b/tests/ui/async-await/issue-74047.stderr
@@ -4,8 +4,8 @@ error[E0046]: not all trait items implemented, missing: `Error`, `try_from`
 LL | impl TryFrom<OtherStream> for MyStream {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Error`, `try_from` in implementation
    |
-   = help: implement the missing item: `type Error = Type;`
-   = help: implement the missing item: `fn try_from(_: T) -> Result<Self, <Self as TryFrom<T>>::Error> { todo!() }`
+   = help: implement the missing item: `type Error = /* Type */;`
+   = help: implement the missing item: `fn try_from(_: OtherStream) -> Result<Self, <Self as TryFrom<OtherStream>>::Error> { todo!() }`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/borrowck/issue-109271-pass-self-into-closure.fixed b/tests/ui/borrowck/issue-109271-pass-self-into-closure.fixed
new file mode 100644
index 00000000000..4a8831dab95
--- /dev/null
+++ b/tests/ui/borrowck/issue-109271-pass-self-into-closure.fixed
@@ -0,0 +1,39 @@
+// run-rustfix
+#![allow(unused)]
+struct S;
+
+impl S {
+    fn call(&mut self, f: impl FnOnce((), &mut Self)) {
+        // change state or something ...
+        f((), self);
+        // change state or something ...
+    }
+
+    fn get(&self) {}
+    fn set(&mut self) {}
+}
+
+fn main() {
+    let mut v = S;
+
+    v.call(|(), this: &mut S| this.get());
+    //~^ error: cannot borrow `v` as mutable because it is also borrowed as immutable
+    v.call(|(), this: &mut S| this.set());
+    //~^ error: cannot borrow `v` as mutable more than once at a time
+    //~| error: cannot borrow `v` as mutable more than once at a time
+
+    v.call(|(), this: &mut S| {
+        //~^ error: cannot borrow `v` as mutable more than once at a time
+        //~| error: cannot borrow `v` as mutable more than once at a time
+
+        _ = this;
+        this.set();
+        this.get();
+        S::get(&this);
+
+        use std::ops::Add;
+        let v = 0u32;
+        _ = v + v;
+        _ = v.add(3);
+    });
+}
diff --git a/tests/ui/borrowck/issue-109271-pass-self-into-closure.rs b/tests/ui/borrowck/issue-109271-pass-self-into-closure.rs
new file mode 100644
index 00000000000..fcd855f862d
--- /dev/null
+++ b/tests/ui/borrowck/issue-109271-pass-self-into-closure.rs
@@ -0,0 +1,39 @@
+// run-rustfix
+#![allow(unused)]
+struct S;
+
+impl S {
+    fn call(&mut self, f: impl FnOnce((), &mut Self)) {
+        // change state or something ...
+        f((), self);
+        // change state or something ...
+    }
+
+    fn get(&self) {}
+    fn set(&mut self) {}
+}
+
+fn main() {
+    let mut v = S;
+
+    v.call(|(), this: &mut S| v.get());
+    //~^ error: cannot borrow `v` as mutable because it is also borrowed as immutable
+    v.call(|(), this: &mut S| v.set());
+    //~^ error: cannot borrow `v` as mutable more than once at a time
+    //~| error: cannot borrow `v` as mutable more than once at a time
+
+    v.call(|(), this: &mut S| {
+        //~^ error: cannot borrow `v` as mutable more than once at a time
+        //~| error: cannot borrow `v` as mutable more than once at a time
+
+        _ = v;
+        v.set();
+        v.get();
+        S::get(&v);
+
+        use std::ops::Add;
+        let v = 0u32;
+        _ = v + v;
+        _ = v.add(3);
+    });
+}
diff --git a/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr b/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr
new file mode 100644
index 00000000000..25974e0d008
--- /dev/null
+++ b/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr
@@ -0,0 +1,85 @@
+error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
+  --> $DIR/issue-109271-pass-self-into-closure.rs:19:5
+   |
+LL |     v.call(|(), this: &mut S| v.get());
+   |     ^^----^------------------^-^^^^^^^
+   |     | |    |                  |
+   |     | |    |                  first borrow occurs due to use of `v` in closure
+   |     | |    |                  help: try using the closure argument: `this`
+   |     | |    immutable borrow occurs here
+   |     | immutable borrow later used by call
+   |     mutable borrow occurs here
+
+error[E0499]: cannot borrow `v` as mutable more than once at a time
+  --> $DIR/issue-109271-pass-self-into-closure.rs:21:5
+   |
+LL |     v.call(|(), this: &mut S| v.set());
+   |     ^^----^------------------^-^^^^^^^
+   |     | |    |                  |
+   |     | |    |                  first borrow occurs due to use of `v` in closure
+   |     | |    |                  help: try using the closure argument: `this`
+   |     | |    first mutable borrow occurs here
+   |     | first borrow later used by call
+   |     second mutable borrow occurs here
+
+error[E0499]: cannot borrow `v` as mutable more than once at a time
+  --> $DIR/issue-109271-pass-self-into-closure.rs:21:12
+   |
+LL |     v.call(|(), this: &mut S| v.set());
+   |     -------^^^^^^^^^^^^^^^^^^---------
+   |     | |    |                  |
+   |     | |    |                  second borrow occurs due to use of `v` in closure
+   |     | |    second mutable borrow occurs here
+   |     | first borrow later used by call
+   |     first mutable borrow occurs here
+
+error[E0499]: cannot borrow `v` as mutable more than once at a time
+  --> $DIR/issue-109271-pass-self-into-closure.rs:25:5
+   |
+LL |       v.call(|(), this: &mut S| {
+   |       ^ ---- ------------------ first mutable borrow occurs here
+   |       | |
+   |  _____| first borrow later used by call
+   | |
+LL | |
+LL | |
+LL | |
+LL | |         _ = v;
+LL | |         v.set();
+   | |         - first borrow occurs due to use of `v` in closure
+...  |
+LL | |         _ = v.add(3);
+LL | |     });
+   | |______^ second mutable borrow occurs here
+   |
+help: try using the closure argument
+   |
+LL ~         _ = this;
+LL ~         this.set();
+LL ~         this.get();
+LL ~         S::get(&this);
+   |
+
+error[E0499]: cannot borrow `v` as mutable more than once at a time
+  --> $DIR/issue-109271-pass-self-into-closure.rs:25:12
+   |
+LL |       v.call(|(), this: &mut S| {
+   |       - ---- ^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
+   |       | |
+   |  _____| first borrow later used by call
+   | |
+LL | |
+LL | |
+LL | |
+LL | |         _ = v;
+LL | |         v.set();
+   | |         - second borrow occurs due to use of `v` in closure
+...  |
+LL | |         _ = v.add(3);
+LL | |     });
+   | |______- first mutable borrow occurs here
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0499, E0502.
+For more information about an error, try `rustc --explain E0499`.
diff --git a/tests/ui/issues/issue-47646.rs b/tests/ui/borrowck/issue-47646.rs
index ace6cdce841..ace6cdce841 100644
--- a/tests/ui/issues/issue-47646.rs
+++ b/tests/ui/borrowck/issue-47646.rs
diff --git a/tests/ui/issues/issue-47646.stderr b/tests/ui/borrowck/issue-47646.stderr
index 84cf9237a56..84cf9237a56 100644
--- a/tests/ui/issues/issue-47646.stderr
+++ b/tests/ui/borrowck/issue-47646.stderr
diff --git a/tests/ui/chalkify/bugs/async.stderr b/tests/ui/chalkify/bugs/async.stderr
index 36606fd49f2..7e64e67f24c 100644
--- a/tests/ui/chalkify/bugs/async.stderr
+++ b/tests/ui/chalkify/bugs/async.stderr
@@ -18,7 +18,7 @@ LL | async fn foo(x: u32) -> u32 {
 #3 [mir_built] building MIR for `foo`
 #4 [unsafety_check_result] unsafety-checking `foo`
 #5 [mir_const] preparing `foo` for borrow checking
-#6 [mir_promoted] processing MIR for `foo`
+#6 [mir_promoted] promoting constants in MIR for `foo`
 #7 [mir_borrowck] borrow-checking `foo`
 #8 [type_of] computing type of `foo::{opaque#0}`
 #9 [check_mod_item_types] checking item types in top-level module
diff --git a/tests/ui/consts/auxiliary/foreign-generic-mismatch-with-const-arg.rs b/tests/ui/consts/auxiliary/foreign-generic-mismatch-with-const-arg.rs
deleted file mode 100644
index 85b0c6c9df8..00000000000
--- a/tests/ui/consts/auxiliary/foreign-generic-mismatch-with-const-arg.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub fn test<const N: usize, T>() {}
diff --git a/tests/ui/consts/const-eval/generic-slice.stderr b/tests/ui/consts/const-eval/generic-slice.stderr
index c38088df4d8..ff1dc29ccfd 100644
--- a/tests/ui/consts/const-eval/generic-slice.stderr
+++ b/tests/ui/consts/const-eval/generic-slice.stderr
@@ -4,6 +4,8 @@ error[E0597]: `x` does not live long enough
 LL | impl<'a, T: 'static> Generic<'a, T> {
    |      -- lifetime `'a` defined here
 ...
+LL |         let x: &'static [T] = &[];
+   |             - binding `x` declared here
 LL |         &x
    |         ^^
    |         |
@@ -16,6 +18,8 @@ LL |     };
 error[E0597]: `x` does not live long enough
   --> $DIR/generic-slice.rs:27:5
    |
+LL |     let x: &[_] = &[];
+   |         - binding `x` declared here
 LL |     &x
    |     ^^
    |     |
diff --git a/tests/ui/consts/const-eval/issue-100878.rs b/tests/ui/consts/const-eval/issue-100878.rs
index 353ce505035..bd56f854c8b 100644
--- a/tests/ui/consts/const-eval/issue-100878.rs
+++ b/tests/ui/consts/const-eval/issue-100878.rs
@@ -1,6 +1,8 @@
 // This checks that the const-eval ICE in issue #100878 does not recur.
 //
 // build-pass
+
+#[allow(arithmetic_overflow)]
 pub fn bitshift_data(data: [u8; 1]) -> u8 {
     data[0] << 8
 }
diff --git a/tests/ui/consts/foreign-generic-mismatch-with-const-arg.rs b/tests/ui/consts/foreign-generic-mismatch-with-const-arg.rs
deleted file mode 100644
index 7590abbd827..00000000000
--- a/tests/ui/consts/foreign-generic-mismatch-with-const-arg.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// aux-build: foreign-generic-mismatch-with-const-arg.rs
-
-extern crate foreign_generic_mismatch_with_const_arg;
-
-fn main() {
-    foreign_generic_mismatch_with_const_arg::test::<1>();
-    //~^ ERROR function takes 2 generic arguments but 1 generic argument was supplied
-}
diff --git a/tests/ui/consts/foreign-generic-mismatch-with-const-arg.stderr b/tests/ui/consts/foreign-generic-mismatch-with-const-arg.stderr
deleted file mode 100644
index 4cc03a20514..00000000000
--- a/tests/ui/consts/foreign-generic-mismatch-with-const-arg.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied
-  --> $DIR/foreign-generic-mismatch-with-const-arg.rs:6:46
-   |
-LL |     foreign_generic_mismatch_with_const_arg::test::<1>();
-   |                                              ^^^^   - supplied 1 generic argument
-   |                                              |
-   |                                              expected 2 generic arguments
-   |
-note: function defined here, with 2 generic parameters: `N`, `T`
-  --> $DIR/auxiliary/foreign-generic-mismatch-with-const-arg.rs:1:8
-   |
-LL | pub fn test<const N: usize, T>() {}
-   |        ^^^^ --------------  -
-help: add missing generic argument
-   |
-LL |     foreign_generic_mismatch_with_const_arg::test::<1, T>();
-   |                                                      +++
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/issues/auxiliary/issue-41394.rs b/tests/ui/enum-discriminant/auxiliary/issue-41394.rs
index 2e650efc714..2e650efc714 100644
--- a/tests/ui/issues/auxiliary/issue-41394.rs
+++ b/tests/ui/enum-discriminant/auxiliary/issue-41394.rs
diff --git a/tests/ui/issues/issue-41394-rpass.rs b/tests/ui/enum-discriminant/issue-41394-rpass.rs
index 37c6525234d..37c6525234d 100644
--- a/tests/ui/issues/issue-41394-rpass.rs
+++ b/tests/ui/enum-discriminant/issue-41394-rpass.rs
diff --git a/tests/ui/issues/issue-41394.rs b/tests/ui/enum-discriminant/issue-41394.rs
index 07cad8796e1..07cad8796e1 100644
--- a/tests/ui/issues/issue-41394.rs
+++ b/tests/ui/enum-discriminant/issue-41394.rs
diff --git a/tests/ui/issues/issue-41394.stderr b/tests/ui/enum-discriminant/issue-41394.stderr
index 1b5c64628a1..1b5c64628a1 100644
--- a/tests/ui/issues/issue-41394.stderr
+++ b/tests/ui/enum-discriminant/issue-41394.stderr
diff --git a/tests/ui/extenv/issue-110547.rs b/tests/ui/extenv/issue-110547.rs
new file mode 100644
index 00000000000..a6fb96ac066
--- /dev/null
+++ b/tests/ui/extenv/issue-110547.rs
@@ -0,0 +1,7 @@
+// compile-flags: -C debug-assertions
+
+fn main() {
+    env!{"\t"}; //~ ERROR not defined at compile time
+    env!("\t"); //~ ERROR not defined at compile time
+    env!("\u{2069}"); //~ ERROR not defined at compile time
+}
diff --git a/tests/ui/extenv/issue-110547.stderr b/tests/ui/extenv/issue-110547.stderr
new file mode 100644
index 00000000000..1219630d346
--- /dev/null
+++ b/tests/ui/extenv/issue-110547.stderr
@@ -0,0 +1,29 @@
+error: environment variable `    ` not defined at compile time
+  --> $DIR/issue-110547.rs:4:5
+   |
+LL |     env!{"\t"};
+   |     ^^^^^^^^^^
+   |
+   = help: use `std::env::var("    ")` to read the variable at run time
+   = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: environment variable `    ` not defined at compile time
+  --> $DIR/issue-110547.rs:5:5
+   |
+LL |     env!("\t");
+   |     ^^^^^^^^^^
+   |
+   = help: use `std::env::var("    ")` to read the variable at run time
+   = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: environment variable `` not defined at compile time
+  --> $DIR/issue-110547.rs:6:5
+   |
+LL |     env!("\u{2069}");
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: use `std::env::var("")` to read the variable at run time
+   = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/generator/auto-trait-regions.drop_tracking.stderr b/tests/ui/generator/auto-trait-regions.drop_tracking.stderr
index 165748d4430..b2a5b92ed0f 100644
--- a/tests/ui/generator/auto-trait-regions.drop_tracking.stderr
+++ b/tests/ui/generator/auto-trait-regions.drop_tracking.stderr
@@ -9,7 +9,11 @@ LL |         let a = A(&mut true, &mut true, No);
 LL |         assert_foo(a);
    |                    - borrow later used here
    |
-   = note: consider using a `let` binding to create a longer lived value
+help: consider using a `let` binding to create a longer lived value
+   |
+LL ~         let binding = true;
+LL ~         let a = A(&mut binding, &mut true, No);
+   |
 
 error[E0716]: temporary value dropped while borrowed
   --> $DIR/auto-trait-regions.rs:48:35
@@ -22,7 +26,11 @@ LL |         let a = A(&mut true, &mut true, No);
 LL |         assert_foo(a);
    |                    - borrow later used here
    |
-   = note: consider using a `let` binding to create a longer lived value
+help: consider using a `let` binding to create a longer lived value
+   |
+LL ~         let binding = true;
+LL ~         let a = A(&mut true, &mut binding, No);
+   |
 
 error: implementation of `Foo` is not general enough
   --> $DIR/auto-trait-regions.rs:34:5
diff --git a/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr b/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr
index 165748d4430..b2a5b92ed0f 100644
--- a/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr
+++ b/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr
@@ -9,7 +9,11 @@ LL |         let a = A(&mut true, &mut true, No);
 LL |         assert_foo(a);
    |                    - borrow later used here
    |
-   = note: consider using a `let` binding to create a longer lived value
+help: consider using a `let` binding to create a longer lived value
+   |
+LL ~         let binding = true;
+LL ~         let a = A(&mut binding, &mut true, No);
+   |
 
 error[E0716]: temporary value dropped while borrowed
   --> $DIR/auto-trait-regions.rs:48:35
@@ -22,7 +26,11 @@ LL |         let a = A(&mut true, &mut true, No);
 LL |         assert_foo(a);
    |                    - borrow later used here
    |
-   = note: consider using a `let` binding to create a longer lived value
+help: consider using a `let` binding to create a longer lived value
+   |
+LL ~         let binding = true;
+LL ~         let a = A(&mut true, &mut binding, No);
+   |
 
 error: implementation of `Foo` is not general enough
   --> $DIR/auto-trait-regions.rs:34:5
diff --git a/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr b/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr
index 165748d4430..b2a5b92ed0f 100644
--- a/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr
+++ b/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr
@@ -9,7 +9,11 @@ LL |         let a = A(&mut true, &mut true, No);
 LL |         assert_foo(a);
    |                    - borrow later used here
    |
-   = note: consider using a `let` binding to create a longer lived value
+help: consider using a `let` binding to create a longer lived value
+   |
+LL ~         let binding = true;
+LL ~         let a = A(&mut binding, &mut true, No);
+   |
 
 error[E0716]: temporary value dropped while borrowed
   --> $DIR/auto-trait-regions.rs:48:35
@@ -22,7 +26,11 @@ LL |         let a = A(&mut true, &mut true, No);
 LL |         assert_foo(a);
    |                    - borrow later used here
    |
-   = note: consider using a `let` binding to create a longer lived value
+help: consider using a `let` binding to create a longer lived value
+   |
+LL ~         let binding = true;
+LL ~         let a = A(&mut true, &mut binding, No);
+   |
 
 error: implementation of `Foo` is not general enough
   --> $DIR/auto-trait-regions.rs:34:5
diff --git a/tests/ui/generator/auto-trait-regions.stderr b/tests/ui/generator/auto-trait-regions.stderr
deleted file mode 100644
index 165748d4430..00000000000
--- a/tests/ui/generator/auto-trait-regions.stderr
+++ /dev/null
@@ -1,47 +0,0 @@
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/auto-trait-regions.rs:48:24
-   |
-LL |         let a = A(&mut true, &mut true, No);
-   |                        ^^^^                - temporary value is freed at the end of this statement
-   |                        |
-   |                        creates a temporary value which is freed while still in use
-...
-LL |         assert_foo(a);
-   |                    - borrow later used here
-   |
-   = note: consider using a `let` binding to create a longer lived value
-
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/auto-trait-regions.rs:48:35
-   |
-LL |         let a = A(&mut true, &mut true, No);
-   |                                   ^^^^     - temporary value is freed at the end of this statement
-   |                                   |
-   |                                   creates a temporary value which is freed while still in use
-...
-LL |         assert_foo(a);
-   |                    - borrow later used here
-   |
-   = note: consider using a `let` binding to create a longer lived value
-
-error: implementation of `Foo` is not general enough
-  --> $DIR/auto-trait-regions.rs:34:5
-   |
-LL |     assert_foo(gen);
-   |     ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `&'0 OnlyFooIfStaticRef` must implement `Foo`, for any lifetime `'0`...
-   = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef`
-
-error: implementation of `Foo` is not general enough
-  --> $DIR/auto-trait-regions.rs:54:5
-   |
-LL |     assert_foo(gen);
-   |     ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2`
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs b/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs
new file mode 100644
index 00000000000..5b10aab4b3f
--- /dev/null
+++ b/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs
@@ -0,0 +1,5 @@
+pub trait Foo {
+    type Gat<T>
+    where
+        T: std::fmt::Display;
+}
diff --git a/tests/ui/generic-associated-types/missing-item-sugg.rs b/tests/ui/generic-associated-types/missing-item-sugg.rs
new file mode 100644
index 00000000000..35d573d8188
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing-item-sugg.rs
@@ -0,0 +1,11 @@
+// aux-build:missing-item-sugg.rs
+
+extern crate missing_item_sugg;
+
+struct Local;
+impl missing_item_sugg::Foo for Local {
+    //~^ ERROR not all trait items implemented, missing: `Gat`
+}
+//~^ HELP implement the missing item: `type Gat<T> = /* Type */ where T: std::fmt::Display;`
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/missing-item-sugg.stderr b/tests/ui/generic-associated-types/missing-item-sugg.stderr
new file mode 100644
index 00000000000..378115f6d38
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing-item-sugg.stderr
@@ -0,0 +1,11 @@
+error[E0046]: not all trait items implemented, missing: `Gat`
+  --> $DIR/missing-item-sugg.rs:6:1
+   |
+LL | impl missing_item_sugg::Foo for Local {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Gat` in implementation
+   |
+   = help: implement the missing item: `type Gat<T> = /* Type */ where T: std::fmt::Display;`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/generics/auxiliary/foreign-generic-mismatch.rs b/tests/ui/generics/auxiliary/foreign-generic-mismatch.rs
new file mode 100644
index 00000000000..d89c1e03688
--- /dev/null
+++ b/tests/ui/generics/auxiliary/foreign-generic-mismatch.rs
@@ -0,0 +1,3 @@
+pub fn const_arg<const N: usize, T>() {}
+
+pub fn lt_arg<'a: 'a>() {}
diff --git a/tests/ui/generics/foreign-generic-mismatch.rs b/tests/ui/generics/foreign-generic-mismatch.rs
new file mode 100644
index 00000000000..403fd73d7df
--- /dev/null
+++ b/tests/ui/generics/foreign-generic-mismatch.rs
@@ -0,0 +1,10 @@
+// aux-build: foreign-generic-mismatch.rs
+
+extern crate foreign_generic_mismatch;
+
+fn main() {
+    foreign_generic_mismatch::const_arg::<()>();
+    //~^ ERROR function takes 2 generic arguments but 1 generic argument was supplied
+    foreign_generic_mismatch::lt_arg::<'static, 'static>();
+    //~^ ERROR function takes 1 lifetime argument but 2 lifetime arguments were supplied
+}
diff --git a/tests/ui/generics/foreign-generic-mismatch.stderr b/tests/ui/generics/foreign-generic-mismatch.stderr
new file mode 100644
index 00000000000..5322b3f919d
--- /dev/null
+++ b/tests/ui/generics/foreign-generic-mismatch.stderr
@@ -0,0 +1,35 @@
+error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied
+  --> $DIR/foreign-generic-mismatch.rs:6:31
+   |
+LL |     foreign_generic_mismatch::const_arg::<()>();
+   |                               ^^^^^^^^^   -- supplied 1 generic argument
+   |                               |
+   |                               expected 2 generic arguments
+   |
+note: function defined here, with 2 generic parameters: `N`, `T`
+  --> $DIR/auxiliary/foreign-generic-mismatch.rs:1:8
+   |
+LL | pub fn const_arg<const N: usize, T>() {}
+   |        ^^^^^^^^^ --------------  -
+help: add missing generic argument
+   |
+LL |     foreign_generic_mismatch::const_arg::<(), T>();
+   |                                             +++
+
+error[E0107]: function takes 1 lifetime argument but 2 lifetime arguments were supplied
+  --> $DIR/foreign-generic-mismatch.rs:8:31
+   |
+LL |     foreign_generic_mismatch::lt_arg::<'static, 'static>();
+   |                               ^^^^^^            ------- help: remove this lifetime argument
+   |                               |
+   |                               expected 1 lifetime argument
+   |
+note: function defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/auxiliary/foreign-generic-mismatch.rs:3:8
+   |
+LL | pub fn lt_arg<'a: 'a>() {}
+   |        ^^^^^^ --
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/impl-trait/auto-trait-leak.stderr b/tests/ui/impl-trait/auto-trait-leak.stderr
index e6c750d0e42..aa4ee75bb75 100644
--- a/tests/ui/impl-trait/auto-trait-leak.stderr
+++ b/tests/ui/impl-trait/auto-trait-leak.stderr
@@ -9,7 +9,7 @@ note: ...which requires borrow-checking `cycle1`...
    |
 LL | fn cycle1() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing MIR for `cycle1`...
+note: ...which requires promoting constants in MIR for `cycle1`...
   --> $DIR/auto-trait-leak.rs:12:1
    |
 LL | fn cycle1() -> impl Clone {
@@ -55,7 +55,7 @@ note: ...which requires borrow-checking `cycle2`...
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing MIR for `cycle2`...
+note: ...which requires promoting constants in MIR for `cycle2`...
   --> $DIR/auto-trait-leak.rs:19:1
    |
 LL | fn cycle2() -> impl Clone {
diff --git a/tests/ui/impl-trait/issue-108591.rs b/tests/ui/impl-trait/issue-108591.rs
new file mode 100644
index 00000000000..6b9d14941f2
--- /dev/null
+++ b/tests/ui/impl-trait/issue-108591.rs
@@ -0,0 +1,30 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+struct MyTy<'a>(Vec<u8>, &'a ());
+
+impl MyTy<'_> {
+    fn one(&mut self) -> &mut impl Sized {
+        &mut self.0
+    }
+    fn two(&mut self) -> &mut (impl Sized + 'static) {
+        self.one()
+    }
+}
+
+type Opaque<'a> = impl Sized;
+fn define<'a>() -> Opaque<'a> {}
+
+fn test<'a>() {
+    None::<&'static Opaque<'a>>;
+}
+
+fn one<'a, 'b: 'b>() -> &'a impl Sized {
+    &()
+}
+fn two<'a, 'b>() {
+    one::<'a, 'b>();
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/issue-108592.rs b/tests/ui/impl-trait/issue-108592.rs
new file mode 100644
index 00000000000..58a0ed9bf1a
--- /dev/null
+++ b/tests/ui/impl-trait/issue-108592.rs
@@ -0,0 +1,21 @@
+// check-pass
+#![feature(type_alias_impl_trait)]
+
+fn opaque<'a: 'a>() -> impl Sized {}
+fn assert_static<T: 'static>(_: T) {}
+
+fn test_closure() {
+    let closure = |_| {
+        assert_static(opaque());
+    };
+    closure(&opaque());
+}
+
+type Opaque<'a> = impl Sized;
+fn define<'a>() -> Opaque<'a> {}
+
+fn test_tait(_: &Opaque<'_>) {
+    None::<&'static Opaque<'_>>;
+}
+
+fn main() {}
diff --git a/tests/ui/issues/issue-36792.rs b/tests/ui/impl-trait/issue-36792.rs
index 99ae633dd0e..99ae633dd0e 100644
--- a/tests/ui/issues/issue-36792.rs
+++ b/tests/ui/impl-trait/issue-36792.rs
diff --git a/tests/ui/issues/issue-33287.rs b/tests/ui/issues/issue-33287.rs
index 770eb7c02bb..b3f87305781 100644
--- a/tests/ui/issues/issue-33287.rs
+++ b/tests/ui/issues/issue-33287.rs
@@ -1,6 +1,7 @@
 // build-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
+#![allow(unconditional_panic)]
 const A: [u32; 1] = [0];
 
 fn test() {
diff --git a/tests/ui/issues/issue-3344.stderr b/tests/ui/issues/issue-3344.stderr
index 11d5999672e..e849f5d0490 100644
--- a/tests/ui/issues/issue-3344.stderr
+++ b/tests/ui/issues/issue-3344.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `partial_cmp`
 LL | impl PartialOrd for Thing {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation
    |
-   = help: implement the missing item: `fn partial_cmp(&self, _: &Rhs) -> Option<std::cmp::Ordering> { todo!() }`
+   = help: implement the missing item: `fn partial_cmp(&self, _: &Thing) -> Option<std::cmp::Ordering> { todo!() }`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-6458-1.rs b/tests/ui/issues/issue-6458-1.rs
deleted file mode 100644
index 184e4832b90..00000000000
--- a/tests/ui/issues/issue-6458-1.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// run-fail
-// error-pattern:explicit panic
-// ignore-emscripten no processes
-
-fn foo<T>(t: T) {}
-fn main() {
-    foo(panic!())
-}
diff --git a/tests/ui/issues/issue-6458-2.rs b/tests/ui/issues/issue-6458-2.rs
deleted file mode 100644
index b18cae3ed1a..00000000000
--- a/tests/ui/issues/issue-6458-2.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-fn main() {
-    // Unconstrained type:
-    format!("{:?}", None);
-    //~^ ERROR type annotations needed [E0282]
-}
diff --git a/tests/ui/issues/issue-6458-2.stderr b/tests/ui/issues/issue-6458-2.stderr
deleted file mode 100644
index 8dbdd9a2735..00000000000
--- a/tests/ui/issues/issue-6458-2.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0282]: type annotations needed
-  --> $DIR/issue-6458-2.rs:3:21
-   |
-LL |     format!("{:?}", None);
-   |                     ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
-   |
-help: consider specifying the generic argument
-   |
-LL |     format!("{:?}", None::<T>);
-   |                         +++++
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/issues/issue-6458-3.rs b/tests/ui/issues/issue-6458-3.rs
deleted file mode 100644
index d4f8886e9b0..00000000000
--- a/tests/ui/issues/issue-6458-3.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-use std::mem;
-
-fn main() {
-    mem::transmute(0);
-    //~^ ERROR type annotations needed [E0282]
-}
diff --git a/tests/ui/issues/issue-6458-3.stderr b/tests/ui/issues/issue-6458-3.stderr
deleted file mode 100644
index 520efccae51..00000000000
--- a/tests/ui/issues/issue-6458-3.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0282]: type annotations needed
-  --> $DIR/issue-6458-3.rs:4:5
-   |
-LL |     mem::transmute(0);
-   |     ^^^^^^^^^^^^^^ cannot infer type of the type parameter `Dst` declared on the function `transmute`
-   |
-help: consider specifying the generic arguments
-   |
-LL |     mem::transmute::<i32, Dst>(0);
-   |                   ++++++++++++
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/issues/issue-6458-4.rs b/tests/ui/issues/issue-6458-4.rs
deleted file mode 100644
index 054a5c15c3f..00000000000
--- a/tests/ui/issues/issue-6458-4.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-fn foo(b: bool) -> Result<bool,String> { //~ ERROR mismatched types
-    Err("bar".to_string());
-}
-
-fn main() {
-    foo(false);
-}
diff --git a/tests/ui/issues/issue-6458-4.stderr b/tests/ui/issues/issue-6458-4.stderr
deleted file mode 100644
index 66ccfdff236..00000000000
--- a/tests/ui/issues/issue-6458-4.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-6458-4.rs:1:20
-   |
-LL | fn foo(b: bool) -> Result<bool,String> {
-   |    ---             ^^^^^^^^^^^^^^^^^^^ expected `Result<bool, String>`, found `()`
-   |    |
-   |    implicitly returns `()` as its body has no tail or `return` expression
-LL |     Err("bar".to_string());
-   |                           - help: remove this semicolon to return this value
-   |
-   = note:   expected enum `Result<bool, String>`
-           found unit type `()`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/issues/issue-6458.rs b/tests/ui/issues/issue-6458.rs
deleted file mode 100644
index 16718e90deb..00000000000
--- a/tests/ui/issues/issue-6458.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-use std::marker;
-
-pub struct TypeWithState<State>(marker::PhantomData<State>);
-pub struct MyState;
-
-pub fn foo<State>(_: TypeWithState<State>) {}
-
-pub fn bar() {
-   foo(TypeWithState(marker::PhantomData));
-   //~^ ERROR type annotations needed [E0282]
-}
-
-fn main() {
-}
diff --git a/tests/ui/issues/issue-6458.stderr b/tests/ui/issues/issue-6458.stderr
deleted file mode 100644
index 2e93c13855f..00000000000
--- a/tests/ui/issues/issue-6458.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0282]: type annotations needed
-  --> $DIR/issue-6458.rs:9:22
-   |
-LL |    foo(TypeWithState(marker::PhantomData));
-   |                      ^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData`
-   |
-help: consider specifying the generic argument
-   |
-LL |    foo(TypeWithState(marker::PhantomData::<T>));
-   |                                         +++++
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/issues/issue-36744-without-calls.rs b/tests/ui/lifetimes/issue-36744-without-calls.rs
index dc5dc4f13c0..dc5dc4f13c0 100644
--- a/tests/ui/issues/issue-36744-without-calls.rs
+++ b/tests/ui/lifetimes/issue-36744-without-calls.rs
diff --git a/tests/ui/lifetimes/issue-69314.stderr b/tests/ui/lifetimes/issue-69314.stderr
index 7ae6789285b..3879f35505c 100644
--- a/tests/ui/lifetimes/issue-69314.stderr
+++ b/tests/ui/lifetimes/issue-69314.stderr
@@ -12,6 +12,8 @@ LL |     async fn f2(m: Msg<'_>) {}
 error[E0597]: `buf` does not live long enough
   --> $DIR/issue-69314.rs:14:19
    |
+LL |         let mut buf = [0; 512];
+   |             ------- binding `buf` declared here
 LL |         let m2 = &buf[..];
    |                   ^^^ borrowed value does not live long enough
 LL |         let m = Self::g(m2).await;
diff --git a/tests/ui/lint/dead-code/offset-of-correct-param-env.rs b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs
new file mode 100644
index 00000000000..2c6fcef2500
--- /dev/null
+++ b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs
@@ -0,0 +1,42 @@
+// check-pass
+
+#![feature(offset_of)]
+#![deny(dead_code)]
+
+// This struct contains a projection that can only be normalized after getting the field type.
+struct A<T: Project> {
+    a: <T as Project>::EquateParamTo,
+}
+
+// This is the inner struct that we want to get.
+struct MyFieldIsNotDead {
+    not_dead: u8,
+}
+
+// These are some helpers.
+// Inside the param env of `test`, we want to make it so that it considers T=MyFieldIsNotDead.
+struct GenericIsEqual<T>(T);
+trait Project {
+    type EquateParamTo;
+}
+impl<T> Project for GenericIsEqual<T> {
+    type EquateParamTo = T;
+}
+
+fn test<T>() -> usize
+where
+    GenericIsEqual<T>: Project<EquateParamTo = MyFieldIsNotDead>,
+{
+    // The first field of the A that we construct here is
+    // `<GenericIsEqual<T>> as Project>::EquateParamTo`.
+    // Typeck normalizes this and figures that the not_dead field is totally fine and accessible.
+    // But importantly, the normalization ends up with T, which, as we've declared in our param
+    // env is MyFieldDead. When we're in the param env of the `a` field, the where bound above
+    // is not in scope, so we don't know what T is - it's generic.
+    // If we use the wrong param env, the lint will ICE.
+    std::mem::offset_of!(A<GenericIsEqual<T>>, a.not_dead)
+}
+
+fn main() {
+    test::<MyFieldIsNotDead>();
+}
diff --git a/tests/ui/lint/dead-code/offset-of.rs b/tests/ui/lint/dead-code/offset-of.rs
new file mode 100644
index 00000000000..da91de3862f
--- /dev/null
+++ b/tests/ui/lint/dead-code/offset-of.rs
@@ -0,0 +1,44 @@
+#![feature(offset_of)]
+#![deny(dead_code)]
+
+use std::mem::offset_of;
+
+struct Alpha {
+    a: (),
+    b: (), //~ ERROR field `b` is never read
+    c: Beta,
+}
+
+struct Beta {
+    a: (), //~ ERROR field `a` is never read
+    b: (),
+}
+
+struct Gamma {
+    a: (), //~ ERROR field `a` is never read
+    b: (),
+}
+
+struct Delta {
+    a: (),
+    b: (), //~ ERROR field `b` is never read
+}
+
+trait Trait {
+    type Assoc;
+}
+impl Trait for () {
+    type Assoc = Delta;
+}
+
+struct Project<T: Trait> {
+    a: u8, //~ ERROR field `a` is never read
+    b: <T as Trait>::Assoc,
+}
+
+fn main() {
+    offset_of!(Alpha, a);
+    offset_of!(Alpha, c.b);
+    offset_of!((Gamma,), 0.b);
+    offset_of!(Project::<()>, b.a);
+}
diff --git a/tests/ui/lint/dead-code/offset-of.stderr b/tests/ui/lint/dead-code/offset-of.stderr
new file mode 100644
index 00000000000..ed2916461cd
--- /dev/null
+++ b/tests/ui/lint/dead-code/offset-of.stderr
@@ -0,0 +1,50 @@
+error: field `b` is never read
+  --> $DIR/offset-of.rs:8:5
+   |
+LL | struct Alpha {
+   |        ----- field in this struct
+LL |     a: (),
+LL |     b: (),
+   |     ^
+   |
+note: the lint level is defined here
+  --> $DIR/offset-of.rs:2:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: field `a` is never read
+  --> $DIR/offset-of.rs:13:5
+   |
+LL | struct Beta {
+   |        ---- field in this struct
+LL |     a: (),
+   |     ^
+
+error: field `a` is never read
+  --> $DIR/offset-of.rs:18:5
+   |
+LL | struct Gamma {
+   |        ----- field in this struct
+LL |     a: (),
+   |     ^
+
+error: field `b` is never read
+  --> $DIR/offset-of.rs:24:5
+   |
+LL | struct Delta {
+   |        ----- field in this struct
+LL |     a: (),
+LL |     b: (),
+   |     ^
+
+error: field `a` is never read
+  --> $DIR/offset-of.rs:35:5
+   |
+LL | struct Project<T: Trait> {
+   |        ------- field in this struct
+LL |     a: u8,
+   |     ^
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/lint/issue-110573.rs b/tests/ui/lint/issue-110573.rs
new file mode 100644
index 00000000000..d9f0868b765
--- /dev/null
+++ b/tests/ui/lint/issue-110573.rs
@@ -0,0 +1,12 @@
+// check-pass
+
+#![deny(warnings)]
+
+pub struct Struct;
+
+impl Struct {
+    #[allow(non_upper_case_globals)]
+    pub const Const: () = ();
+}
+
+fn main() {}
diff --git a/tests/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs
index f30d7e2edcc..f30d7e2edcc 100644
--- a/tests/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs
+++ b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs
diff --git a/tests/ui/issues/issue-26094.rs b/tests/ui/macros/issue-26094.rs
index 2742529edd3..2742529edd3 100644
--- a/tests/ui/issues/issue-26094.rs
+++ b/tests/ui/macros/issue-26094.rs
diff --git a/tests/ui/issues/issue-26094.stderr b/tests/ui/macros/issue-26094.stderr
index ecdf48470f7..ecdf48470f7 100644
--- a/tests/ui/issues/issue-26094.stderr
+++ b/tests/ui/macros/issue-26094.stderr
diff --git a/tests/ui/issues/issue-69396-const-no-type-in-macro.rs b/tests/ui/macros/issue-69396-const-no-type-in-macro.rs
index 45a30857413..45a30857413 100644
--- a/tests/ui/issues/issue-69396-const-no-type-in-macro.rs
+++ b/tests/ui/macros/issue-69396-const-no-type-in-macro.rs
diff --git a/tests/ui/issues/issue-69396-const-no-type-in-macro.stderr b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr
index 89aeafebac4..89aeafebac4 100644
--- a/tests/ui/issues/issue-69396-const-no-type-in-macro.stderr
+++ b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr
diff --git a/tests/ui/user-defined-macro-rules.rs b/tests/ui/macros/user-defined-macro-rules.rs
index 09e071ec454..09e071ec454 100644
--- a/tests/ui/user-defined-macro-rules.rs
+++ b/tests/ui/macros/user-defined-macro-rules.rs
diff --git a/tests/ui/mir/validate/storage-live.stderr b/tests/ui/mir/validate/storage-live.stderr
index b586a865849..720fb0a90b0 100644
--- a/tests/ui/mir/validate/storage-live.stderr
+++ b/tests/ui/mir/validate/storage-live.stderr
@@ -1,4 +1,4 @@
-error: internal compiler error: broken MIR in Item(WithOptConstParam { did: DefId(0:8 ~ storage_live[HASH]::multiple_storage), const_param_did: None }) (before pass CheckPackedRef) at bb0[1]:
+error: internal compiler error: broken MIR in Item(DefId(0:8 ~ storage_live[HASH]::multiple_storage)) (before pass CheckPackedRef) at bb0[1]:
                                 StorageLive(_1) which already has storage here
   --> $DIR/storage-live.rs:22:13
    |
@@ -9,5 +9,5 @@ error: the compiler unexpectedly panicked. this is a bug.
 
 query stack during panic:
 #0 [mir_const] preparing `multiple_storage` for borrow checking
-#1 [mir_promoted] processing MIR for `multiple_storage`
+#1 [mir_promoted] promoting constants in MIR for `multiple_storage`
 end of query stack
diff --git a/tests/ui/missing/missing-items/m2.stderr b/tests/ui/missing/missing-items/m2.stderr
index d18fb443aa4..835c9b2aa48 100644
--- a/tests/ui/missing/missing-items/m2.stderr
+++ b/tests/ui/missing/missing-items/m2.stderr
@@ -5,7 +5,7 @@ LL | impl m1::X for X {
    | ^^^^^^^^^^^^^^^^ missing `CONSTANT`, `Type`, `method`, `method2`, `method3`, `method4`, `method5` in implementation
    |
    = help: implement the missing item: `const CONSTANT: u32 = 42;`
-   = help: implement the missing item: `type Type = Type;`
+   = help: implement the missing item: `type Type = /* Type */;`
    = help: implement the missing item: `fn method(&self, _: String) -> <Self as m1::X>::Type { todo!() }`
    = help: implement the missing item: `fn method2(self: Box<Self>, _: String) -> <Self as m1::X>::Type { todo!() }`
    = help: implement the missing item: `fn method3(_: &Self, _: String) -> <Self as m1::X>::Type { todo!() }`
diff --git a/tests/ui/nll/user-annotations/adt-brace-enums.stderr b/tests/ui/nll/user-annotations/adt-brace-enums.stderr
index 9e94fd5a782..900e7e25390 100644
--- a/tests/ui/nll/user-annotations/adt-brace-enums.stderr
+++ b/tests/ui/nll/user-annotations/adt-brace-enums.stderr
@@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough
    |
 LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
    |                                              -- lifetime `'a` defined here
-...
+LL |     let _closure = || {
+LL |         let c = 66;
+   |             - binding `c` declared here
 LL |         SomeEnum::SomeVariant::<&'a u32> { t: &c };
    |                                               ^^
    |                                               |
diff --git a/tests/ui/nll/user-annotations/adt-brace-structs.stderr b/tests/ui/nll/user-annotations/adt-brace-structs.stderr
index cbb7f6a55a9..d61643dc6ed 100644
--- a/tests/ui/nll/user-annotations/adt-brace-structs.stderr
+++ b/tests/ui/nll/user-annotations/adt-brace-structs.stderr
@@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough
    |
 LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
    |                                              -- lifetime `'a` defined here
-...
+LL |     let _closure = || {
+LL |         let c = 66;
+   |             - binding `c` declared here
 LL |         SomeStruct::<&'a u32> { t: &c };
    |                                    ^^
    |                                    |
diff --git a/tests/ui/nll/user-annotations/adt-nullary-enums.stderr b/tests/ui/nll/user-annotations/adt-nullary-enums.stderr
index bca85a90d19..5b385feeedc 100644
--- a/tests/ui/nll/user-annotations/adt-nullary-enums.stderr
+++ b/tests/ui/nll/user-annotations/adt-nullary-enums.stderr
@@ -34,7 +34,10 @@ error[E0597]: `c` does not live long enough
    |
 LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
    |                                              -- lifetime `'a` defined here
-...
+LL |     let _closure = || {
+LL |         let c = 66;
+   |             - binding `c` declared here
+LL |         combine(
 LL |             SomeEnum::SomeVariant(Cell::new(&c)),
    |                                   ----------^^-
    |                                   |         |
diff --git a/tests/ui/nll/user-annotations/adt-tuple-enums.stderr b/tests/ui/nll/user-annotations/adt-tuple-enums.stderr
index d2d85ec2b9b..766da9ec00c 100644
--- a/tests/ui/nll/user-annotations/adt-tuple-enums.stderr
+++ b/tests/ui/nll/user-annotations/adt-tuple-enums.stderr
@@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough
    |
 LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
    |                                              -- lifetime `'a` defined here
-...
+LL |     let _closure = || {
+LL |         let c = 66;
+   |             - binding `c` declared here
 LL |         SomeEnum::SomeVariant::<&'a u32>(&c);
    |                                          ^^
    |                                          |
diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr
index b7bc2a10b70..2084697e7e2 100644
--- a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr
+++ b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr
@@ -33,7 +33,10 @@ error[E0597]: `c` does not live long enough
    |
 LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
    |                                              -- lifetime `'a` defined here
-...
+LL |     let _closure = || {
+LL |         let c = 66;
+   |             - binding `c` declared here
+LL |         let f = SomeStruct::<&'a u32>;
 LL |         f(&c);
    |         --^^-
    |         | |
@@ -47,7 +50,9 @@ error[E0597]: `c` does not live long enough
    |
 LL |     let f = SomeStruct::<&'a u32>;
    |         - lifetime `'1` appears in the type of `f`
-...
+LL |     let _closure = || {
+LL |         let c = 66;
+   |             - binding `c` declared here
 LL |         f(&c);
    |         --^^-
    |         | |
diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct.stderr b/tests/ui/nll/user-annotations/adt-tuple-struct.stderr
index 97d39da265f..c7480f52963 100644
--- a/tests/ui/nll/user-annotations/adt-tuple-struct.stderr
+++ b/tests/ui/nll/user-annotations/adt-tuple-struct.stderr
@@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough
    |
 LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
    |                                              -- lifetime `'a` defined here
-...
+LL |     let _closure = || {
+LL |         let c = 66;
+   |             - binding `c` declared here
 LL |         SomeStruct::<&'a u32>(&c);
    |                               ^^
    |                               |
diff --git a/tests/ui/nll/user-annotations/fns.stderr b/tests/ui/nll/user-annotations/fns.stderr
index 8b53e138d9b..abaa35e9516 100644
--- a/tests/ui/nll/user-annotations/fns.stderr
+++ b/tests/ui/nll/user-annotations/fns.stderr
@@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough
    |
 LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
    |                                              -- lifetime `'a` defined here
-...
+LL |     let _closure = || {
+LL |         let c = 66;
+   |             - binding `c` declared here
 LL |         some_fn::<&'a u32>(&c);
    |         -------------------^^-
    |         |                  |
diff --git a/tests/ui/nll/user-annotations/method-call.stderr b/tests/ui/nll/user-annotations/method-call.stderr
index 3803cbf776b..b4d1ac042a2 100644
--- a/tests/ui/nll/user-annotations/method-call.stderr
+++ b/tests/ui/nll/user-annotations/method-call.stderr
@@ -33,6 +33,8 @@ error[E0597]: `c` does not live long enough
 LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
    |                                              -- lifetime `'a` defined here
 ...
+LL |         let c = 66;
+   |             - binding `c` declared here
 LL |         a.method::<&'a u32>(b,  &c);
    |         ------------------------^^-
    |         |                       |
diff --git a/tests/ui/nll/user-annotations/method-ufcs-3.stderr b/tests/ui/nll/user-annotations/method-ufcs-3.stderr
index 8cb995a03ce..4dd39e10827 100644
--- a/tests/ui/nll/user-annotations/method-ufcs-3.stderr
+++ b/tests/ui/nll/user-annotations/method-ufcs-3.stderr
@@ -33,6 +33,8 @@ error[E0597]: `c` does not live long enough
 LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
    |                                              -- lifetime `'a` defined here
 ...
+LL |         let c = 66;
+   |             - binding `c` declared here
 LL |         <_ as Bazoom<_>>::method::<&'a u32>(&a, b, &c);
    |         -------------------------------------------^^-
    |         |                                          |
diff --git a/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs b/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs
new file mode 100644
index 00000000000..565b7e86fc4
--- /dev/null
+++ b/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs
@@ -0,0 +1,12 @@
+// run-fail
+// error-pattern:thread 'main' panicked at 'attempt to negate with overflow'
+// ignore-emscripten no processes
+// compile-flags: -C debug-assertions
+
+#![allow(arithmetic_overflow)]
+
+use std::num::NonZeroI8;
+
+fn main() {
+    let _x = -NonZeroI8::new(i8::MIN).unwrap();
+}
diff --git a/tests/ui/offset-of/auxiliary/offset-of-staged-api.rs b/tests/ui/offset-of/auxiliary/offset-of-staged-api.rs
new file mode 100644
index 00000000000..088086cc580
--- /dev/null
+++ b/tests/ui/offset-of/auxiliary/offset-of-staged-api.rs
@@ -0,0 +1,33 @@
+#![crate_type = "lib"]
+#![feature(staged_api)]
+#![stable(feature = "stable_test_feature", since = "1.0")]
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub struct Unstable {
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    pub unstable: u8,
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0")]
+pub struct Stable {
+    #[stable(feature = "stable_test_feature", since = "1.0")]
+    pub stable: u8,
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0")]
+pub struct StableWithUnstableField {
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    pub unstable: u8,
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0")]
+pub struct StableWithUnstableFieldType {
+    #[stable(feature = "stable_test_feature", since = "1.0")]
+    pub stable: Unstable,
+}
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+pub struct UnstableWithStableFieldType {
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    pub unstable: Stable,
+}
diff --git a/tests/ui/offset-of/offset-of-arg-count.rs b/tests/ui/offset-of/offset-of-arg-count.rs
new file mode 100644
index 00000000000..163b07454ec
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-arg-count.rs
@@ -0,0 +1,9 @@
+#![feature(offset_of)]
+
+use std::mem::offset_of;
+
+fn main() {
+    offset_of!(NotEnoughArguments); //~ ERROR expected one of
+    offset_of!(NotEnoughArgumentsWithAComma, ); //~ ERROR expected 2 arguments
+    offset_of!(Container, field, too many arguments); //~ ERROR expected 2 arguments
+}
diff --git a/tests/ui/offset-of/offset-of-arg-count.stderr b/tests/ui/offset-of/offset-of-arg-count.stderr
new file mode 100644
index 00000000000..ebecc982c51
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-arg-count.stderr
@@ -0,0 +1,20 @@
+error: expected one of `!`, `(`, `+`, `,`, `::`, or `<`, found `<eof>`
+  --> $DIR/offset-of-arg-count.rs:6:16
+   |
+LL |     offset_of!(NotEnoughArguments);
+   |                ^^^^^^^^^^^^^^^^^^ expected one of `!`, `(`, `+`, `,`, `::`, or `<`
+
+error: expected 2 arguments
+  --> $DIR/offset-of-arg-count.rs:7:5
+   |
+LL |     offset_of!(NotEnoughArgumentsWithAComma, );
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: expected 2 arguments
+  --> $DIR/offset-of-arg-count.rs:8:5
+   |
+LL |     offset_of!(Container, field, too many arguments);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs
new file mode 100644
index 00000000000..a0269ca2d12
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-dst-field.rs
@@ -0,0 +1,33 @@
+#![feature(offset_of, extern_types)]
+
+use std::mem::offset_of;
+
+struct Alpha {
+    x: u8,
+    y: u16,
+    z: [u8],
+}
+
+trait Trait {}
+
+struct Beta {
+    x: u8,
+    y: u16,
+    z: dyn Trait,
+}
+
+extern {
+    type Extern;
+}
+
+struct Gamma {
+    x: u8,
+    y: u16,
+    z: Extern,
+}
+
+fn main() {
+    offset_of!(Alpha, z); //~ ERROR the size for values of type
+    offset_of!(Beta, z); //~ ERROR the size for values of type
+    offset_of!(Gamma, z); //~ ERROR the size for values of type
+}
diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr
new file mode 100644
index 00000000000..8e88015b07a
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-dst-field.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/offset-of-dst-field.rs:30:5
+   |
+LL |     offset_of!(Alpha, z);
+   |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+
+error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
+  --> $DIR/offset-of-dst-field.rs:31:5
+   |
+LL |     offset_of!(Beta, z);
+   |     ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn Trait + 'static)`
+
+error[E0277]: the size for values of type `Extern` cannot be known at compilation time
+  --> $DIR/offset-of-dst-field.rs:32:5
+   |
+LL |     offset_of!(Gamma, z);
+   |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `Extern`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/offset-of/offset-of-enum.rs b/tests/ui/offset-of/offset-of-enum.rs
new file mode 100644
index 00000000000..d73505821ff
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-enum.rs
@@ -0,0 +1,13 @@
+#![feature(offset_of)]
+
+use std::mem::offset_of;
+
+enum Alpha {
+    One(u8),
+    Two(u8),
+}
+
+fn main() {
+    offset_of!(Alpha::One, 0); //~ ERROR expected type, found variant `Alpha::One`
+    offset_of!(Alpha, Two.0); //~ ERROR no field `Two` on type `Alpha`
+}
diff --git a/tests/ui/offset-of/offset-of-enum.stderr b/tests/ui/offset-of/offset-of-enum.stderr
new file mode 100644
index 00000000000..6958d199fbd
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-enum.stderr
@@ -0,0 +1,19 @@
+error[E0573]: expected type, found variant `Alpha::One`
+  --> $DIR/offset-of-enum.rs:11:16
+   |
+LL |     offset_of!(Alpha::One, 0);
+   |                ^^^^^^^^^^
+   |                |
+   |                not a type
+   |                help: try using the variant's enum: `Alpha`
+
+error[E0609]: no field `Two` on type `Alpha`
+  --> $DIR/offset-of-enum.rs:12:23
+   |
+LL |     offset_of!(Alpha, Two.0);
+   |                       ^^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0573, E0609.
+For more information about an error, try `rustc --explain E0573`.
diff --git a/tests/ui/offset-of/offset-of-private.rs b/tests/ui/offset-of/offset-of-private.rs
new file mode 100644
index 00000000000..0291b7825ca
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-private.rs
@@ -0,0 +1,16 @@
+#![feature(offset_of)]
+
+use std::mem::offset_of;
+
+mod m {
+    #[repr(C)]
+    pub struct Foo {
+        pub public: u8,
+        private: u8,
+    }
+}
+
+fn main() {
+    offset_of!(m::Foo, public);
+    offset_of!(m::Foo, private); //~ ERROR field `private` of struct `Foo` is private
+}
diff --git a/tests/ui/offset-of/offset-of-private.stderr b/tests/ui/offset-of/offset-of-private.stderr
new file mode 100644
index 00000000000..8a186dd5a02
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-private.stderr
@@ -0,0 +1,9 @@
+error[E0616]: field `private` of struct `Foo` is private
+  --> $DIR/offset-of-private.rs:15:24
+   |
+LL |     offset_of!(m::Foo, private);
+   |                        ^^^^^^^ private field
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0616`.
diff --git a/tests/ui/offset-of/offset-of-unstable-with-feature.rs b/tests/ui/offset-of/offset-of-unstable-with-feature.rs
new file mode 100644
index 00000000000..7d2eb46c056
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-unstable-with-feature.rs
@@ -0,0 +1,20 @@
+// check-pass
+// aux-build:offset-of-staged-api.rs
+
+#![feature(offset_of, unstable_test_feature)]
+
+use std::mem::offset_of;
+
+extern crate offset_of_staged_api;
+
+use offset_of_staged_api::*;
+
+fn main() {
+    offset_of!(Unstable, unstable);
+    offset_of!(Stable, stable);
+    offset_of!(StableWithUnstableField, unstable);
+    offset_of!(StableWithUnstableFieldType, stable);
+    offset_of!(StableWithUnstableFieldType, stable.unstable);
+    offset_of!(UnstableWithStableFieldType, unstable);
+    offset_of!(UnstableWithStableFieldType, unstable.stable);
+}
diff --git a/tests/ui/offset-of/offset-of-unstable.rs b/tests/ui/offset-of/offset-of-unstable.rs
new file mode 100644
index 00000000000..1e19f2091f2
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-unstable.rs
@@ -0,0 +1,31 @@
+// aux-build:offset-of-staged-api.rs
+
+#![feature(offset_of)]
+
+use std::mem::offset_of;
+
+extern crate offset_of_staged_api;
+
+use offset_of_staged_api::*;
+
+fn main() {
+    offset_of!(
+        //~^ ERROR use of unstable library feature
+        Unstable, //~ ERROR use of unstable library feature
+        unstable
+    );
+    offset_of!(Stable, stable);
+    offset_of!(StableWithUnstableField, unstable); //~ ERROR use of unstable library feature
+    offset_of!(StableWithUnstableFieldType, stable);
+    offset_of!(StableWithUnstableFieldType, stable.unstable); //~ ERROR use of unstable library feature
+    offset_of!(
+        //~^ ERROR use of unstable library feature
+        UnstableWithStableFieldType, //~ ERROR use of unstable library feature
+        unstable
+    );
+    offset_of!(
+        //~^ ERROR use of unstable library feature
+        UnstableWithStableFieldType, //~ ERROR use of unstable library feature
+        unstable.stable
+    );
+}
diff --git a/tests/ui/offset-of/offset-of-unstable.stderr b/tests/ui/offset-of/offset-of-unstable.stderr
new file mode 100644
index 00000000000..25811a061d7
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-unstable.stderr
@@ -0,0 +1,79 @@
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+  --> $DIR/offset-of-unstable.rs:14:9
+   |
+LL |         Unstable,
+   |         ^^^^^^^^
+   |
+   = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+  --> $DIR/offset-of-unstable.rs:23:9
+   |
+LL |         UnstableWithStableFieldType,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+  --> $DIR/offset-of-unstable.rs:28:9
+   |
+LL |         UnstableWithStableFieldType,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+  --> $DIR/offset-of-unstable.rs:12:5
+   |
+LL | /     offset_of!(
+LL | |
+LL | |         Unstable,
+LL | |         unstable
+LL | |     );
+   | |_____^
+   |
+   = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+  --> $DIR/offset-of-unstable.rs:18:5
+   |
+LL |     offset_of!(StableWithUnstableField, unstable);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+  --> $DIR/offset-of-unstable.rs:20:5
+   |
+LL |     offset_of!(StableWithUnstableFieldType, stable.unstable);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+  --> $DIR/offset-of-unstable.rs:21:5
+   |
+LL | /     offset_of!(
+LL | |
+LL | |         UnstableWithStableFieldType,
+LL | |         unstable
+LL | |     );
+   | |_____^
+   |
+   = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'unstable_test_feature'
+  --> $DIR/offset-of-unstable.rs:26:5
+   |
+LL | /     offset_of!(
+LL | |
+LL | |         UnstableWithStableFieldType,
+LL | |         unstable.stable
+LL | |     );
+   | |_____^
+   |
+   = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/polymorphization/generators.stderr b/tests/ui/polymorphization/generators.stderr
index 84888f6fb2f..32d49d25f02 100644
--- a/tests/ui/polymorphization/generators.stderr
+++ b/tests/ui/polymorphization/generators.stderr
@@ -15,12 +15,6 @@ LL | pub fn unused_type<T>() -> impl Generator<(), Yield = u32, Return = u32> +
 LL |     || {
    |     ^^
 
-note: the above error was encountered while instantiating `fn finish::<[generator@$DIR/generators.rs:35:5: 35:7], u32, u32>`
-  --> $DIR/generators.rs:86:5
-   |
-LL |     finish(unused_type::<u32>());
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error: item has unused generic parameters
   --> $DIR/generators.rs:60:5
    |
@@ -29,11 +23,5 @@ LL | pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Retu
 LL |     || {
    |     ^^
 
-note: the above error was encountered while instantiating `fn finish::<[generator@$DIR/generators.rs:60:5: 60:7], u32, u32>`
-  --> $DIR/generators.rs:89:5
-   |
-LL |     finish(unused_const::<1u32>());
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/polymorphization/predicates.stderr b/tests/ui/polymorphization/predicates.stderr
index 80bb2af25cc..a3b2f75b12d 100644
--- a/tests/ui/polymorphization/predicates.stderr
+++ b/tests/ui/polymorphization/predicates.stderr
@@ -1,4 +1,10 @@
 error: item has unused generic parameters
+  --> $DIR/predicates.rs:10:4
+   |
+LL | fn bar<I>() {
+   |    ^^^ - generic parameter `I` is unused
+
+error: item has unused generic parameters
   --> $DIR/predicates.rs:15:4
    |
 LL | fn foo<I, T>(_: I)
@@ -35,17 +41,5 @@ error: item has unused generic parameters
 LL | fn foobar<F, G>() -> usize
    |    ^^^^^^ - generic parameter `F` is unused
 
-error: item has unused generic parameters
-  --> $DIR/predicates.rs:10:4
-   |
-LL | fn bar<I>() {
-   |    ^^^ - generic parameter `I` is unused
-
-note: the above error was encountered while instantiating `fn foo::<std::slice::Iter<'_, u32>, T>`
-  --> $DIR/predicates.rs:86:5
-   |
-LL |     foo(x.iter());
-   |     ^^^^^^^^^^^^^
-
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/polymorphization/type_parameters/closures.stderr b/tests/ui/polymorphization/type_parameters/closures.stderr
index 94a4a08bd2f..5c3b46c6041 100644
--- a/tests/ui/polymorphization/type_parameters/closures.stderr
+++ b/tests/ui/polymorphization/type_parameters/closures.stderr
@@ -44,21 +44,6 @@ LL |     pub fn unused_all<G: Default>() -> u32 {
    |            ^^^^^^^^^^ - generic parameter `G` is unused
 
 error: item has unused generic parameters
-  --> $DIR/closures.rs:128:23
-   |
-LL |     pub fn used_impl<G: Default>() -> u32 {
-   |                      - generic parameter `G` is unused
-LL |
-LL |         let add_one = |x: u32| {
-   |                       ^^^^^^^^
-
-error: item has unused generic parameters
-  --> $DIR/closures.rs:126:12
-   |
-LL |     pub fn used_impl<G: Default>() -> u32 {
-   |            ^^^^^^^^^ - generic parameter `G` is unused
-
-error: item has unused generic parameters
   --> $DIR/closures.rs:115:23
    |
 LL | impl<F: Default> Foo<F> {
@@ -76,5 +61,20 @@ LL | impl<F: Default> Foo<F> {
 LL |     pub fn used_fn<G: Default>() -> u32 {
    |            ^^^^^^^
 
+error: item has unused generic parameters
+  --> $DIR/closures.rs:128:23
+   |
+LL |     pub fn used_impl<G: Default>() -> u32 {
+   |                      - generic parameter `G` is unused
+LL |
+LL |         let add_one = |x: u32| {
+   |                       ^^^^^^^^
+
+error: item has unused generic parameters
+  --> $DIR/closures.rs:126:12
+   |
+LL |     pub fn used_impl<G: Default>() -> u32 {
+   |            ^^^^^^^^^ - generic parameter `G` is unused
+
 error: aborting due to 9 previous errors
 
diff --git a/tests/ui/span/issue-23729.stderr b/tests/ui/span/issue-23729.stderr
index f88ce6c88db..cd854e61f2f 100644
--- a/tests/ui/span/issue-23729.stderr
+++ b/tests/ui/span/issue-23729.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Item`
 LL |         impl Iterator for Recurrence {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation
    |
-   = help: implement the missing item: `type Item = Type;`
+   = help: implement the missing item: `type Item = /* Type */;`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/span/issue-23827.stderr b/tests/ui/span/issue-23827.stderr
index 46a820f1b76..83a9e8c9b98 100644
--- a/tests/ui/span/issue-23827.stderr
+++ b/tests/ui/span/issue-23827.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Output`
 LL | impl<C: Component> FnOnce<(C,)> for Prototype {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Output` in implementation
    |
-   = help: implement the missing item: `type Output = Type;`
+   = help: implement the missing item: `type Output = /* Type */;`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/span/issue-24356.stderr b/tests/ui/span/issue-24356.stderr
index a1f9b255020..cf666e8b4a7 100644
--- a/tests/ui/span/issue-24356.stderr
+++ b/tests/ui/span/issue-24356.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Target`
 LL |         impl Deref for Thing {
    |         ^^^^^^^^^^^^^^^^^^^^ missing `Target` in implementation
    |
-   = help: implement the missing item: `type Target = Type;`
+   = help: implement the missing item: `type Target = /* Type */;`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/static/issue-18118.stderr b/tests/ui/static/issue-18118.stderr
index 49798a148de..035be2b1202 100644
--- a/tests/ui/static/issue-18118.stderr
+++ b/tests/ui/static/issue-18118.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `p` does not live long enough
   --> $DIR/issue-18118.rs:4:9
    |
+LL |         let p = 3;
+   |             - binding `p` declared here
 LL |         &p
    |         ^^
    |         |
diff --git a/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs b/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs
new file mode 100644
index 00000000000..b026035a6a1
--- /dev/null
+++ b/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs
@@ -0,0 +1,16 @@
+pub trait TraitB {
+    type Item;
+}
+
+pub trait TraitA<A> {
+    type Type;
+
+    fn bar<T>(_: T) -> Self;
+
+    fn baz<T>(_: T) -> Self
+    where
+        T: TraitB,
+        <T as TraitB>::Item: Copy;
+
+    const A: usize;
+}
diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed
deleted file mode 100644
index a0cb39a3f8a..00000000000
--- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed
+++ /dev/null
@@ -1,21 +0,0 @@
-// run-rustfix
-trait TraitB {
-    type Item;
-}
-
-trait TraitA<A> {
-    type Type;
-    fn bar<T>(_: T) -> Self;
-    fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy;
-}
-
-struct S;
-struct Type;
-
-impl TraitA<()> for S { //~ ERROR not all trait items implemented
-fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }
-fn bar<T>(_: T) -> Self { todo!() }
-type Type = Type;
-}
-
-fn main() {}
diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs
index c80ede1b2be..11e0c9a3a72 100644
--- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs
+++ b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs
@@ -1,18 +1,15 @@
-// run-rustfix
-trait TraitB {
-    type Item;
-}
+// aux-build:missing-assoc-fn-applicable-suggestions.rs
 
-trait TraitA<A> {
-    type Type;
-    fn bar<T>(_: T) -> Self;
-    fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy;
-}
+extern crate missing_assoc_fn_applicable_suggestions;
+use missing_assoc_fn_applicable_suggestions::TraitA;
 
 struct S;
-struct Type;
-
-impl TraitA<()> for S { //~ ERROR not all trait items implemented
+impl TraitA<()> for S {
+    //~^ ERROR not all trait items implemented
 }
+//~^ HELP implement the missing item: `type Type = /* Type */;`
+//~| HELP implement the missing item: `fn bar<T>(_: T) -> Self { todo!() }`
+//~| HELP implement the missing item: `fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }`
+//~| HELP implement the missing item: `const A: usize = 42;`
 
 fn main() {}
diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr
index 4c75fbe4c78..4c2d2776d3d 100644
--- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr
+++ b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr
@@ -1,15 +1,13 @@
-error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz`
-  --> $DIR/missing-assoc-fn-applicable-suggestions.rs:15:1
+error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz`, `A`
+  --> $DIR/missing-assoc-fn-applicable-suggestions.rs:7:1
    |
-LL |     type Type;
-   |     --------- `Type` from trait
-LL |     fn bar<T>(_: T) -> Self;
-   |     ------------------------ `bar` from trait
-LL |     fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy;
-   |     ------------------------------------------------------------------- `baz` from trait
-...
 LL | impl TraitA<()> for S {
-   | ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz` in implementation
+   | ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz`, `A` in implementation
+   |
+   = help: implement the missing item: `type Type = /* Type */;`
+   = help: implement the missing item: `fn bar<T>(_: T) -> Self { todo!() }`
+   = help: implement the missing item: `fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }`
+   = help: implement the missing item: `const A: usize = 42;`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/missing-assoc-fn.stderr b/tests/ui/suggestions/missing-assoc-fn.stderr
index 136ec2152e0..77fa9562878 100644
--- a/tests/ui/suggestions/missing-assoc-fn.stderr
+++ b/tests/ui/suggestions/missing-assoc-fn.stderr
@@ -28,7 +28,7 @@ error[E0046]: not all trait items implemented, missing: `from_iter`
 LL | impl FromIterator<()> for X {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation
    |
-   = help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = A { todo!() }`
+   = help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = () { todo!() }`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/issues/issue-22384.rs b/tests/ui/traits/issue-22384.rs
index 98988f27ecc..98988f27ecc 100644
--- a/tests/ui/issues/issue-22384.rs
+++ b/tests/ui/traits/issue-22384.rs
diff --git a/tests/ui/issues/issue-22384.stderr b/tests/ui/traits/issue-22384.stderr
index 1f767a443d0..1f767a443d0 100644
--- a/tests/ui/issues/issue-22384.stderr
+++ b/tests/ui/traits/issue-22384.stderr
diff --git a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
index 576fc6a4f8d..c943a4918ba 100644
--- a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
+++ b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
@@ -29,7 +29,7 @@ note: ...which requires borrow-checking `Alpha::V3::{constant#0}`...
    |
 LL |     V3 = Self::V1 {} as u8 + 2,
    |          ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires processing MIR for `Alpha::V3::{constant#0}`...
+note: ...which requires promoting constants in MIR for `Alpha::V3::{constant#0}`...
   --> $DIR/self-in-enum-definition.rs:5:10
    |
 LL |     V3 = Self::V1 {} as u8 + 2,