about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1798
-rw-r--r--Cargo.toml10
-rw-r--r--compiler/rustc_abi/src/layout.rs7
-rw-r--r--compiler/rustc_abi/src/lib.rs13
-rw-r--r--compiler/rustc_ast/src/ast.rs20
-rw-r--r--compiler/rustc_ast/src/node_id.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs55
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs5
-rw-r--r--compiler/rustc_borrowck/Cargo.toml1
-rw-r--r--compiler/rustc_borrowck/messages.ftl150
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs192
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs252
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs53
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs22
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/var_name.rs4
-rw-r--r--compiler/rustc_borrowck/src/facts.rs5
-rw-r--r--compiler/rustc_borrowck/src/lib.rs1
-rw-r--r--compiler/rustc_borrowck/src/location.rs8
-rw-r--r--compiler/rustc_borrowck/src/nll.rs8
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs207
-rw-r--r--compiler/rustc_borrowck/src/type_check/input_output.rs3
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs4
-rw-r--r--compiler/rustc_borrowck/src/util/collect_writes.rs (renamed from compiler/rustc_const_eval/src/util/collect_writes.rs)0
-rw-r--r--compiler/rustc_borrowck/src/util/mod.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/discriminant.rs17
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs27
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs2
-rw-r--r--compiler/rustc_const_eval/src/util/mod.rs5
-rw-r--r--compiler/rustc_data_structures/src/aligned.rs33
-rw-r--r--compiler/rustc_data_structures/src/lib.rs3
-rw-r--r--compiler/rustc_data_structures/src/sso/map.rs7
-rw-r--r--compiler/rustc_data_structures/src/svh.rs34
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr.rs270
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/copy.rs312
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs50
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/drop.rs116
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/drop/tests.rs71
-rw-r--r--compiler/rustc_hir/src/arena.rs1
-rw-r--r--compiler/rustc_hir/src/def.rs5
-rw-r--r--compiler/rustc_hir/src/hir.rs2
-rw-r--r--compiler/rustc_hir_analysis/Cargo.toml2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs11
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/suggest.rs3
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs8
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs8
-rw-r--r--compiler/rustc_lint/src/unused.rs89
-rw-r--r--compiler/rustc_macros/src/query.rs8
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs4
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs14
-rw-r--r--compiler/rustc_middle/src/lib.rs7
-rw-r--r--compiler/rustc_middle/src/macros.rs34
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs32
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs4
-rw-r--r--compiler/rustc_middle/src/mir/type_foldable.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs25
-rw-r--r--compiler/rustc_middle/src/ty/context.rs9
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs3
-rw-r--r--compiler/rustc_middle/src/ty/list.rs30
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs20
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/query.rs14
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs22
-rw-r--r--compiler/rustc_middle/src/ty/visit.rs2
-rw-r--r--compiler/rustc_middle/src/util/call_kind.rs (renamed from compiler/rustc_const_eval/src/util/call_kind.rs)4
-rw-r--r--compiler/rustc_middle/src/util/find_self_call.rs (renamed from compiler/rustc_const_eval/src/util/find_self_call.rs)6
-rw-r--r--compiler/rustc_middle/src/util/mod.rs7
-rw-r--r--compiler/rustc_mir_build/src/errors.rs9
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs6
-rw-r--r--compiler/rustc_mir_transform/src/check_const_item_mutation.rs7
-rw-r--r--compiler/rustc_mir_transform/src/const_prop_lint.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/debug.rs6
-rw-r--r--compiler/rustc_mir_transform/src/deduce_param_attrs.rs5
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs10
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs6
-rw-r--r--compiler/rustc_parse/src/parser/item.rs14
-rw-r--r--compiler/rustc_parse/src/parser/nonterminal.rs10
-rw-r--r--compiler/rustc_passes/messages.ftl6
-rw-r--r--compiler/rustc_passes/src/check_attr.rs12
-rw-r--r--compiler/rustc_passes/src/errors.rs4
-rw-r--r--compiler/rustc_query_system/src/dep_graph/query.rs5
-rw-r--r--compiler/rustc_query_system/src/ich/impls_syntax.rs2
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs30
-rw-r--r--compiler/rustc_span/src/lib.rs11
-rw-r--r--compiler/rustc_span/src/source_map.rs4
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs13
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs22
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs48
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs9
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs8
-rw-r--r--compiler/rustc_traits/src/type_op.rs1
-rw-r--r--compiler/rustc_transmute/src/layout/tree.rs2
-rw-r--r--compiler/rustc_transmute/src/lib.rs9
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs11
-rw-r--r--compiler/rustc_ty_utils/src/structural_match.rs2
-rw-r--r--compiler/rustc_type_ir/src/fold.rs37
-rw-r--r--compiler/rustc_type_ir/src/macros.rs141
-rw-r--r--compiler/rustc_type_ir/src/structural_impls.rs58
-rw-r--r--compiler/rustc_type_ir/src/visit.rs28
-rw-r--r--library/core/src/intrinsics.rs4
-rw-r--r--library/core/tests/num/ieee754.rs1
-rw-r--r--library/std/src/sys/windows/mod.rs9
-rw-r--r--src/bootstrap/bolt.rs2
-rw-r--r--src/bootstrap/bootstrap.py3
-rw-r--r--src/bootstrap/dist.rs3
-rw-r--r--src/bootstrap/lib.rs3
-rw-r--r--src/bootstrap/metadata.rs59
-rw-r--r--src/bootstrap/test.rs4
-rw-r--r--src/bootstrap/tool.rs141
-rw-r--r--src/doc/rustc/src/codegen-options/index.md4
-rw-r--r--src/doc/rustc/src/instrument-coverage.md2
-rw-r--r--src/doc/rustc/src/json.md2
-rw-r--r--src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md2
-rw-r--r--src/doc/rustc/src/platform-support/unknown-uefi.md2
-rw-r--r--src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md9
-rw-r--r--src/doc/style-guide/src/principles.md2
-rw-r--r--src/doc/style-guide/src/types.md2
-rw-r--r--src/doc/unstable-book/src/compiler-flags/check-cfg.md2
-rw-r--r--src/doc/unstable-book/src/compiler-flags/move-size-limit.md2
-rw-r--r--src/doc/unstable-book/src/language-features/transparent-unions.md2
-rw-r--r--src/librustdoc/clean/auto_trait.rs13
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/clean/types.rs8
-rw-r--r--src/librustdoc/config.rs2
-rw-r--r--src/librustdoc/formats/cache.rs7
-rw-r--r--src/librustdoc/html/highlight.rs10
-rw-r--r--src/librustdoc/html/markdown.rs2
-rw-r--r--src/librustdoc/html/render/context.rs10
-rw-r--r--src/librustdoc/html/static/js/main.js6
-rw-r--r--src/librustdoc/json/conversions.rs4
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
-rw-r--r--src/librustdoc/scrape_examples.rs2
-rw-r--r--src/librustdoc/theme/tests.rs4
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_strip.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/open_options.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs2
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/header/needs.rs5
-rw-r--r--src/tools/compiletest/src/header/tests.rs10
-rw-r--r--src/tools/compiletest/src/main.rs2
-rw-r--r--src/tools/miri/README.md14
-rw-r--r--src/tools/miri/src/bin/miri.rs3
-rw-r--r--src/tools/miri/src/borrow_tracker/mod.rs2
-rw-r--r--src/tools/miri/src/diagnostics.rs39
-rw-r--r--src/tools/miri/src/eval.rs19
-rw-r--r--src/tools/miri/src/machine.rs51
-rw-r--r--src/tools/miri/src/tag_gc.rs2
-rw-r--r--src/tools/miri/tests/fail/memleak.rs2
-rw-r--r--src/tools/miri/tests/fail/memleak.stderr23
-rw-r--r--src/tools/miri/tests/fail/memleak_no_backtrace.rs7
-rw-r--r--src/tools/miri/tests/fail/memleak_no_backtrace.stderr4
-rw-r--r--src/tools/miri/tests/fail/memleak_rc.32bit.stderr24
-rw-r--r--src/tools/miri/tests/fail/memleak_rc.64bit.stderr25
-rw-r--r--src/tools/miri/tests/fail/memleak_rc.rs2
-rw-r--r--src/tools/rls/Cargo.toml4
-rw-r--r--src/tools/rustc-workspace-hack/Cargo.toml102
-rw-r--r--src/tools/rustc-workspace-hack/README.md25
-rw-r--r--src/tools/rustc-workspace-hack/lib.rs1
-rw-r--r--src/tools/rustdoc-gui/tester.js10
-rw-r--r--src/tools/tidy/src/deps.rs113
-rw-r--r--tests/codegen-units/item-collection/cross-crate-trait-method.rs2
-rw-r--r--tests/codegen-units/item-collection/function-as-argument.rs3
-rw-r--r--tests/codegen-units/item-collection/generic-functions.rs2
-rw-r--r--tests/codegen-units/item-collection/generic-impl.rs2
-rw-r--r--tests/codegen-units/item-collection/trait-implementations.rs2
-rw-r--r--tests/codegen-units/item-collection/trait-method-as-argument.rs3
-rw-r--r--tests/codegen-units/item-collection/trait-method-default-impl.rs2
-rw-r--r--tests/codegen/align-fn.rs40
-rw-r--r--tests/codegen/array-map.rs2
-rw-r--r--tests/codegen/inline-hint.rs2
-rw-r--r--tests/codegen/local-generics-in-exe-internalized.rs2
-rw-r--r--tests/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs4
-rw-r--r--tests/codegen/remap_path_prefix/xcrate-generic.rs2
-rw-r--r--tests/codegen/thread-local.rs8
-rw-r--r--tests/run-make/issue-107094/Makefile7
-rw-r--r--tests/ui/attributes/invalid-repr.rs5
-rw-r--r--tests/ui/attributes/invalid-repr.stderr12
-rw-r--r--tests/ui/codegen/freeze-on-polymorphic-projection.rs19
-rw-r--r--tests/ui/codegen/freeze-on-polymorphic-projection.stderr12
-rw-r--r--tests/ui/consts/auxiliary/foreign-generic-mismatch-with-const-arg.rs1
-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/lint/unused/issue-54538-unused-parens-lint.fixed19
-rw-r--r--tests/ui/lint/unused/issue-54538-unused-parens-lint.rs19
-rw-r--r--tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr62
-rw-r--r--tests/ui/rfc-2632-const-trait-impl/trait-method-ptr-in-consts-ice.rs23
-rw-r--r--tests/ui/transmutability/references.current.stderr4
-rw-r--r--tests/ui/transmutability/references.next.stderr4
-rw-r--r--tests/ui/transmutability/region-infer.rs22
-rw-r--r--tests/ui/transmutability/region-infer.stderr23
210 files changed, 2430 insertions, 3503 deletions
diff --git a/Cargo.lock b/Cargo.lock
index df6f0425954..da2e483fe61 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -42,7 +42,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bf6ccdb167abbf410dcb915cabd428929d7f6a04980b54a11f26a39f1c7f7107"
 dependencies = [
  "cfg-if",
- "getrandom",
  "once_cell",
  "version_check",
 ]
@@ -108,7 +107,7 @@ dependencies = [
  "anstyle-parse",
  "anstyle-wincon",
  "concolor-override",
- "concolor-query 0.3.3",
+ "concolor-query",
  "is-terminal",
  "utf8parse",
 ]
@@ -154,12 +153,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "arc-swap"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
-
-[[package]]
 name = "array_tool"
 version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -167,12 +160,6 @@ checksum = "8f8cb5d814eb646a863c4f24978cff2880c4be96ad8cde2c0f0678732902e271"
 
 [[package]]
 name = "arrayvec"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
-
-[[package]]
-name = "arrayvec"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5a2f58b0bb10c380af2b26e57212856b8c9a59e0925b4c20f4a174a49734eaf7"
@@ -242,24 +229,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "base16ct"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce"
-
-[[package]]
-name = "base64"
-version = "0.21.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
-
-[[package]]
-name = "base64ct"
-version = "1.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf"
-
-[[package]]
 name = "basic-toml"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -275,15 +244,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
-name = "bitmaps"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2"
-dependencies = [
- "typenum",
-]
-
-[[package]]
 name = "block-buffer"
 version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -316,15 +276,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "btoi"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9dd6407f73a9b8b6162d8a2ef999fe6afd7cc15902ebf42c5cd296addf17e0ad"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
 name = "build-manifest"
 version = "0.1.0"
 dependencies = [
@@ -336,7 +287,7 @@ dependencies = [
  "serde_json",
  "sha2",
  "tar",
- "toml 0.5.7",
+ "toml",
 ]
 
 [[package]]
@@ -352,16 +303,10 @@ dependencies = [
  "indexmap",
  "serde",
  "serde_json",
- "toml 0.5.7",
+ "toml",
 ]
 
 [[package]]
-name = "bumpalo"
-version = "3.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
-
-[[package]]
 name = "bytecount"
 version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -377,12 +322,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
 
 [[package]]
-name = "bytesize"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da"
-
-[[package]]
 name = "camino"
 version = "1.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -392,108 +331,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "cargo"
-version = "0.71.0"
-dependencies = [
- "anyhow",
- "base64",
- "bytesize",
- "cargo-platform 0.1.2",
- "cargo-test-macro",
- "cargo-test-support",
- "cargo-util",
- "clap 4.2.1",
- "crates-io",
- "curl",
- "curl-sys",
- "env_logger 0.10.0",
- "filetime",
- "flate2",
- "fwdansi",
- "git2",
- "git2-curl",
- "gix",
- "gix-features",
- "glob",
- "hex",
- "hmac",
- "home",
- "http-auth",
- "humantime 2.0.1",
- "ignore",
- "im-rc",
- "indexmap",
- "is-terminal",
- "itertools",
- "jobserver",
- "lazy_static",
- "lazycell",
- "libc",
- "libgit2-sys",
- "log",
- "memchr",
- "opener",
- "openssl",
- "os_info",
- "pasetors",
- "pathdiff",
- "pretty_env_logger",
- "rand",
- "rustc-workspace-hack",
- "rustfix",
- "same-file",
- "semver",
- "serde",
- "serde-value",
- "serde_ignored",
- "serde_json",
- "sha1",
- "shell-escape",
- "snapbox",
- "strip-ansi-escapes",
- "tar",
- "tempfile",
- "termcolor",
- "time 0.3.17",
- "toml 0.7.2",
- "toml_edit",
- "unicode-width",
- "unicode-xid",
- "url",
- "walkdir",
- "windows-sys 0.45.0",
-]
-
-[[package]]
-name = "cargo-credential"
-version = "0.2.0"
-
-[[package]]
-name = "cargo-credential-1password"
-version = "0.2.0"
-dependencies = [
- "cargo-credential",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "cargo-credential-macos-keychain"
-version = "0.2.0"
-dependencies = [
- "cargo-credential",
- "security-framework",
-]
-
-[[package]]
-name = "cargo-credential-wincred"
-version = "0.2.0"
-dependencies = [
- "cargo-credential",
- "windows-sys 0.45.0",
-]
-
-[[package]]
 name = "cargo-miri"
 version = "0.1.0"
 dependencies = [
@@ -510,13 +347,6 @@ dependencies = [
 [[package]]
 name = "cargo-platform"
 version = "0.1.2"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "cargo-platform"
-version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27"
 dependencies = [
@@ -524,63 +354,13 @@ dependencies = [
 ]
 
 [[package]]
-name = "cargo-test-macro"
-version = "0.1.0"
-
-[[package]]
-name = "cargo-test-support"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "cargo-test-macro",
- "cargo-util",
- "crates-io",
- "filetime",
- "flate2",
- "git2",
- "glob",
- "itertools",
- "lazy_static",
- "pasetors",
- "serde",
- "serde_json",
- "snapbox",
- "tar",
- "termcolor",
- "time 0.3.17",
- "toml 0.7.2",
- "url",
- "windows-sys 0.45.0",
-]
-
-[[package]]
-name = "cargo-util"
-version = "0.2.4"
-dependencies = [
- "anyhow",
- "core-foundation",
- "filetime",
- "hex",
- "jobserver",
- "libc",
- "log",
- "miow 0.5.0",
- "same-file",
- "sha2",
- "shell-escape",
- "tempfile",
- "walkdir",
- "windows-sys 0.45.0",
-]
-
-[[package]]
 name = "cargo_metadata"
 version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c297bd3135f558552f99a0daa180876984ea2c4ffa7470314540dff8c654109a"
 dependencies = [
  "camino",
- "cargo-platform 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo-platform",
  "semver",
  "serde",
  "serde_json",
@@ -593,7 +373,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "08a1ec454bc3eead8719cb56e15dbbfecdbc14e4b3a3ae4936cc6e31f5fc0d07"
 dependencies = [
  "camino",
- "cargo-platform 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo-platform",
  "semver",
  "serde",
  "serde_json",
@@ -609,9 +389,6 @@ name = "cc"
 version = "1.0.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
-dependencies = [
- "jobserver",
-]
 
 [[package]]
 name = "cfg-if"
@@ -687,7 +464,7 @@ dependencies = [
  "num-integer",
  "num-traits",
  "serde",
- "time 0.1.43",
+ "time",
  "winapi",
 ]
 
@@ -809,7 +586,7 @@ dependencies = [
  "termize",
  "tester",
  "tokio",
- "toml 0.5.7",
+ "toml",
  "walkdir",
 ]
 
@@ -830,7 +607,7 @@ dependencies = [
 name = "clippy_lints"
 version = "0.1.70"
 dependencies = [
- "arrayvec 0.7.0",
+ "arrayvec",
  "cargo_metadata 0.15.3",
  "clippy_utils",
  "declare_clippy_lint",
@@ -844,7 +621,7 @@ dependencies = [
  "serde",
  "serde_json",
  "tempfile",
- "toml 0.5.7",
+ "toml",
  "unicode-normalization",
  "unicode-script",
  "url",
@@ -854,19 +631,13 @@ dependencies = [
 name = "clippy_utils"
 version = "0.1.70"
 dependencies = [
- "arrayvec 0.7.0",
+ "arrayvec",
  "if_chain",
  "itertools",
  "rustc-semver",
 ]
 
 [[package]]
-name = "clru"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8191fa7302e03607ff0e237d4246cc043ff5b3cb9409d995172ba3bea16b807"
-
-[[package]]
 name = "collect-license-metadata"
 version = "0.1.0"
 dependencies = [
@@ -946,7 +717,7 @@ dependencies = [
  "tracing-subscriber",
  "unified-diff",
  "walkdir",
- "windows 0.46.0",
+ "windows",
 ]
 
 [[package]]
@@ -973,17 +744,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "concolor"
-version = "0.0.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b90f9dcd9490a97db91a85ccd79e38a87e14323f0bb824659ee3274e9143ba37"
-dependencies = [
- "atty",
- "bitflags",
- "concolor-query 0.1.0",
-]
-
-[[package]]
 name = "concolor-override"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -991,12 +751,6 @@ checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f"
 
 [[package]]
 name = "concolor-query"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317"
-
-[[package]]
-name = "concolor-query"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf"
@@ -1005,21 +759,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "const-oid"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b"
-
-[[package]]
-name = "content_inspector"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38"
-dependencies = [
- "memchr",
-]
-
-[[package]]
 name = "convert_case"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1034,22 +773,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "core-foundation"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b5ed8e7e76c45974e15e41bfa8d5b0483cd90191639e01d8f5f1e606299d3fb"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "core-foundation-sys"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6"
-
-[[package]]
 name = "coverage_test_macros"
 version = "0.0.0"
 
@@ -1063,18 +786,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "crates-io"
-version = "0.36.0"
-dependencies = [
- "anyhow",
- "curl",
- "percent-encoding",
- "serde",
- "serde_json",
- "url",
-]
-
-[[package]]
 name = "crc32fast"
 version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1127,18 +838,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "crypto-bigint"
-version = "0.4.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef"
-dependencies = [
- "generic-array",
- "rand_core",
- "subtle",
- "zeroize",
-]
-
-[[package]]
 name = "crypto-common"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1159,22 +858,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "ct-codecs"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df"
-
-[[package]]
-name = "ctor"
-version = "0.1.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
-dependencies = [
- "quote",
- "syn 1.0.102",
-]
-
-[[package]]
 name = "curl"
 version = "0.4.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1197,7 +880,6 @@ checksum = "14d05c10f541ae6f3bc5b3d923c20001f47db7d5f0b2bc6ad16490133842db79"
 dependencies = [
  "cc",
  "libc",
- "libnghttp2-sys",
  "libz-sys",
  "openssl-sys",
  "pkg-config",
@@ -1221,17 +903,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "der"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de"
-dependencies = [
- "const-oid",
- "pem-rfc7468",
- "zeroize",
-]
-
-[[package]]
 name = "derive-new"
 version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1269,7 +940,6 @@ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
 dependencies = [
  "block-buffer",
  "crypto-common",
- "subtle",
 ]
 
 [[package]]
@@ -1351,33 +1021,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "dunce"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c"
-
-[[package]]
-name = "ecdsa"
-version = "0.14.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c"
-dependencies = [
- "der",
- "elliptic-curve",
- "rfc6979",
- "signature",
-]
-
-[[package]]
-name = "ed25519-compact"
-version = "2.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a3d382e8464107391c8706b4c14b087808ecb909f6c15c34114bc42e53a9e4c"
-dependencies = [
- "getrandom",
-]
-
-[[package]]
 name = "either"
 version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1396,28 +1039,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "elliptic-curve"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3"
-dependencies = [
- "base16ct",
- "crypto-bigint",
- "der",
- "digest",
- "ff",
- "generic-array",
- "group",
- "hkdf",
- "pem-rfc7468",
- "pkcs8",
- "rand_core",
- "sec1",
- "subtle",
- "zeroize",
-]
-
-[[package]]
 name = "elsa"
 version = "1.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1547,22 +1168,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "ff"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160"
-dependencies = [
- "rand_core",
- "subtle",
-]
-
-[[package]]
-name = "fiat-crypto"
-version = "0.1.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a214f5bb88731d436478f3ae1f8a277b62124089ba9fb67f4f93fb100ef73c90"
-
-[[package]]
 name = "filetime"
 version = "0.2.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1589,7 +1194,6 @@ dependencies = [
  "cfg-if",
  "crc32fast",
  "libc",
- "libz-sys",
  "miniz_oxide",
 ]
 
@@ -1634,21 +1238,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
 [[package]]
-name = "foreign-types"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
-dependencies = [
- "foreign-types-shared",
-]
-
-[[package]]
-name = "foreign-types-shared"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
-
-[[package]]
 name = "form_urlencoded"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1774,16 +1363,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "fwdansi"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c1f5787fe85505d1f7777268db5103d80a7a374d2316a7ce262e57baf8f208"
-dependencies = [
- "memchr",
- "termcolor",
-]
-
-[[package]]
 name = "generate-copyright"
 version = "0.1.0"
 dependencies = [
@@ -1820,10 +1399,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
 dependencies = [
  "cfg-if",
- "js-sys",
  "libc",
  "wasi",
- "wasm-bindgen",
 ]
 
 [[package]]
@@ -1841,586 +1418,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "git2"
-version = "0.17.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89511277159354bea13ae1e53e0c9ab85ba1b20d7e91618fa30e6bc5566857fb"
-dependencies = [
- "bitflags",
- "libc",
- "libgit2-sys",
- "log",
- "openssl-probe",
- "openssl-sys",
- "url",
-]
-
-[[package]]
-name = "git2-curl"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8f8b7432b72928cff76f69e59ed5327f94a52763731e71274960dee72fe5f8c"
-dependencies = [
- "curl",
- "git2",
- "log",
- "url",
-]
-
-[[package]]
-name = "gix"
-version = "0.39.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dabfac58aecb4a38cdd2568de66eb1f0d968fd6726f5a80cb8bea7944ef10cc0"
-dependencies = [
- "gix-actor",
- "gix-attributes",
- "gix-config",
- "gix-credentials",
- "gix-date",
- "gix-diff",
- "gix-discover",
- "gix-features",
- "gix-glob",
- "gix-hash",
- "gix-hashtable",
- "gix-index",
- "gix-lock",
- "gix-mailmap",
- "gix-object",
- "gix-odb",
- "gix-pack",
- "gix-path",
- "gix-prompt",
- "gix-protocol",
- "gix-ref",
- "gix-refspec",
- "gix-revision",
- "gix-sec",
- "gix-tempfile",
- "gix-transport",
- "gix-traverse",
- "gix-url",
- "gix-validate",
- "gix-worktree",
- "log",
- "once_cell",
- "prodash",
- "signal-hook",
- "smallvec",
- "thiserror",
- "unicode-normalization",
-]
-
-[[package]]
-name = "gix-actor"
-version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc22b0cdc52237667c301dd7cdc6ead8f8f73c9f824e9942c8ebd6b764f6c0bf"
-dependencies = [
- "bstr 1.3.0",
- "btoi",
- "gix-date",
- "itoa",
- "nom",
- "thiserror",
-]
-
-[[package]]
-name = "gix-attributes"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2231a25934a240d0a4b6f4478401c73ee81d8be52de0293eedbc172334abf3e1"
-dependencies = [
- "bstr 1.3.0",
- "gix-features",
- "gix-glob",
- "gix-path",
- "gix-quote",
- "thiserror",
- "unicode-bom",
-]
-
-[[package]]
-name = "gix-bitmap"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "024bca0c7187517bda5ea24ab148c9ca8208dd0c3e2bea88cdb2008f91791a6d"
-dependencies = [
- "thiserror",
-]
-
-[[package]]
-name = "gix-chunk"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0d39583cab06464b8bf73b3f1707458270f0e7383cb24c3c9c1a16e6f792978"
-dependencies = [
- "thiserror",
-]
-
-[[package]]
-name = "gix-command"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2c6f75c1e0f924de39e750880a6e21307194bb1ab773efe3c7d2d787277f8ab"
-dependencies = [
- "bstr 1.3.0",
-]
-
-[[package]]
-name = "gix-config"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52c62e26ce11f607712e4f49a0a192ed87675d30187fd61be070abbd607d12f1"
-dependencies = [
- "bstr 1.3.0",
- "gix-config-value",
- "gix-features",
- "gix-glob",
- "gix-path",
- "gix-ref",
- "gix-sec",
- "memchr",
- "nom",
- "once_cell",
- "smallvec",
- "thiserror",
- "unicode-bom",
-]
-
-[[package]]
-name = "gix-config-value"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "693d4a4ba0531e46fe558459557a5b29fb86c3e4b2666c1c0861d93c7c678331"
-dependencies = [
- "bitflags",
- "bstr 1.3.0",
- "gix-path",
- "libc",
- "thiserror",
-]
-
-[[package]]
-name = "gix-credentials"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5be32b5fe339a31b8e53fa854081dc914c45020dcb64637f3c21baf69c96fc1b"
-dependencies = [
- "bstr 1.3.0",
- "gix-command",
- "gix-config-value",
- "gix-path",
- "gix-prompt",
- "gix-sec",
- "gix-url",
- "thiserror",
-]
-
-[[package]]
-name = "gix-date"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b96271912ce39822501616f177dea7218784e6c63be90d5f36322ff3a722aae2"
-dependencies = [
- "bstr 1.3.0",
- "itoa",
- "thiserror",
- "time 0.3.17",
-]
-
-[[package]]
-name = "gix-diff"
-version = "0.28.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "585b0834d4b6791a848637c4e109545fda9b0f29b591ba55edb33ceda6e7856b"
-dependencies = [
- "gix-hash",
- "gix-object",
- "imara-diff",
- "thiserror",
-]
-
-[[package]]
-name = "gix-discover"
-version = "0.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91c204adba5ebd211c74735cbb65817d277e154486bac0dffa3701f163b80350"
-dependencies = [
- "bstr 1.3.0",
- "dunce",
- "gix-hash",
- "gix-path",
- "gix-ref",
- "gix-sec",
- "thiserror",
-]
-
-[[package]]
-name = "gix-features"
-version = "0.28.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e6a9dfa7b3c1a99315203e8b97f8f99f3bd95731590607abeaa5ca31bc41fe3"
-dependencies = [
- "bytes",
- "crc32fast",
- "crossbeam-channel",
- "flate2",
- "gix-hash",
- "libc",
- "once_cell",
- "parking_lot 0.12.1",
- "prodash",
- "sha1_smol",
- "thiserror",
- "walkdir",
-]
-
-[[package]]
-name = "gix-glob"
-version = "0.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93e43efd776bc543f46f0fd0ca3d920c37af71a764a16f2aebd89765e9ff2993"
-dependencies = [
- "bitflags",
- "bstr 1.3.0",
-]
-
-[[package]]
-name = "gix-hash"
-version = "0.10.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c0c5a9f4d621d4f4ea046bb331df5c746ca735b8cae5b234cc2be70ee4dbef0"
-dependencies = [
- "hex",
- "thiserror",
-]
-
-[[package]]
-name = "gix-hashtable"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9609c1b8f36f12968e6a6098f7cdb52004f7d42d570f47a2d6d7c16612f19acb"
-dependencies = [
- "gix-hash",
- "hashbrown 0.13.1",
- "parking_lot 0.12.1",
-]
-
-[[package]]
-name = "gix-index"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c12caf7886c7ba06f2b28835cdc2be1dca86bd047d00299d2d49e707ce1c2616"
-dependencies = [
- "bitflags",
- "bstr 1.3.0",
- "btoi",
- "filetime",
- "gix-bitmap",
- "gix-features",
- "gix-hash",
- "gix-lock",
- "gix-object",
- "gix-traverse",
- "itoa",
- "memmap2 0.5.10",
- "smallvec",
- "thiserror",
-]
-
-[[package]]
-name = "gix-lock"
-version = "4.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66119ff8a4a395d0ea033fef718bc85f8b4f0855874f4ce1e005fc16cfe1f66e"
-dependencies = [
- "fastrand",
- "gix-tempfile",
- "thiserror",
-]
-
-[[package]]
-name = "gix-mailmap"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b66aea5e52875cd4915f4957a6f4b75831a36981e2ec3f5fad9e370e444fe1a"
-dependencies = [
- "bstr 1.3.0",
- "gix-actor",
- "thiserror",
-]
-
-[[package]]
-name = "gix-object"
-version = "0.28.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8df068db9180ee935fbb70504848369e270bdcb576b05c0faa8b9fd3b86fc017"
-dependencies = [
- "bstr 1.3.0",
- "btoi",
- "gix-actor",
- "gix-features",
- "gix-hash",
- "gix-validate",
- "hex",
- "itoa",
- "nom",
- "smallvec",
- "thiserror",
-]
-
-[[package]]
-name = "gix-odb"
-version = "0.42.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9a5f9e1afbd509761977a2ea02869cedaaba500b4e783deb2e4de5179a55a80"
-dependencies = [
- "arc-swap",
- "gix-features",
- "gix-hash",
- "gix-object",
- "gix-pack",
- "gix-path",
- "gix-quote",
- "parking_lot 0.12.1",
- "tempfile",
- "thiserror",
-]
-
-[[package]]
-name = "gix-pack"
-version = "0.32.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51db84e1459a8022e518d40a8778028d793dbb28e4d35c9a5eaf92658fb0775"
-dependencies = [
- "clru",
- "gix-chunk",
- "gix-diff",
- "gix-features",
- "gix-hash",
- "gix-hashtable",
- "gix-object",
- "gix-path",
- "gix-tempfile",
- "gix-traverse",
- "memmap2 0.5.10",
- "parking_lot 0.12.1",
- "smallvec",
- "thiserror",
-]
-
-[[package]]
-name = "gix-packetline"
-version = "0.14.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d63e5e5a9a92d4fc6b63ff9d94954d25c779ce25c98d5bbe2e4399aa42f7073c"
-dependencies = [
- "bstr 1.3.0",
- "hex",
- "thiserror",
-]
-
-[[package]]
-name = "gix-path"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6c104a66dec149cb8f7aaafc6ab797654cf82d67f050fd0cb7e7294e328354b"
-dependencies = [
- "bstr 1.3.0",
- "thiserror",
-]
-
-[[package]]
-name = "gix-prompt"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a20cebf73229debaa82574c4fd20dcaf00fa8d4bfce823a862c4e990d7a0b5b4"
-dependencies = [
- "gix-command",
- "gix-config-value",
- "nix",
- "parking_lot 0.12.1",
- "thiserror",
-]
-
-[[package]]
-name = "gix-protocol"
-version = "0.28.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d372ab11d5d28ac21800e3f1a6603a67c1ead57f6f5fab07e1e73e960f331c1"
-dependencies = [
- "bstr 1.3.0",
- "btoi",
- "gix-credentials",
- "gix-features",
- "gix-hash",
- "gix-transport",
- "maybe-async",
- "nom",
- "thiserror",
-]
-
-[[package]]
-name = "gix-quote"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a282f5a8d9ee0b09ec47390ac727350c48f2f5c76d803cd8da6b3e7ad56e0bcb"
-dependencies = [
- "bstr 1.3.0",
- "btoi",
- "thiserror",
-]
-
-[[package]]
-name = "gix-ref"
-version = "0.26.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90a0ed29e581f04b904ecd0c32b11f33b8209b5a0af9c43f415249a4f2fba632"
-dependencies = [
- "gix-actor",
- "gix-features",
- "gix-hash",
- "gix-lock",
- "gix-object",
- "gix-path",
- "gix-tempfile",
- "gix-validate",
- "memmap2 0.5.10",
- "nom",
- "thiserror",
-]
-
-[[package]]
-name = "gix-refspec"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aba332462bda2e8efeae4302b39a6ed01ad56ef772fd5b7ef197cf2798294d65"
-dependencies = [
- "bstr 1.3.0",
- "gix-hash",
- "gix-revision",
- "gix-validate",
- "smallvec",
- "thiserror",
-]
-
-[[package]]
-name = "gix-revision"
-version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed98e4a0254953c64bc913bd23146a1de662067d5cf974cbdde396958b39e5b0"
-dependencies = [
- "bstr 1.3.0",
- "gix-date",
- "gix-hash",
- "gix-hashtable",
- "gix-object",
- "thiserror",
-]
-
-[[package]]
-name = "gix-sec"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8ffa5bf0772f9b01de501c035b6b084cf9b8bb07dec41e3afc6a17336a65f47"
-dependencies = [
- "bitflags",
- "dirs",
- "gix-path",
- "libc",
- "windows 0.43.0",
-]
-
-[[package]]
-name = "gix-tempfile"
-version = "4.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88751f247234b1f73c8e8056fd835a0999b04e596e052302cb71186005dc4b27"
-dependencies = [
- "libc",
- "once_cell",
- "parking_lot 0.12.1",
- "signal-hook",
- "signal-hook-registry",
- "tempfile",
-]
-
-[[package]]
-name = "gix-transport"
-version = "0.27.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d633947b36a2fbbc089195bdc71621158f1660c2ff2a6b12b0279c16e2f764bc"
-dependencies = [
- "base64",
- "bstr 1.3.0",
- "curl",
- "gix-command",
- "gix-credentials",
- "gix-features",
- "gix-packetline",
- "gix-quote",
- "gix-sec",
- "gix-url",
- "thiserror",
-]
-
-[[package]]
-name = "gix-traverse"
-version = "0.24.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd9a4a07bb22168dc79c60e1a6a41919d198187ca83d8a5940ad8d7122a45df3"
-dependencies = [
- "gix-hash",
- "gix-hashtable",
- "gix-object",
- "thiserror",
-]
-
-[[package]]
-name = "gix-url"
-version = "0.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "044072b7ce8601b62dcec841b92129f5cc677072823324121b395d766ac5f528"
-dependencies = [
- "bstr 1.3.0",
- "gix-features",
- "gix-path",
- "home",
- "thiserror",
- "url",
-]
-
-[[package]]
-name = "gix-validate"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b69ddb780ea1465255e66818d75b7098371c58dbc9560da4488a44b9f5c7e443"
-dependencies = [
- "bstr 1.3.0",
- "thiserror",
-]
-
-[[package]]
-name = "gix-worktree"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cb9af6e56152953d8fe113c4f9d7cf60cf7a982362711e9200a255579b49cb"
-dependencies = [
- "bstr 1.3.0",
- "gix-attributes",
- "gix-features",
- "gix-glob",
- "gix-hash",
- "gix-index",
- "gix-object",
- "gix-path",
- "io-close",
- "thiserror",
-]
-
-[[package]]
 name = "glob"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2440,17 +1437,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "group"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7"
-dependencies = [
- "ff",
- "rand_core",
- "subtle",
-]
-
-[[package]]
 name = "gsgdt"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2461,21 +1447,6 @@ dependencies = [
 
 [[package]]
 name = "handlebars"
-version = "3.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4498fc115fa7d34de968184e473529abb40eeb6be8bc5f7faba3d08c316cb3e3"
-dependencies = [
- "log",
- "pest",
- "pest_derive",
- "quick-error 2.0.1",
- "serde",
- "serde_json",
- "walkdir",
-]
-
-[[package]]
-name = "handlebars"
 version = "4.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "360d9740069b2f6cbb63ce2dbaa71a20d3185350cbb990d7bebeb9318415eb17"
@@ -2542,33 +1513,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
 
 [[package]]
-name = "hkdf"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437"
-dependencies = [
- "hmac",
-]
-
-[[package]]
-name = "hmac"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
-dependencies = [
- "digest",
-]
-
-[[package]]
-name = "home"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
-dependencies = [
- "winapi",
-]
-
-[[package]]
 name = "html-checker"
 version = "0.1.0"
 dependencies = [
@@ -2591,21 +1535,12 @@ dependencies = [
 ]
 
 [[package]]
-name = "http-auth"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0b40b39d66c28829a0cf4d09f7e139ff8201f7500a5083732848ed3b4b4d850"
-dependencies = [
- "memchr",
-]
-
-[[package]]
 name = "humantime"
 version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
 dependencies = [
- "quick-error 1.2.3",
+ "quick-error",
 ]
 
 [[package]]
@@ -2715,30 +1650,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "im-rc"
-version = "15.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe"
-dependencies = [
- "bitmaps",
- "rand_core",
- "rand_xoshiro",
- "sized-chunks",
- "typenum",
- "version_check",
-]
-
-[[package]]
-name = "imara-diff"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e98c1d0ad70fc91b8b9654b1f33db55e59579d3b3de2bffdced0fdb810570cb8"
-dependencies = [
- "ahash 0.8.2",
- "hashbrown 0.12.3",
-]
-
-[[package]]
 name = "indenter"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2806,16 +1717,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "io-close"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc"
-dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
 name = "io-lifetimes"
 version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2872,15 +1773,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "js-sys"
-version = "0.3.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
-dependencies = [
- "wasm-bindgen",
-]
-
-[[package]]
 name = "jsondocck"
 version = "0.1.0"
 dependencies = [
@@ -2960,20 +1852,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "libgit2-sys"
-version = "0.15.0+1.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "032e537ae4dd4e50c877f258dc55fcd0657b5021f454094a425bb6bcc9edea4c"
-dependencies = [
- "cc",
- "libc",
- "libssh2-sys",
- "libz-sys",
- "openssl-sys",
- "pkg-config",
-]
-
-[[package]]
 name = "libloading"
 version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2990,30 +1868,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
 
 [[package]]
-name = "libnghttp2-sys"
-version = "0.1.4+1.41.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03624ec6df166e79e139a2310ca213283d6b3c30810c54844f307086d4488df1"
-dependencies = [
- "cc",
- "libc",
-]
-
-[[package]]
-name = "libssh2-sys"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee"
-dependencies = [
- "cc",
- "libc",
- "libz-sys",
- "openssl-sys",
- "pkg-config",
- "vcpkg",
-]
-
-[[package]]
 name = "libz-sys"
 version = "1.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3136,17 +1990,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
 
 [[package]]
-name = "maybe-async"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.102",
-]
-
-[[package]]
 name = "md-5"
 version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3168,7 +2011,7 @@ dependencies = [
  "clap_complete",
  "elasticlunr-rs",
  "env_logger 0.10.0",
- "handlebars 4.3.3",
+ "handlebars",
  "log",
  "memchr",
  "once_cell",
@@ -3179,31 +2022,18 @@ dependencies = [
  "serde_json",
  "shlex",
  "tempfile",
- "toml 0.5.7",
+ "toml",
  "topological-sort",
 ]
 
 [[package]]
-name = "mdman"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "handlebars 3.5.5",
- "pretty_assertions",
- "pulldown-cmark",
- "same-file",
- "serde_json",
- "url",
-]
-
-[[package]]
 name = "measureme"
 version = "10.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cbdc226fa10994e8f66a4d2f6f000148bc563a1c671b6dcd2135737018033d8a"
 dependencies = [
  "log",
- "memmap2 0.2.1",
+ "memmap2",
  "parking_lot 0.11.2",
  "perf-event-open-sys",
  "rustc-hash",
@@ -3230,15 +2060,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "memmap2"
-version = "0.5.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
-dependencies = [
- "libc",
-]
-
-[[package]]
 name = "memoffset"
 version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3340,18 +2161,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
 
 [[package]]
-name = "nix"
-version = "0.26.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
-dependencies = [
- "bitflags",
- "cfg-if",
- "libc",
- "static_assertions",
-]
-
-[[package]]
 name = "nom"
 version = "7.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3363,21 +2172,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "nom8"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "normalize-line-endings"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
-
-[[package]]
 name = "num-integer"
 version = "0.1.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3407,15 +2201,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "num_threads"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
-dependencies = [
- "libc",
-]
-
-[[package]]
 name = "object"
 version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3466,47 +2251,12 @@ dependencies = [
 ]
 
 [[package]]
-name = "openssl"
-version = "0.10.49"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d2f106ab837a24e03672c59b1239669a0596406ff657c3c0835b6b7f0f35a33"
-dependencies = [
- "bitflags",
- "cfg-if",
- "foreign-types",
- "libc",
- "once_cell",
- "openssl-macros",
- "openssl-sys",
-]
-
-[[package]]
-name = "openssl-macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.8",
-]
-
-[[package]]
 name = "openssl-probe"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
 
 [[package]]
-name = "openssl-src"
-version = "111.25.0+1.1.1t"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3173cd3626c43e3854b1b727422a276e568d9ec5fe8cec197822cf52cfb743d6"
-dependencies = [
- "cc",
-]
-
-[[package]]
 name = "openssl-sys"
 version = "0.9.84"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3514,75 +2264,23 @@ checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa"
 dependencies = [
  "cc",
  "libc",
- "openssl-src",
  "pkg-config",
  "vcpkg",
 ]
 
 [[package]]
-name = "ordered-float"
-version = "2.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
-name = "orion"
-version = "0.17.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2baf7fd2e326e3895c681176788dd227fcd8369350e53c570592d8563fecbb6"
-dependencies = [
- "fiat-crypto",
- "subtle",
- "zeroize",
-]
-
-[[package]]
-name = "os_info"
-version = "3.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5209b2162b2c140df493a93689e04f8deab3a67634f5bc7a553c0a98e5b8d399"
-dependencies = [
- "log",
- "serde",
- "winapi",
-]
-
-[[package]]
 name = "os_str_bytes"
 version = "6.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
 
 [[package]]
-name = "output_vt100"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66"
-dependencies = [
- "winapi",
-]
-
-[[package]]
 name = "owo-colors"
 version = "3.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
 
 [[package]]
-name = "p384"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa"
-dependencies = [
- "ecdsa",
- "elliptic-curve",
- "sha2",
-]
-
-[[package]]
 name = "packed_simd_2"
 version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3664,42 +2362,12 @@ dependencies = [
 ]
 
 [[package]]
-name = "pasetors"
-version = "0.6.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed20c4c21d893414f42e0cbfebe8a8036b5ae9b0264611fb6504e395eda6ceec"
-dependencies = [
- "ct-codecs",
- "ed25519-compact",
- "getrandom",
- "orion",
- "p384",
- "rand_core",
- "regex",
- "serde",
- "serde_json",
- "sha2",
- "subtle",
- "time 0.3.17",
- "zeroize",
-]
-
-[[package]]
 name = "pathdiff"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
 
 [[package]]
-name = "pem-rfc7468"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac"
-dependencies = [
- "base64ct",
-]
-
-[[package]]
 name = "percent-encoding"
 version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3819,16 +2487,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
 [[package]]
-name = "pkcs8"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba"
-dependencies = [
- "der",
- "spki",
-]
-
-[[package]]
 name = "pkg-config"
 version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3858,28 +2516,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 
 [[package]]
-name = "pretty_assertions"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755"
-dependencies = [
- "ctor",
- "diff",
- "output_vt100",
- "yansi",
-]
-
-[[package]]
-name = "pretty_env_logger"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d"
-dependencies = [
- "env_logger 0.7.1",
- "log",
-]
-
-[[package]]
 name = "proc-macro-error"
 version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3927,15 +2563,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "prodash"
-version = "23.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d73c6b64cb5b99eb63ca97d378685712617ec0172ff5c04cd47a489d3e2c51f8"
-dependencies = [
- "parking_lot 0.12.1",
-]
-
-[[package]]
 name = "profiler_builtins"
 version = "0.0.0"
 dependencies = [
@@ -3977,12 +2604,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
 
 [[package]]
-name = "quick-error"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
-
-[[package]]
 name = "quine-mc_cluskey"
 version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4149,21 +2770,9 @@ dependencies = [
 ]
 
 [[package]]
-name = "rfc6979"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb"
-dependencies = [
- "crypto-bigint",
- "hmac",
- "zeroize",
-]
-
-[[package]]
 name = "rls"
 version = "2.0.0"
 dependencies = [
- "rustc-workspace-hack",
  "serde",
  "serde_json",
 ]
@@ -4275,22 +2884,8 @@ dependencies = [
 [[package]]
 name = "rustc-workspace-hack"
 version = "1.0.0"
-dependencies = [
- "bstr 0.2.17",
- "clap 3.2.20",
- "getrandom",
- "hashbrown 0.12.3",
- "libc",
- "libz-sys",
- "once_cell",
- "rand",
- "regex",
- "serde_json",
- "smallvec",
- "syn 1.0.102",
- "url",
- "winapi",
-]
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc71d2faa173b74b232dedc235e3ee1696581bb132fc116fa3626d6151a1a8fb"
 
 [[package]]
 name = "rustc_abi"
@@ -4421,7 +3016,6 @@ dependencies = [
  "either",
  "itertools",
  "polonius-engine",
- "rustc_const_eval",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_graphviz",
@@ -4568,7 +3162,7 @@ dependencies = [
 name = "rustc_data_structures"
 version = "0.0.0"
 dependencies = [
- "arrayvec 0.7.0",
+ "arrayvec",
  "bitflags",
  "cfg-if",
  "elsa",
@@ -4578,7 +3172,7 @@ dependencies = [
  "jobserver",
  "libc",
  "measureme",
- "memmap2 0.2.1",
+ "memmap2",
  "parking_lot 0.11.2",
  "rustc-hash",
  "rustc-rayon",
@@ -4593,7 +3187,7 @@ dependencies = [
  "tempfile",
  "thin-vec",
  "tracing",
- "windows 0.46.0",
+ "windows",
 ]
 
 [[package]]
@@ -4652,7 +3246,7 @@ dependencies = [
  "rustc_ty_utils",
  "serde_json",
  "tracing",
- "windows 0.46.0",
+ "windows",
 ]
 
 [[package]]
@@ -4700,7 +3294,7 @@ dependencies = [
  "termize",
  "tracing",
  "unicode-width",
- "windows 0.46.0",
+ "windows",
 ]
 
 [[package]]
@@ -4774,7 +3368,7 @@ dependencies = [
  "rustc_hir",
  "rustc_index",
  "rustc_infer",
- "rustc_lint",
+ "rustc_lint_defs",
  "rustc_macros",
  "rustc_middle",
  "rustc_session",
@@ -4848,7 +3442,7 @@ dependencies = [
 name = "rustc_index"
 version = "0.0.0"
 dependencies = [
- "arrayvec 0.7.0",
+ "arrayvec",
  "rustc_macros",
  "rustc_serialize",
  "smallvec",
@@ -5343,7 +3937,7 @@ dependencies = [
  "smallvec",
  "termize",
  "tracing",
- "windows 0.46.0",
+ "windows",
 ]
 
 [[package]]
@@ -5520,7 +4114,7 @@ dependencies = [
 name = "rustdoc"
 version = "0.0.0"
 dependencies = [
- "arrayvec 0.7.0",
+ "arrayvec",
  "askama",
  "expect-test",
  "itertools",
@@ -5605,7 +4199,7 @@ dependencies = [
  "serde_json",
  "term",
  "thiserror",
- "toml 0.5.7",
+ "toml",
  "unicode-segmentation",
  "unicode-width",
  "unicode_categories",
@@ -5669,43 +4263,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
 [[package]]
-name = "sec1"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928"
-dependencies = [
- "base16ct",
- "der",
- "generic-array",
- "pkcs8",
- "subtle",
- "zeroize",
-]
-
-[[package]]
-name = "security-framework"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1759c2e3c8580017a484a7ac56d3abc5a6c1feadf88db2f3633f12ae4268c69"
-dependencies = [
- "bitflags",
- "core-foundation",
- "core-foundation-sys",
- "libc",
- "security-framework-sys",
-]
-
-[[package]]
-name = "security-framework-sys"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f99b9d5e26d2a71633cc4f2ebae7cc9f874044e0c351a27e17892d76dce5678b"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
 name = "self_cell"
 version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5730,16 +4287,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "serde-value"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
-dependencies = [
- "ordered-float",
- "serde",
-]
-
-[[package]]
 name = "serde_derive"
 version = "1.0.159"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5751,15 +4298,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "serde_ignored"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c2c7d39d14f2f2ea82239de71594782f186fd03501ac81f0ce08e674819ff2f"
-dependencies = [
- "serde",
-]
-
-[[package]]
 name = "serde_json"
 version = "1.0.85"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5772,15 +4310,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "serde_spanned"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4"
-dependencies = [
- "serde",
-]
-
-[[package]]
 name = "sha1"
 version = "0.10.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5792,12 +4321,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "sha1_smol"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
-
-[[package]]
 name = "sha2"
 version = "0.10.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5830,57 +4353,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d"
 
 [[package]]
-name = "signal-hook"
-version = "0.3.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9"
-dependencies = [
- "libc",
- "signal-hook-registry",
-]
-
-[[package]]
-name = "signal-hook-registry"
-version = "1.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "signature"
-version = "1.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
-dependencies = [
- "digest",
- "rand_core",
-]
-
-[[package]]
-name = "similar"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3"
-
-[[package]]
 name = "siphasher"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
 
 [[package]]
-name = "sized-chunks"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65e65d6a9f13cd78f361ea5a2cf53a45d67cdda421ba0316b9be101560f3d207"
-dependencies = [
- "bitmaps",
- "typenum",
-]
-
-[[package]]
 name = "slab"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5899,30 +4377,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831"
 
 [[package]]
-name = "snapbox"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "827c00e91b15e2674d8a5270bae91f898693cbf9561cbb58d8eaa31974597293"
-dependencies = [
- "concolor",
- "content_inspector",
- "dunce",
- "filetime",
- "normalize-line-endings",
- "similar",
- "snapbox-macros",
- "tempfile",
- "walkdir",
- "yansi",
-]
-
-[[package]]
-name = "snapbox-macros"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a253e6f894cfa440cba00600a249fa90869d8e0ec45ab274a456e043a0ce8f2"
-
-[[package]]
 name = "socket2"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5962,16 +4416,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "spki"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b"
-dependencies = [
- "base64ct",
- "der",
-]
-
-[[package]]
 name = "stable_deref_trait"
 version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6061,15 +4505,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "strip-ansi-escapes"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "011cbb39cf7c1f62871aea3cc46e5817b0937b49e9447370c93cacbe93a766d8"
-dependencies = [
- "vte",
-]
-
-[[package]]
 name = "strsim"
 version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6095,12 +4530,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "subtle"
-version = "2.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
-
-[[package]]
 name = "suggest-tests"
 version = "0.1.0"
 dependencies = [
@@ -6322,7 +4751,7 @@ dependencies = [
 name = "tidy"
 version = "0.1.0"
 dependencies = [
- "cargo-platform 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cargo-platform",
  "cargo_metadata 0.15.3",
  "ignore",
  "lazy_static",
@@ -6348,35 +4777,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "time"
-version = "0.3.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
-dependencies = [
- "itoa",
- "libc",
- "num_threads",
- "serde",
- "time-core",
- "time-macros",
-]
-
-[[package]]
-name = "time-core"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
-
-[[package]]
-name = "time-macros"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
-dependencies = [
- "time-core",
-]
-
-[[package]]
 name = "tinystr"
 version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6423,40 +4823,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "toml"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7afcae9e3f0fe2c370fd4657108972cbb2fa9db1b9f84849cefd80741b01cb6"
-dependencies = [
- "serde",
- "serde_spanned",
- "toml_datetime",
- "toml_edit",
-]
-
-[[package]]
-name = "toml_datetime"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.19.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e6a7712b49e1775fb9a7b998de6635b299237f48b404dde71704f2e0e7f37e5"
-dependencies = [
- "indexmap",
- "nom8",
- "serde",
- "serde_spanned",
- "toml_datetime",
-]
-
-[[package]]
 name = "topological-sort"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6720,12 +5086,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "unicode-bom"
-version = "1.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63ec69f541d875b783ca40184d655f2927c95f0bffd486faa83cd3ac3529ec32"
-
-[[package]]
 name = "unicode-ident"
 version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6866,27 +5226,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
 [[package]]
-name = "vte"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983"
-dependencies = [
- "arrayvec 0.5.2",
- "utf8parse",
- "vte_generate_state_changes",
-]
-
-[[package]]
-name = "vte_generate_state_changes"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff"
-dependencies = [
- "proc-macro2",
- "quote",
-]
-
-[[package]]
 name = "walkdir"
 version = "2.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6909,60 +5248,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "wasm-bindgen"
-version = "0.2.83"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
-dependencies = [
- "cfg-if",
- "wasm-bindgen-macro",
-]
-
-[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.83"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
-dependencies = [
- "bumpalo",
- "log",
- "once_cell",
- "proc-macro2",
- "quote",
- "syn 1.0.102",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.83"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.83"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.102",
- "wasm-bindgen-backend",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.83"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
-
-[[package]]
 name = "winapi"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6995,21 +5280,6 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
 name = "windows"
-version = "0.43.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244"
-dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
-]
-
-[[package]]
-name = "windows"
 version = "0.46.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25"
@@ -7143,12 +5413,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "yansi"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
-
-[[package]]
 name = "yansi-term"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -7203,12 +5467,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "zeroize"
-version = "1.5.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"
-
-[[package]]
 name = "zerovec"
 version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 1fcaaf6ddc4..a497d7321e0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,12 +22,6 @@ members = [
   "src/tools/remote-test-server",
   "src/tools/rust-installer",
   "src/tools/rust-demangler",
-  "src/tools/cargo",
-  "src/tools/cargo/crates/credential/cargo-credential-1password",
-  "src/tools/cargo/crates/credential/cargo-credential-macos-keychain",
-  "src/tools/cargo/crates/credential/cargo-credential-wincred",
-  "src/tools/cargo/crates/mdman",
-  # "src/tools/cargo/crates/resolver-tests",
   "src/tools/rustdoc",
   "src/tools/rls",
   "src/tools/rustfmt",
@@ -106,10 +100,6 @@ miniz_oxide.debug = 0
 object.debug = 0
 
 [patch.crates-io]
-# See comments in `src/tools/rustc-workspace-hack/README.md` for what's going on
-# here
-rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' }
-
 # See comments in `library/rustc-std-workspace-core/README.md` for what's going on
 # here
 rustc-std-workspace-core = { path = 'library/rustc-std-workspace-core' }
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index c863acde7b0..2b01aca2ee4 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -461,8 +461,8 @@ pub trait LayoutCalculator {
             let all_indices = variants.indices();
             let needs_disc =
                 |index: VariantIdx| index != largest_variant_index && !absent(&variants[index]);
-            let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap().index()
-                ..=all_indices.rev().find(|v| needs_disc(*v)).unwrap().index();
+            let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap()
+                ..=all_indices.rev().find(|v| needs_disc(*v)).unwrap();
 
             let count = niche_variants.size_hint().1.unwrap() as u128;
 
@@ -560,8 +560,7 @@ pub trait LayoutCalculator {
                     tag: niche_scalar,
                     tag_encoding: TagEncoding::Niche {
                         untagged_variant: largest_variant_index,
-                        niche_variants: (VariantIdx::new(*niche_variants.start())
-                            ..=VariantIdx::new(*niche_variants.end())),
+                        niche_variants,
                         niche_start,
                     },
                     tag_field: 0,
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index b0c0ee942ea..402ea6ff48f 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -11,7 +11,7 @@ use bitflags::bitflags;
 use rustc_data_structures::intern::Interned;
 #[cfg(feature = "nightly")]
 use rustc_data_structures::stable_hasher::StableOrd;
-use rustc_index::vec::{Idx, IndexSlice, IndexVec};
+use rustc_index::vec::{IndexSlice, IndexVec};
 #[cfg(feature = "nightly")]
 use rustc_macros::HashStable_Generic;
 #[cfg(feature = "nightly")]
@@ -665,15 +665,12 @@ impl Align {
             format!("`{}` is too large", align)
         }
 
-        let mut bytes = align;
-        let mut pow2: u8 = 0;
-        while (bytes & 1) == 0 {
-            pow2 += 1;
-            bytes >>= 1;
-        }
-        if bytes != 1 {
+        let tz = align.trailing_zeros();
+        if align != (1 << tz) {
             return Err(not_power_of_2(align));
         }
+
+        let pow2 = tz as u8;
         if pow2 > Self::MAX.pow2 {
             return Err(too_large(align));
         }
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index df1a716755b..ab0409efb3b 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1298,17 +1298,17 @@ impl Expr {
 
     /// To a first-order approximation, is this a pattern?
     pub fn is_approximately_pattern(&self) -> bool {
-        match &self.peel_parens().kind {
+        matches!(
+            &self.peel_parens().kind,
             ExprKind::Array(_)
-            | ExprKind::Call(_, _)
-            | ExprKind::Tup(_)
-            | ExprKind::Lit(_)
-            | ExprKind::Range(_, _, _)
-            | ExprKind::Underscore
-            | ExprKind::Path(_, _)
-            | ExprKind::Struct(_) => true,
-            _ => false,
-        }
+                | ExprKind::Call(_, _)
+                | ExprKind::Tup(_)
+                | ExprKind::Lit(_)
+                | ExprKind::Range(_, _, _)
+                | ExprKind::Underscore
+                | ExprKind::Path(_, _)
+                | ExprKind::Struct(_)
+        )
     }
 }
 
diff --git a/compiler/rustc_ast/src/node_id.rs b/compiler/rustc_ast/src/node_id.rs
index daa82996b3d..d16741757d1 100644
--- a/compiler/rustc_ast/src/node_id.rs
+++ b/compiler/rustc_ast/src/node_id.rs
@@ -9,14 +9,14 @@ rustc_index::newtype_index! {
     ///
     /// [`DefId`]: rustc_span::def_id::DefId
     #[debug_format = "NodeId({})"]
-    pub struct NodeId {}
+    pub struct NodeId {
+        /// The [`NodeId`] used to represent the root of the crate.
+        const CRATE_NODE_ID = 0;
+    }
 }
 
 rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeMapEntry, NodeId);
 
-/// The [`NodeId`] used to represent the root of the crate.
-pub const CRATE_NODE_ID: NodeId = NodeId::from_u32(0);
-
 /// When parsing and at the beginning of doing expansions, we initially give all AST nodes
 /// this dummy AST [`NodeId`]. Then, during a later phase of expansion, we renumber them
 /// to have small, positive IDs.
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 1b1c4765bc0..0d212b3e130 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -121,12 +121,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             LitKind::Err
                         }
                     };
-                    hir::ExprKind::Lit(respan(self.lower_span(e.span), lit_kind))
+                    let lit = self.arena.alloc(respan(self.lower_span(e.span), lit_kind));
+                    hir::ExprKind::Lit(lit)
+                }
+                ExprKind::IncludedBytes(bytes) => {
+                    let lit = self.arena.alloc(respan(
+                        self.lower_span(e.span),
+                        LitKind::ByteStr(bytes.clone(), StrStyle::Cooked),
+                    ));
+                    hir::ExprKind::Lit(lit)
                 }
-                ExprKind::IncludedBytes(bytes) => hir::ExprKind::Lit(respan(
-                    self.lower_span(e.span),
-                    LitKind::ByteStr(bytes.clone(), StrStyle::Cooked),
-                )),
                 ExprKind::Cast(expr, ty) => {
                     let expr = self.lower_expr(expr);
                     let ty =
@@ -1746,40 +1750,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     pub(super) fn expr_usize(&mut self, sp: Span, value: usize) -> hir::Expr<'hir> {
-        self.expr(
-            sp,
-            hir::ExprKind::Lit(hir::Lit {
-                span: sp,
-                node: ast::LitKind::Int(
-                    value as u128,
-                    ast::LitIntType::Unsigned(ast::UintTy::Usize),
-                ),
-            }),
-        )
+        let lit = self.arena.alloc(hir::Lit {
+            span: sp,
+            node: ast::LitKind::Int(value as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)),
+        });
+        self.expr(sp, hir::ExprKind::Lit(lit))
     }
 
     pub(super) fn expr_u32(&mut self, sp: Span, value: u32) -> hir::Expr<'hir> {
-        self.expr(
-            sp,
-            hir::ExprKind::Lit(hir::Lit {
-                span: sp,
-                node: ast::LitKind::Int(value.into(), ast::LitIntType::Unsigned(ast::UintTy::U32)),
-            }),
-        )
+        let lit = self.arena.alloc(hir::Lit {
+            span: sp,
+            node: ast::LitKind::Int(value.into(), ast::LitIntType::Unsigned(ast::UintTy::U32)),
+        });
+        self.expr(sp, hir::ExprKind::Lit(lit))
     }
 
     pub(super) fn expr_char(&mut self, sp: Span, value: char) -> hir::Expr<'hir> {
-        self.expr(sp, hir::ExprKind::Lit(hir::Lit { span: sp, node: ast::LitKind::Char(value) }))
+        let lit = self.arena.alloc(hir::Lit { span: sp, node: ast::LitKind::Char(value) });
+        self.expr(sp, hir::ExprKind::Lit(lit))
     }
 
     pub(super) fn expr_str(&mut self, sp: Span, value: Symbol) -> hir::Expr<'hir> {
-        self.expr(
-            sp,
-            hir::ExprKind::Lit(hir::Lit {
-                span: sp,
-                node: ast::LitKind::Str(value, ast::StrStyle::Cooked),
-            }),
-        )
+        let lit = self
+            .arena
+            .alloc(hir::Lit { span: sp, node: ast::LitKind::Str(value, ast::StrStyle::Cooked) });
+        self.expr(sp, hir::ExprKind::Lit(lit))
     }
 
     pub(super) fn expr_call_mut(
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index f7ae96b7c4a..2af47e11637 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -332,10 +332,7 @@ enum FnDeclKind {
 
 impl FnDeclKind {
     fn param_impl_trait_allowed(&self) -> bool {
-        match self {
-            FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => true,
-            _ => false,
-        }
+        matches!(self, FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait)
     }
 
     fn return_impl_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool {
diff --git a/compiler/rustc_borrowck/Cargo.toml b/compiler/rustc_borrowck/Cargo.toml
index 87c113f3e30..e0bb87336e5 100644
--- a/compiler/rustc_borrowck/Cargo.toml
+++ b/compiler/rustc_borrowck/Cargo.toml
@@ -20,7 +20,6 @@ rustc_infer = { path = "../rustc_infer" }
 rustc_lexer = { path = "../rustc_lexer" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
-rustc_const_eval = { path = "../rustc_const_eval" }
 rustc_mir_dataflow = { path = "../rustc_mir_dataflow" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl
index a3b6b5e8138..0b8123c9703 100644
--- a/compiler/rustc_borrowck/messages.ftl
+++ b/compiler/rustc_borrowck/messages.ftl
@@ -56,18 +56,6 @@ borrowck_returned_lifetime_short =
 borrowck_used_impl_require_static =
     the used `impl` has a `'static` requirement
 
-borrowck_capture_kind_label =
-    capture is {$kind_desc} because of use here
-
-borrowck_var_borrow_by_use_place_in_generator =
-    borrow occurs due to use of {$place} in closure in generator
-
-borrowck_var_borrow_by_use_place_in_closure =
-    borrow occurs due to use of {$place} in closure
-
-borrowck_var_borrow_by_use_place =
-    borrow occurs due to use of {$place}
-
 borrowck_borrow_due_to_use_generator =
     borrow occurs due to use in generator
 
@@ -101,12 +89,63 @@ borrowck_capture_mut =
 borrowck_capture_move =
     capture is moved because of use here
 
+borrowck_var_borrow_by_use_place_in_generator =
+    {$is_single_var ->
+        *[true] borrow occurs
+        [false] borrows occur
+    } due to use of {$place} in generator
+
+borrowck_var_borrow_by_use_place_in_closure =
+    {$is_single_var ->
+        *[true] borrow occurs
+        [false] borrows occur
+    } due to use of {$place} in closure
+
+borrowck_var_borrow_by_use_in_generator =
+    borrow occurs due to use in generator
+
+borrowck_var_borrow_by_use_in_closure =
+    borrow occurs due to use in closure
+
 borrowck_var_move_by_use_place_in_generator =
     move occurs due to use of {$place} in generator
 
 borrowck_var_move_by_use_place_in_closure =
     move occurs due to use of {$place} in closure
 
+borrowck_var_move_by_use_in_generator =
+    move occurs due to use in generator
+
+borrowck_var_move_by_use_in_closure =
+    move occurs due to use in closure
+
+borrowck_partial_var_move_by_use_in_generator =
+    variable {$is_partial ->
+        [true] partially moved
+        *[false] moved
+    } due to use in generator
+
+borrowck_partial_var_move_by_use_in_closure =
+    variable {$is_partial ->
+        [true] partially moved
+        *[false] moved
+    } due to use in closure
+
+borrowck_var_first_borrow_by_use_place_in_generator =
+    first borrow occurs due to use of {$place} in generator
+
+borrowck_var_first_borrow_by_use_place_in_closure =
+    first borrow occurs due to use of {$place} in closure
+
+borrowck_var_second_borrow_by_use_place_in_generator =
+    second borrow occurs due to use of {$place} in generator
+
+borrowck_var_second_borrow_by_use_place_in_closure =
+    second borrow occurs due to use of {$place} in closure
+
+borrowck_var_mutable_borrow_by_use_place_in_closure =
+    mutable borrow occurs due to use of {$place} in closure
+
 borrowck_cannot_move_when_borrowed =
     cannot move out of {$place ->
         [value] value
@@ -127,3 +166,90 @@ borrowck_opaque_type_non_generic_param =
         [true] cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
         *[other] this generic parameter must be used with a generic {$kind} parameter
     }
+
+borrowck_moved_due_to_call =
+    {$place_name} {$is_partial ->
+        [true] partially moved
+        *[false] moved
+    } due to this {$is_loop_message ->
+        [true] call, in previous iteration of loop
+        *[false] call
+    }
+
+borrowck_moved_due_to_usage_in_operator =
+    {$place_name} {$is_partial ->
+        [true] partially moved
+        *[false] moved
+    } due to usage in {$is_loop_message ->
+        [true] operator, in previous iteration of loop
+        *[false] operator
+    }
+
+borrowck_moved_due_to_implicit_into_iter_call =
+    {$place_name} {$is_partial ->
+        [true] partially moved
+        *[false] moved
+    } due to this implicit call to {$is_loop_message ->
+        [true] `.into_iter()`, in previous iteration of loop
+        *[false] `.into_iter()`
+    }
+
+borrowck_moved_due_to_method_call =
+    {$place_name} {$is_partial ->
+        [true] partially moved
+        *[false] moved
+    } due to this method {$is_loop_message ->
+        [true] call, in previous iteration of loop
+        *[false] call
+    }
+
+borrowck_value_moved_here =
+    value {$is_partial ->
+        [true] partially moved
+        *[false] moved
+    } {$is_move_msg ->
+        [true] into closure here
+        *[false] here
+    }{$is_loop_message ->
+        [true] , in previous iteration of loop
+        *[false] {""}
+    }
+
+borrowck_consider_borrow_type_contents =
+    help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
+
+borrowck_moved_a_fn_once_in_call =
+    this value implements `FnOnce`, which causes it to be moved when called
+
+borrowck_calling_operator_moves_lhs =
+    calling this operator moves the left-hand side
+
+borrowck_func_take_self_moved_place =
+    `{$func}` takes ownership of the receiver `self`, which moves {$place_name}
+
+borrowck_suggest_iterate_over_slice =
+    consider iterating over a slice of the `{$ty}`'s content to avoid moving into the `for` loop
+
+borrowck_suggest_create_freash_reborrow =
+    consider reborrowing the `Pin` instead of moving it
+
+borrowck_value_capture_here =
+    value captured {$is_within ->
+        [true] here by generator
+        *[false] here
+    }
+
+borrowck_move_out_place_here =
+    {$place} is moved here
+
+borrowck_closure_invoked_twice =
+    closure cannot be invoked more than once because it moves the variable `{$place_name}` out of its environment
+
+borrowck_closure_moved_twice =
+    closure cannot be moved more than once as it is not `Copy` due to moving the variable `{$place_name}` out of its environment
+
+borrowck_ty_no_impl_copy =
+    {$is_partial_move ->
+        [true] partial move
+        *[false] move
+    } occurs because {$place} has type `{$ty}`, which does not implement the `Copy` trait
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 75a3dd0c0f3..a4a3c738f47 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1,5 +1,4 @@
 use either::Either;
-use rustc_const_eval::util::CallKind;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::{
@@ -18,6 +17,7 @@ use rustc_middle::mir::{
     ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
 };
 use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty};
+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;
@@ -30,8 +30,8 @@ use crate::borrow_set::TwoPhaseActivation;
 use crate::borrowck_errors;
 
 use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
-use crate::diagnostics::find_all_local_uses;
 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,
     InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind,
@@ -183,13 +183,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 let move_spans = self.move_spans(moved_place.as_ref(), move_out.source);
                 let move_span = move_spans.args_or_use();
 
-                let move_msg = if move_spans.for_closure() { " into closure" } else { "" };
+                let is_move_msg = move_spans.for_closure();
 
-                let loop_message = if location == move_out.source || move_site.traversed_back_edge {
-                    ", in previous iteration of loop"
-                } else {
-                    ""
-                };
+                let is_loop_message = location == move_out.source || move_site.traversed_back_edge;
 
                 if location == move_out.source {
                     is_loop_move = true;
@@ -206,17 +202,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         );
                     }
 
+                    let msg_opt = CapturedMessageOpt {
+                        is_partial_move,
+                        is_loop_message,
+                        is_move_msg,
+                        is_loop_move,
+                        maybe_reinitialized_locations_is_empty: maybe_reinitialized_locations
+                            .is_empty(),
+                    };
                     self.explain_captures(
                         &mut err,
                         span,
                         move_span,
                         move_spans,
                         *moved_place,
-                        partially_str,
-                        loop_message,
-                        move_msg,
-                        is_loop_move,
-                        maybe_reinitialized_locations.is_empty(),
+                        msg_opt,
                     );
                 }
                 seen_spans.insert(move_span);
@@ -282,12 +282,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             }
 
             if needs_note {
-                let span = if let Some(local) = place.as_local() {
-                    Some(self.body.local_decls[local].source_info.span)
+                if let Some(local) = place.as_local() {
+                    let span = self.body.local_decls[local].source_info.span;
+                    err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
+                        is_partial_move,
+                        ty,
+                        place: &note_msg,
+                        span,
+                    });
                 } else {
-                    None
+                    err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Note {
+                        is_partial_move,
+                        ty,
+                        place: &note_msg,
+                    });
                 };
-                self.note_type_does_not_implement_copy(&mut err, &note_msg, ty, span, partial_str);
             }
 
             if let UseSpans::FnSelfUse {
@@ -827,11 +836,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
         borrow_spans.var_path_only_subdiag(&mut err, crate::InitializationRequiringAction::Borrow);
 
-        move_spans.var_span_label(
-            &mut err,
-            format!("move occurs due to use{}", move_spans.describe()),
-            "moved",
-        );
+        move_spans.var_subdiag(None, &mut err, None, |kind, var_span| {
+            use crate::session_diagnostics::CaptureVarCause::*;
+            match kind {
+                Some(_) => MoveUseInGenerator { var_span },
+                None => MoveUseInClosure { var_span },
+            }
+        });
 
         self.explain_why_borrow_contains_point(location, borrow, None)
             .add_explanation_to_diagnostic(
@@ -868,13 +879,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             borrow_span,
             &self.describe_any_place(borrow.borrowed_place.as_ref()),
         );
-        borrow_spans.var_subdiag(&mut err, Some(borrow.kind), |kind, var_span| {
+        borrow_spans.var_subdiag(None, &mut err, Some(borrow.kind), |kind, var_span| {
             use crate::session_diagnostics::CaptureVarCause::*;
             let place = &borrow.borrowed_place;
             let desc_place = self.describe_any_place(place.as_ref());
             match kind {
-                Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span },
-                None => BorrowUsePlaceClosure { place: desc_place, var_span },
+                Some(_) => {
+                    BorrowUsePlaceGenerator { place: desc_place, var_span, is_single_var: true }
+                }
+                None => BorrowUsePlaceClosure { place: desc_place, var_span, is_single_var: true },
             }
         });
 
@@ -988,16 +1001,26 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         immutable_section_description,
                         "mutably borrow",
                     );
-                    borrow_spans.var_span_label(
+                    borrow_spans.var_subdiag(
+                        None,
                         &mut err,
-                        format!(
-                            "borrow occurs due to use of {}{}",
-                            desc_place,
-                            borrow_spans.describe(),
-                        ),
-                        "immutable",
+                        Some(BorrowKind::Unique),
+                        |kind, var_span| {
+                            use crate::session_diagnostics::CaptureVarCause::*;
+                            match kind {
+                                Some(_) => BorrowUsePlaceGenerator {
+                                    place: desc_place,
+                                    var_span,
+                                    is_single_var: true,
+                                },
+                                None => BorrowUsePlaceClosure {
+                                    place: desc_place,
+                                    var_span,
+                                    is_single_var: true,
+                                },
+                            }
+                        },
                     );
-
                     return err;
                 } else {
                     first_borrow_desc = "immutable ";
@@ -1070,32 +1093,48 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         };
 
         if issued_spans == borrow_spans {
-            borrow_spans.var_span_label(
-                &mut err,
-                format!("borrows occur due to use of {}{}", desc_place, borrow_spans.describe(),),
-                gen_borrow_kind.describe_mutability(),
-            );
+            borrow_spans.var_subdiag(None, &mut err, Some(gen_borrow_kind), |kind, var_span| {
+                use crate::session_diagnostics::CaptureVarCause::*;
+                match kind {
+                    Some(_) => BorrowUsePlaceGenerator {
+                        place: desc_place,
+                        var_span,
+                        is_single_var: false,
+                    },
+                    None => {
+                        BorrowUsePlaceClosure { place: desc_place, var_span, is_single_var: false }
+                    }
+                }
+            });
         } else {
-            let borrow_place = &issued_borrow.borrowed_place;
-            let borrow_place_desc = self.describe_any_place(borrow_place.as_ref());
-            issued_spans.var_span_label(
+            issued_spans.var_subdiag(
+                Some(&self.infcx.tcx.sess.parse_sess.span_diagnostic),
                 &mut err,
-                format!(
-                    "first borrow occurs due to use of {}{}",
-                    borrow_place_desc,
-                    issued_spans.describe(),
-                ),
-                issued_borrow.kind.describe_mutability(),
+                Some(issued_borrow.kind),
+                |kind, var_span| {
+                    use crate::session_diagnostics::CaptureVarCause::*;
+                    let borrow_place = &issued_borrow.borrowed_place;
+                    let borrow_place_desc = self.describe_any_place(borrow_place.as_ref());
+                    match kind {
+                        Some(_) => {
+                            FirstBorrowUsePlaceGenerator { place: borrow_place_desc, var_span }
+                        }
+                        None => FirstBorrowUsePlaceClosure { place: borrow_place_desc, var_span },
+                    }
+                },
             );
 
-            borrow_spans.var_span_label(
+            borrow_spans.var_subdiag(
+                Some(&self.infcx.tcx.sess.parse_sess.span_diagnostic),
                 &mut err,
-                format!(
-                    "second borrow occurs due to use of {}{}",
-                    desc_place,
-                    borrow_spans.describe(),
-                ),
-                gen_borrow_kind.describe_mutability(),
+                Some(gen_borrow_kind),
+                |kind, var_span| {
+                    use crate::session_diagnostics::CaptureVarCause::*;
+                    match kind {
+                        Some(_) => SecondBorrowUsePlaceGenerator { place: desc_place, var_span },
+                        None => SecondBorrowUsePlaceClosure { place: desc_place, var_span },
+                    }
+                },
             );
         }
 
@@ -1731,9 +1770,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             err.span_label(borrow_span, "borrowed value does not live long enough");
             err.span_label(drop_span, format!("`{}` dropped here while still borrowed", name));
 
-            let within = if borrow_spans.for_generator() { " by generator" } else { "" };
-
-            borrow_spans.args_span_label(&mut err, format!("value captured here{}", within));
+            borrow_spans.args_subdiag(&mut err, |args_span| {
+                crate::session_diagnostics::CaptureArgLabel::Capture {
+                    is_within: borrow_spans.for_generator(),
+                    args_span,
+                }
+            });
 
             explanation.add_explanation_to_diagnostic(
                 self.infcx.tcx,
@@ -1947,9 +1989,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             None,
         );
 
-        let within = if borrow_spans.for_generator() { " by generator" } else { "" };
-
-        borrow_spans.args_span_label(&mut err, format!("value captured here{}", within));
+        borrow_spans.args_subdiag(&mut err, |args_span| {
+            crate::session_diagnostics::CaptureArgLabel::Capture {
+                is_within: borrow_spans.for_generator(),
+                args_span,
+            }
+        });
 
         err
     }
@@ -2382,11 +2427,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     section,
                     "assign",
                 );
-                loan_spans.var_span_label(
-                    &mut err,
-                    format!("borrow occurs due to use{}", loan_spans.describe()),
-                    loan.kind.describe_mutability(),
-                );
+
+                loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| {
+                    use crate::session_diagnostics::CaptureVarCause::*;
+                    match kind {
+                        Some(_) => BorrowUseInGenerator { var_span },
+                        None => BorrowUseInClosure { var_span },
+                    }
+                });
 
                 self.buffer_error(err);
 
@@ -2396,11 +2444,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
         let mut err = self.cannot_assign_to_borrowed(span, loan_span, &descr_place);
 
-        loan_spans.var_span_label(
-            &mut err,
-            format!("borrow occurs due to use{}", loan_spans.describe()),
-            loan.kind.describe_mutability(),
-        );
+        loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| {
+            use crate::session_diagnostics::CaptureVarCause::*;
+            match kind {
+                Some(_) => BorrowUseInGenerator { var_span },
+                None => BorrowUseInClosure { var_span },
+            }
+        });
 
         self.explain_why_borrow_contains_point(location, loan, None).add_explanation_to_diagnostic(
             self.infcx.tcx,
@@ -2424,7 +2474,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             Some((method_did, method_substs)),
         ) = (
             &self.body[loan.reserve_location.block].terminator,
-            rustc_const_eval::util::find_self_call(
+            rustc_middle::util::find_self_call(
                 tcx,
                 self.body,
                 loan.assigned_place.local,
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 110354a20d8..4a85df9f8c0 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -1,7 +1,10 @@
 //! Borrow checker diagnostics.
 
+use crate::session_diagnostics::{
+    CaptureArgLabel, CaptureReasonLabel, CaptureReasonNote, CaptureReasonSuggest, CaptureVarCause,
+    CaptureVarKind, CaptureVarPathUseCause, OnClosureNote,
+};
 use itertools::Itertools;
-use rustc_const_eval::util::{call_kind, CallDesugaringKind};
 use rustc_errors::{Applicability, Diagnostic};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, Namespace};
@@ -15,6 +18,7 @@ use rustc_middle::mir::{
 };
 use rustc_middle::ty::print::Print;
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
+use rustc_middle::util::{call_kind, CallDesugaringKind};
 use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
@@ -45,7 +49,7 @@ pub(crate) use mutability_errors::AccessKind;
 pub(crate) use outlives_suggestion::OutlivesSuggestionBuilder;
 pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
 pub(crate) use region_name::{RegionName, RegionNameSource};
-pub(crate) use rustc_const_eval::util::CallKind;
+pub(crate) use rustc_middle::util::CallKind;
 
 pub(super) struct DescribePlaceOpt {
     pub including_downcast: bool,
@@ -117,13 +121,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     if let ty::Closure(did, _) = self.body.local_decls[closure].ty.kind() {
                         let did = did.expect_local();
                         if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) {
-                            diag.span_note(
-                                *span,
-                                &format!(
-                                    "closure cannot be invoked more than once because it moves the \
-                                    variable `{}` out of its environment",
-                                    ty::place_to_string_for_capture(self.infcx.tcx, hir_place)
-                                ),
+                            diag.eager_subdiagnostic(
+                                &self.infcx.tcx.sess.parse_sess.span_diagnostic,
+                                OnClosureNote::InvokedTwice {
+                                    place_name: &ty::place_to_string_for_capture(
+                                        self.infcx.tcx,
+                                        hir_place,
+                                    ),
+                                    span: *span,
+                                },
                             );
                             return true;
                         }
@@ -137,13 +143,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             if let ty::Closure(did, _) = self.body.local_decls[target].ty.kind() {
                 let did = did.expect_local();
                 if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) {
-                    diag.span_note(
-                        *span,
-                        &format!(
-                            "closure cannot be moved more than once as it is not `Copy` due to \
-                             moving the variable `{}` out of its environment",
-                            ty::place_to_string_for_capture(self.infcx.tcx, hir_place)
-                        ),
+                    diag.eager_subdiagnostic(
+                        &self.infcx.tcx.sess.parse_sess.span_diagnostic,
+                        OnClosureNote::MovedTwice {
+                            place_name: &ty::place_to_string_for_capture(self.infcx.tcx, hir_place),
+                            span: *span,
+                        },
                     );
                     return true;
                 }
@@ -380,25 +385,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         }
     }
 
-    /// Add a note that a type does not implement `Copy`
-    pub(super) fn note_type_does_not_implement_copy(
-        &self,
-        err: &mut Diagnostic,
-        place_desc: &str,
-        ty: Ty<'tcx>,
-        span: Option<Span>,
-        move_prefix: &str,
-    ) {
-        let message = format!(
-            "{move_prefix}move occurs because {place_desc} has type `{ty}`, which does not implement the `Copy` trait",
-        );
-        if let Some(span) = span {
-            err.span_label(span, message);
-        } else {
-            err.note(&message);
-        }
-    }
-
     pub(super) fn borrowed_content_source(
         &self,
         deref_base: PlaceRef<'tcx>,
@@ -582,9 +568,13 @@ impl UseSpans<'_> {
     }
 
     /// Add a span label to the arguments of the closure, if it exists.
-    pub(super) fn args_span_label(self, err: &mut Diagnostic, message: impl Into<String>) {
+    pub(super) fn args_subdiag(
+        self,
+        err: &mut Diagnostic,
+        f: impl FnOnce(Span) -> CaptureArgLabel,
+    ) {
         if let UseSpans::ClosureUse { args_span, .. } = self {
-            err.span_label(args_span, message);
+            err.subdiagnostic(f(args_span));
         }
     }
 
@@ -595,8 +585,8 @@ impl UseSpans<'_> {
         err: &mut Diagnostic,
         action: crate::InitializationRequiringAction,
     ) {
-        use crate::session_diagnostics::CaptureVarPathUseCause::*;
         use crate::InitializationRequiringAction::*;
+        use CaptureVarPathUseCause::*;
         if let UseSpans::ClosureUse { generator_kind, path_span, .. } = self {
             match generator_kind {
                 Some(_) => {
@@ -619,34 +609,14 @@ impl UseSpans<'_> {
         }
     }
 
-    /// Add a span label to the use of the captured variable, if it exists.
-    pub(super) fn var_span_label(
-        self,
-        err: &mut Diagnostic,
-        message: impl Into<String>,
-        kind_desc: impl Into<String>,
-    ) {
-        if let UseSpans::ClosureUse { capture_kind_span, path_span, .. } = self {
-            if capture_kind_span == path_span {
-                err.span_label(capture_kind_span, message);
-            } else {
-                let capture_kind_label =
-                    format!("capture is {} because of use here", kind_desc.into());
-                let path_label = message;
-                err.span_label(capture_kind_span, capture_kind_label);
-                err.span_label(path_span, path_label);
-            }
-        }
-    }
-
     /// Add a subdiagnostic to the use of the captured variable, if it exists.
     pub(super) fn var_subdiag(
         self,
+        handler: Option<&rustc_errors::Handler>,
         err: &mut Diagnostic,
         kind: Option<rustc_middle::mir::BorrowKind>,
-        f: impl Fn(Option<GeneratorKind>, Span) -> crate::session_diagnostics::CaptureVarCause,
+        f: impl FnOnce(Option<GeneratorKind>, Span) -> CaptureVarCause,
     ) {
-        use crate::session_diagnostics::CaptureVarKind::*;
         if let UseSpans::ClosureUse { generator_kind, capture_kind_span, path_span, .. } = self {
             if capture_kind_span != path_span {
                 err.subdiagnostic(match kind {
@@ -654,17 +624,21 @@ impl UseSpans<'_> {
                         rustc_middle::mir::BorrowKind::Shared
                         | rustc_middle::mir::BorrowKind::Shallow
                         | rustc_middle::mir::BorrowKind::Unique => {
-                            Immute { kind_span: capture_kind_span }
+                            CaptureVarKind::Immut { kind_span: capture_kind_span }
                         }
 
                         rustc_middle::mir::BorrowKind::Mut { .. } => {
-                            Mut { kind_span: capture_kind_span }
+                            CaptureVarKind::Mut { kind_span: capture_kind_span }
                         }
                     },
-                    None => Move { kind_span: capture_kind_span },
+                    None => CaptureVarKind::Move { kind_span: capture_kind_span },
                 });
             };
-            err.subdiagnostic(f(generator_kind, path_span));
+            let diag = f(generator_kind, path_span);
+            match handler {
+                Some(hd) => err.eager_subdiagnostic(hd, diag),
+                None => err.subdiagnostic(diag),
+            };
         }
     }
 
@@ -684,20 +658,6 @@ impl UseSpans<'_> {
         }
     }
 
-    /// Describe the span associated with a use of a place.
-    pub(super) fn describe(&self) -> &str {
-        match *self {
-            UseSpans::ClosureUse { generator_kind, .. } => {
-                if generator_kind.is_some() {
-                    " in generator"
-                } else {
-                    " in closure"
-                }
-            }
-            _ => "",
-        }
-    }
-
     pub(super) fn or_else<F>(self, if_other: F) -> Self
     where
         F: FnOnce() -> Self,
@@ -788,6 +748,15 @@ impl<'tcx> BorrowedContentSource<'tcx> {
     }
 }
 
+///helper struct for explain_captures()
+struct CapturedMessageOpt {
+    is_partial_move: bool,
+    is_loop_message: bool,
+    is_move_msg: bool,
+    is_loop_move: bool,
+    maybe_reinitialized_locations_is_empty: bool,
+}
+
 impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     /// Finds the spans associated to a move or copy of move_place at location.
     pub(super) fn move_spans(
@@ -874,7 +843,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         }) = &self.body[location.block].terminator
         {
             let Some((method_did, method_substs)) =
-                rustc_const_eval::util::find_self_call(
+            rustc_middle::util::find_self_call(
                     self.infcx.tcx,
                     &self.body,
                     target_temp,
@@ -1027,12 +996,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         move_span: Span,
         move_spans: UseSpans<'tcx>,
         moved_place: Place<'tcx>,
-        partially_str: &str,
-        loop_message: &str,
-        move_msg: &str,
-        is_loop_move: bool,
-        maybe_reinitialized_locations_is_empty: bool,
+        msg_opt: CapturedMessageOpt,
     ) {
+        let CapturedMessageOpt {
+            is_partial_move: is_partial,
+            is_loop_message,
+            is_move_msg,
+            is_loop_move,
+            maybe_reinitialized_locations_is_empty,
+        } = msg_opt;
         if let UseSpans::FnSelfUse { var_span, fn_call_span, fn_span, kind } = move_spans {
             let place_name = self
                 .describe_place(moved_place.as_ref())
@@ -1042,30 +1014,26 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 CallKind::FnCall { fn_trait_id, .. }
                     if Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait() =>
                 {
-                    err.span_label(
+                    err.subdiagnostic(CaptureReasonLabel::Call {
                         fn_call_span,
-                        &format!(
-                            "{place_name} {partially_str}moved due to this call{loop_message}",
-                        ),
-                    );
-                    err.span_note(
-                        var_span,
-                        "this value implements `FnOnce`, which causes it to be moved when called",
-                    );
+                        place_name: &place_name,
+                        is_partial,
+                        is_loop_message,
+                    });
+                    err.subdiagnostic(CaptureReasonNote::FnOnceMoveInCall { var_span });
                 }
                 CallKind::Operator { self_arg, .. } => {
                     let self_arg = self_arg.unwrap();
-                    err.span_label(
+                    err.subdiagnostic(CaptureReasonLabel::OperatorUse {
                         fn_call_span,
-                        &format!(
-                            "{place_name} {partially_str}moved due to usage in operator{loop_message}",
-                        ),
-                    );
+                        place_name: &place_name,
+                        is_partial,
+                        is_loop_message,
+                    });
                     if self.fn_self_span_reported.insert(fn_span) {
-                        err.span_note(
-                            self_arg.span,
-                            "calling this operator moves the left-hand side",
-                        );
+                        err.subdiagnostic(CaptureReasonNote::LhsMoveByOperator {
+                            span: self_arg.span,
+                        });
                     }
                 }
                 CallKind::Normal { self_arg, desugaring, method_did, method_substs } => {
@@ -1086,23 +1054,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             _ => false,
                         };
                         if suggest {
-                            err.span_suggestion_verbose(
-                                move_span.shrink_to_lo(),
-                                &format!(
-                                    "consider iterating over a slice of the `{ty}`'s content to \
-                                     avoid moving into the `for` loop",
-                                ),
-                                "&",
-                                Applicability::MaybeIncorrect,
-                            );
+                            err.subdiagnostic(CaptureReasonSuggest::IterateSlice {
+                                ty,
+                                span: move_span.shrink_to_lo(),
+                            });
                         }
 
-                        err.span_label(
+                        err.subdiagnostic(CaptureReasonLabel::ImplicitCall {
                             fn_call_span,
-                            &format!(
-                                "{place_name} {partially_str}moved due to this implicit call to `.into_iter()`{loop_message}",
-                            ),
-                        );
+                            place_name: &place_name,
+                            is_partial,
+                            is_loop_message,
+                        });
                         // If the moved place was a `&mut` ref, then we can
                         // suggest to reborrow it where it was moved, so it
                         // will still be valid by the time we get to the usage.
@@ -1125,13 +1088,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             }
                         }
                     } else {
-                        err.span_label(
+                        err.subdiagnostic(CaptureReasonLabel::MethodCall {
                             fn_call_span,
-                            &format!(
-                                "{place_name} {partially_str}moved due to this method call{loop_message}",
-                            ),
-                        );
-
+                            place_name: &place_name,
+                            is_partial,
+                            is_loop_message,
+                        });
                         let infcx = tcx.infer_ctxt().build();
                         // Erase and shadow everything that could be passed to the new infcx.
                         let ty = tcx.erase_regions(moved_place.ty(self.body, tcx).ty);
@@ -1147,12 +1109,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             )
                             && infcx.can_eq(self.param_env, ty, self_ty)
                         {
-                            err.span_suggestion_verbose(
-                                fn_call_span.shrink_to_lo(),
-                                "consider reborrowing the `Pin` instead of moving it",
-                                "as_mut().".to_string(),
-                                Applicability::MaybeIncorrect,
-                            );
+                            err.eager_subdiagnostic(
+                                &self.infcx.tcx.sess.parse_sess.span_diagnostic,
+                                CaptureReasonSuggest::FreshReborrow {
+                                    span: fn_call_span.shrink_to_lo(),
+                                });
                         }
                         if let Some(clone_trait) = tcx.lang_items().clone_trait()
                             && let trait_ref = tcx.mk_trait_ref(clone_trait, [ty])
@@ -1177,10 +1138,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     // error messages.
                     if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span) {
                         let func = tcx.def_path_str(method_did);
-                        err.span_note(
-                            self_arg.span,
-                            &format!("`{func}` takes ownership of the receiver `self`, which moves {place_name}")
-                        );
+                        err.subdiagnostic(CaptureReasonNote::FuncTakeSelf {
+                            func,
+                            place_name,
+                            span: self_arg.span,
+                        });
                     }
                     let parent_did = tcx.parent(method_did);
                     let parent_self_ty =
@@ -1194,30 +1156,28 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
                     });
                     if is_option_or_result && maybe_reinitialized_locations_is_empty {
-                        err.span_label(
-                            var_span,
-                            "help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents",
-                        );
+                        err.subdiagnostic(CaptureReasonLabel::BorrowContent { var_span });
                     }
                 }
                 // Other desugarings takes &self, which cannot cause a move
                 _ => {}
             }
         } else {
-            if move_span != span || !loop_message.is_empty() {
-                err.span_label(
+            if move_span != span || is_loop_message {
+                err.subdiagnostic(CaptureReasonLabel::MovedHere {
                     move_span,
-                    format!("value {partially_str}moved{move_msg} here{loop_message}"),
-                );
+                    is_partial,
+                    is_move_msg,
+                    is_loop_message,
+                });
             }
             // If the move error occurs due to a loop, don't show
             // another message for the same span
-            if loop_message.is_empty() {
-                move_spans.var_span_label(
-                    err,
-                    format!("variable {partially_str}moved due to use{}", move_spans.describe()),
-                    "moved",
-                );
+            if !is_loop_message {
+                move_spans.var_subdiag(None, err, None, |kind, var_span| match kind {
+                    Some(_) => CaptureVarCause::PartialMoveUseInGenerator { var_span, is_partial },
+                    None => CaptureVarCause::PartialMoveUseInClosure { var_span, is_partial },
+                })
             }
         }
     }
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 3662bec0c76..67af96a71e3 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -6,6 +6,7 @@ use rustc_mir_dataflow::move_paths::{
 };
 use rustc_span::{BytePos, Span};
 
+use crate::diagnostics::CapturedMessageOpt;
 use crate::diagnostics::{DescribePlaceOpt, UseSpans};
 use crate::prefixes::PrefixSet;
 use crate::MirBorrowckCtxt;
@@ -397,10 +398,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 }
             }
         };
+        let msg_opt = CapturedMessageOpt {
+            is_partial_move: false,
+            is_loop_message: false,
+            is_move_msg: false,
+            is_loop_move: false,
+            maybe_reinitialized_locations_is_empty: true,
+        };
         if let Some(use_spans) = use_spans {
-            self.explain_captures(
-                &mut err, span, span, use_spans, move_place, "", "", "", false, true,
-            );
+            self.explain_captures(&mut err, span, span, use_spans, move_place, msg_opt);
         }
         err
     }
@@ -416,13 +422,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         None => "value".to_string(),
                     };
 
-                    self.note_type_does_not_implement_copy(
-                        err,
-                        &place_desc,
-                        place_ty,
-                        Some(span),
-                        "",
-                    );
+                    err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
+                        is_partial_move: false,
+                        ty: place_ty,
+                        place: &place_desc,
+                        span,
+                    });
                 } else {
                     binds_to.sort();
                     binds_to.dedup();
@@ -444,9 +449,19 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     Some(desc) => format!("`{desc}`"),
                     None => "value".to_string(),
                 };
-                self.note_type_does_not_implement_copy(err, &place_desc, place_ty, Some(span), "");
+                err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
+                    is_partial_move: false,
+                    ty: place_ty,
+                    place: &place_desc,
+                    span,
+                });
 
-                use_spans.args_span_label(err, format!("{place_desc} is moved here"));
+                use_spans.args_subdiag(err, |args_span| {
+                    crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
+                        place: place_desc,
+                        args_span,
+                    }
+                });
             }
         }
     }
@@ -534,13 +549,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             }
 
             if binds_to.len() == 1 {
-                self.note_type_does_not_implement_copy(
-                    err,
-                    &format!("`{}`", self.local_names[*local].unwrap()),
-                    bind_to.ty,
-                    Some(binding_span),
-                    "",
-                );
+                let place_desc = &format!("`{}`", self.local_names[*local].unwrap());
+                err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
+                    is_partial_move: false,
+                    ty: bind_to.ty,
+                    place: &place_desc,
+                    span: binding_span,
+                });
             }
         }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 9d904009650..eb5f166548d 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -15,8 +15,8 @@ use rustc_span::{sym, BytePos, Span};
 use rustc_target::abi::FieldIdx;
 
 use crate::diagnostics::BorrowedContentSource;
+use crate::util::FindAssignments;
 use crate::MirBorrowckCtxt;
-use rustc_const_eval::util::collect_writes::FindAssignments;
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub(crate) enum AccessKind {
@@ -231,14 +231,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     }
                 }
                 if suggest {
-                    borrow_spans.var_span_label(
-                        &mut err,
-                        format!(
-                            "mutable borrow occurs due to use of {} in closure",
-                            self.describe_any_place(access_place.as_ref()),
-                        ),
-                        "mutable",
-                    );
+                    borrow_spans.var_subdiag(
+                    None,
+                    &mut err,
+                    Some(mir::BorrowKind::Mut { allow_two_phase_borrow: false }),
+                    |_kind, var_span| {
+                        let place = self.describe_any_place(access_place.as_ref());
+                        crate::session_diagnostics::CaptureVarCause::MutableBorrowUsePlaceClosure {
+                            place,
+                            var_span,
+                        }
+                    },
+                );
                 }
                 borrow_span
             }
diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs
index 376415e3d32..aa7cf3578ea 100644
--- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs
@@ -3,7 +3,7 @@
 
 use crate::region_infer::RegionInferenceContext;
 use crate::Upvar;
-use rustc_index::vec::{Idx, IndexSlice};
+use rustc_index::vec::IndexSlice;
 use rustc_middle::mir::{Body, Local};
 use rustc_middle::ty::{RegionVid, TyCtxt};
 use rustc_span::source_map::Span;
@@ -117,7 +117,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         argument_index: usize,
     ) -> (Option<Symbol>, Span) {
         let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs();
-        let argument_local = Local::new(implicit_inputs + argument_index + 1);
+        let argument_local = Local::from_usize(implicit_inputs + argument_index + 1);
         debug!("get_argument_name_and_span_for_region: argument_local={argument_local:?}");
 
         let argument_name = local_names[argument_local];
diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/facts.rs
index 02ffb51fbb7..87fad9a355d 100644
--- a/compiler/rustc_borrowck/src/facts.rs
+++ b/compiler/rustc_borrowck/src/facts.rs
@@ -4,7 +4,6 @@ use crate::location::{LocationIndex, LocationTable};
 use crate::BorrowIndex;
 use polonius_engine::AllFacts as PoloniusFacts;
 use polonius_engine::Atom;
-use rustc_index::vec::Idx;
 use rustc_middle::mir::Local;
 use rustc_middle::ty::{RegionVid, TyCtxt};
 use rustc_mir_dataflow::move_paths::MovePathIndex;
@@ -93,13 +92,13 @@ impl AllFactsExt for AllFacts {
 
 impl Atom for BorrowIndex {
     fn index(self) -> usize {
-        Idx::index(self)
+        self.as_usize()
     }
 }
 
 impl Atom for LocationIndex {
     fn index(self) -> usize {
-        Idx::index(self)
+        self.as_usize()
     }
 }
 
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 70d0a101b4e..fdd82c7e3b2 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -88,6 +88,7 @@ mod session_diagnostics;
 mod type_check;
 mod universal_regions;
 mod used_muts;
+mod util;
 
 /// A public API provided for the Rust compiler consumers.
 pub mod consumers;
diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs
index 288b7d85be2..08fa912f368 100644
--- a/compiler/rustc_borrowck/src/location.rs
+++ b/compiler/rustc_borrowck/src/location.rs
@@ -1,6 +1,6 @@
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-use rustc_index::vec::{Idx, IndexVec};
+use rustc_index::vec::IndexVec;
 use rustc_middle::mir::{BasicBlock, Body, Location};
 
 /// Maps between a MIR Location, which identifies a particular
@@ -50,19 +50,19 @@ impl LocationTable {
     }
 
     pub fn all_points(&self) -> impl Iterator<Item = LocationIndex> {
-        (0..self.num_points).map(LocationIndex::new)
+        (0..self.num_points).map(LocationIndex::from_usize)
     }
 
     pub fn start_index(&self, location: Location) -> LocationIndex {
         let Location { block, statement_index } = location;
         let start_index = self.statements_before_block[block];
-        LocationIndex::new(start_index + statement_index * 2)
+        LocationIndex::from_usize(start_index + statement_index * 2)
     }
 
     pub fn mid_index(&self, location: Location) -> LocationIndex {
         let Location { block, statement_index } = location;
         let start_index = self.statements_before_block[block];
-        LocationIndex::new(start_index + statement_index * 2 + 1)
+        LocationIndex::from_usize(start_index + statement_index * 2 + 1)
     }
 
     pub fn to_location(&self, index: LocationIndex) -> RichLocation {
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 59a3ab3189d..73b8765e57d 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -7,8 +7,8 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_index::vec::IndexSlice;
 use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere};
 use rustc_middle::mir::{
-    BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
-    Promoted,
+    Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location, Promoted,
+    START_BLOCK,
 };
 use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt};
 use rustc_span::symbol::sym;
@@ -94,8 +94,8 @@ fn populate_polonius_move_facts(
         }
     }
 
-    let fn_entry_start = location_table
-        .start_index(Location { block: BasicBlock::from_u32(0u32), statement_index: 0 });
+    let fn_entry_start =
+        location_table.start_index(Location { block: START_BLOCK, statement_index: 0 });
 
     // initialized_at
     for init in move_data.inits.iter() {
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index a3678929099..bb95101845f 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -184,7 +184,7 @@ pub(crate) enum CaptureVarPathUseCause {
 #[derive(Subdiagnostic)]
 pub(crate) enum CaptureVarKind {
     #[label(borrowck_capture_immute)]
-    Immute {
+    Immut {
         #[primary_span]
         kind_span: Span,
     },
@@ -204,16 +204,80 @@ pub(crate) enum CaptureVarKind {
 pub(crate) enum CaptureVarCause {
     #[label(borrowck_var_borrow_by_use_place_in_generator)]
     BorrowUsePlaceGenerator {
+        is_single_var: bool,
         place: String,
         #[primary_span]
         var_span: Span,
     },
     #[label(borrowck_var_borrow_by_use_place_in_closure)]
     BorrowUsePlaceClosure {
+        is_single_var: bool,
         place: String,
         #[primary_span]
         var_span: Span,
     },
+    #[label(borrowck_var_borrow_by_use_in_generator)]
+    BorrowUseInGenerator {
+        #[primary_span]
+        var_span: Span,
+    },
+    #[label(borrowck_var_borrow_by_use_in_closure)]
+    BorrowUseInClosure {
+        #[primary_span]
+        var_span: Span,
+    },
+    #[label(borrowck_var_move_by_use_in_generator)]
+    MoveUseInGenerator {
+        #[primary_span]
+        var_span: Span,
+    },
+    #[label(borrowck_var_move_by_use_in_closure)]
+    MoveUseInClosure {
+        #[primary_span]
+        var_span: Span,
+    },
+    #[label(borrowck_var_first_borrow_by_use_place_in_generator)]
+    FirstBorrowUsePlaceGenerator {
+        place: String,
+        #[primary_span]
+        var_span: Span,
+    },
+    #[label(borrowck_var_first_borrow_by_use_place_in_closure)]
+    FirstBorrowUsePlaceClosure {
+        place: String,
+        #[primary_span]
+        var_span: Span,
+    },
+    #[label(borrowck_var_second_borrow_by_use_place_in_generator)]
+    SecondBorrowUsePlaceGenerator {
+        place: String,
+        #[primary_span]
+        var_span: Span,
+    },
+    #[label(borrowck_var_second_borrow_by_use_place_in_closure)]
+    SecondBorrowUsePlaceClosure {
+        place: String,
+        #[primary_span]
+        var_span: Span,
+    },
+    #[label(borrowck_var_mutable_borrow_by_use_place_in_closure)]
+    MutableBorrowUsePlaceClosure {
+        place: String,
+        #[primary_span]
+        var_span: Span,
+    },
+    #[label(borrowck_partial_var_move_by_use_in_generator)]
+    PartialMoveUseInGenerator {
+        #[primary_span]
+        var_span: Span,
+        is_partial: bool,
+    },
+    #[label(borrowck_partial_var_move_by_use_in_closure)]
+    PartialMoveUseInClosure {
+        #[primary_span]
+        var_span: Span,
+        is_partial: bool,
+    },
 }
 
 #[derive(Diagnostic)]
@@ -239,3 +303,144 @@ pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> {
     #[label]
     pub param_span: Span,
 }
+
+#[derive(Subdiagnostic)]
+pub(crate) enum CaptureReasonLabel<'a> {
+    #[label(borrowck_moved_due_to_call)]
+    Call {
+        #[primary_span]
+        fn_call_span: Span,
+        place_name: &'a str,
+        is_partial: bool,
+        is_loop_message: bool,
+    },
+    #[label(borrowck_moved_due_to_usage_in_operator)]
+    OperatorUse {
+        #[primary_span]
+        fn_call_span: Span,
+        place_name: &'a str,
+        is_partial: bool,
+        is_loop_message: bool,
+    },
+    #[label(borrowck_moved_due_to_implicit_into_iter_call)]
+    ImplicitCall {
+        #[primary_span]
+        fn_call_span: Span,
+        place_name: &'a str,
+        is_partial: bool,
+        is_loop_message: bool,
+    },
+    #[label(borrowck_moved_due_to_method_call)]
+    MethodCall {
+        #[primary_span]
+        fn_call_span: Span,
+        place_name: &'a str,
+        is_partial: bool,
+        is_loop_message: bool,
+    },
+    #[label(borrowck_value_moved_here)]
+    MovedHere {
+        #[primary_span]
+        move_span: Span,
+        is_partial: bool,
+        is_move_msg: bool,
+        is_loop_message: bool,
+    },
+    #[label(borrowck_consider_borrow_type_contents)]
+    BorrowContent {
+        #[primary_span]
+        var_span: Span,
+    },
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum CaptureReasonNote {
+    #[note(borrowck_moved_a_fn_once_in_call)]
+    FnOnceMoveInCall {
+        #[primary_span]
+        var_span: Span,
+    },
+    #[note(borrowck_calling_operator_moves_lhs)]
+    LhsMoveByOperator {
+        #[primary_span]
+        span: Span,
+    },
+    #[note(borrowck_func_take_self_moved_place)]
+    FuncTakeSelf {
+        func: String,
+        place_name: String,
+        #[primary_span]
+        span: Span,
+    },
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum CaptureReasonSuggest<'tcx> {
+    #[suggestion(
+        borrowck_suggest_iterate_over_slice,
+        applicability = "maybe-incorrect",
+        code = "&",
+        style = "verbose"
+    )]
+    IterateSlice {
+        ty: Ty<'tcx>,
+        #[primary_span]
+        span: Span,
+    },
+    #[suggestion(
+        borrowck_suggest_create_freash_reborrow,
+        applicability = "maybe-incorrect",
+        code = "as_mut().",
+        style = "verbose"
+    )]
+    FreshReborrow {
+        #[primary_span]
+        span: Span,
+    },
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum CaptureArgLabel {
+    #[label(borrowck_value_capture_here)]
+    Capture {
+        is_within: bool,
+        #[primary_span]
+        args_span: Span,
+    },
+    #[label(borrowck_move_out_place_here)]
+    MoveOutPlace {
+        place: String,
+        #[primary_span]
+        args_span: Span,
+    },
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum OnClosureNote<'a> {
+    #[note(borrowck_closure_invoked_twice)]
+    InvokedTwice {
+        place_name: &'a str,
+        #[primary_span]
+        span: Span,
+    },
+    #[note(borrowck_closure_moved_twice)]
+    MovedTwice {
+        place_name: &'a str,
+        #[primary_span]
+        span: Span,
+    },
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum TypeNoCopy<'a, 'tcx> {
+    #[label(borrowck_ty_no_impl_copy)]
+    Label {
+        is_partial_move: bool,
+        ty: Ty<'tcx>,
+        place: &'a str,
+        #[primary_span]
+        span: Span,
+    },
+    #[note(borrowck_ty_no_impl_copy)]
+    Note { is_partial_move: bool, ty: Ty<'tcx>, place: &'a str },
+}
diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs
index 17e702eb8c5..9250b8d3eaf 100644
--- a/compiler/rustc_borrowck/src/type_check/input_output.rs
+++ b/compiler/rustc_borrowck/src/type_check/input_output.rs
@@ -7,7 +7,6 @@
 //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and
 //! contain revealed `impl Trait` values).
 
-use rustc_index::vec::Idx;
 use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, Ty};
@@ -83,7 +82,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             }
 
             // In MIR, argument N is stored in local N+1.
-            let local = Local::new(argument_index + 1);
+            let local = Local::from_usize(argument_index + 1);
 
             let mir_input_ty = body.local_decls[local].ty;
 
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 70fddb1057c..74241f722a6 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -19,7 +19,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::BodyOwnerKind;
-use rustc_index::vec::{Idx, IndexVec};
+use rustc_index::vec::IndexVec;
 use rustc_infer::infer::NllRegionVariableOrigin;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt};
@@ -289,7 +289,7 @@ impl<'tcx> UniversalRegions<'tcx> {
     /// Returns an iterator over all the RegionVids corresponding to
     /// universally quantified free regions.
     pub fn universal_regions(&self) -> impl Iterator<Item = RegionVid> {
-        (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::new)
+        (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize)
     }
 
     /// Returns `true` if `r` is classified as an local region.
diff --git a/compiler/rustc_const_eval/src/util/collect_writes.rs b/compiler/rustc_borrowck/src/util/collect_writes.rs
index 8d92bb35938..8d92bb35938 100644
--- a/compiler/rustc_const_eval/src/util/collect_writes.rs
+++ b/compiler/rustc_borrowck/src/util/collect_writes.rs
diff --git a/compiler/rustc_borrowck/src/util/mod.rs b/compiler/rustc_borrowck/src/util/mod.rs
new file mode 100644
index 00000000000..7377d4de727
--- /dev/null
+++ b/compiler/rustc_borrowck/src/util/mod.rs
@@ -0,0 +1,3 @@
+mod collect_writes;
+
+pub use collect_writes::FindAssignments;
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index f0fc61d7c4f..f17df5b0a83 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -141,13 +141,7 @@ fn parse_args<'a>(ecx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<
                         args: args
                             .named_args()
                             .iter()
-                            .filter_map(|a| {
-                                if let Some(ident) = a.kind.ident() {
-                                    Some((a, ident))
-                                } else {
-                                    None
-                                }
-                            })
+                            .filter_map(|a| a.kind.ident().map(|ident| (a, ident)))
                             .map(|(arg, n)| n.span.to(arg.expr.span))
                             .collect(),
                     });
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index dd86977817f..a0a8246be15 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -12,7 +12,6 @@ use crate::MemFlags;
 use rustc_ast as ast;
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_hir::lang_items::LangItem;
-use rustc_index::vec::Idx;
 use rustc_middle::mir::{self, AssertKind, SwitchTargets};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
@@ -369,7 +368,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         if self.fn_abi.c_variadic {
             // The `VaList` "spoofed" argument is just after all the real arguments.
             let va_list_arg_idx = self.fn_abi.args.len();
-            match self.locals[mir::Local::new(1 + va_list_arg_idx)] {
+            match self.locals[mir::Local::from_usize(1 + va_list_arg_idx)] {
                 LocalRef::Place(va_list) => {
                     bx.va_end(va_list.llval);
                 }
diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs
index 557e721249d..015a9beab83 100644
--- a/compiler/rustc_const_eval/src/interpret/discriminant.rs
+++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs
@@ -211,18 +211,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                             let variant_index_relative = u32::try_from(variant_index_relative)
                                 .expect("we checked that this fits into a u32");
                             // Then computing the absolute variant idx should not overflow any more.
-                            let variant_index = variants_start
-                                .checked_add(variant_index_relative)
-                                .expect("overflow computing absolute variant idx");
-                            let variants_len = op
+                            let variant_index = VariantIdx::from_u32(
+                                variants_start
+                                    .checked_add(variant_index_relative)
+                                    .expect("overflow computing absolute variant idx"),
+                            );
+                            let variants = op
                                 .layout
                                 .ty
                                 .ty_adt_def()
                                 .expect("tagged layout for non adt")
-                                .variants()
-                                .len();
-                            assert!(usize::try_from(variant_index).unwrap() < variants_len);
-                            VariantIdx::from_u32(variant_index)
+                                .variants();
+                            assert!(variant_index < variants.next_index());
+                            variant_index
                         } else {
                             untagged_variant
                         }
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 3e58a58aef7..b5b5cc4f196 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -132,11 +132,10 @@ pub struct Frame<'mir, 'tcx, Prov: Provenance = AllocId, Extra = ()> {
 }
 
 /// What we store about a frame in an interpreter backtrace.
-#[derive(Debug)]
+#[derive(Clone, Debug)]
 pub struct FrameInfo<'tcx> {
     pub instance: ty::Instance<'tcx>,
     pub span: Span,
-    pub lint_root: Option<hir::HirId>,
 }
 
 #[derive(Clone, Copy, Eq, PartialEq, Debug)] // Miri debug-prints these
@@ -947,10 +946,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // This deliberately does *not* honor `requires_caller_location` since it is used for much
         // more than just panics.
         for frame in stack.iter().rev() {
-            let lint_root = frame.lint_root();
             let span = frame.current_span();
-
-            frames.push(FrameInfo { span, instance: frame.instance, lint_root });
+            frames.push(FrameInfo { span, instance: frame.instance });
         }
         trace!("generate stacktrace: {:#?}", frames);
         frames
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 0291cca7378..b448e3a24c6 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -104,7 +104,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
     type FrameExtra;
 
     /// Extra data stored in every allocation.
-    type AllocExtra: Debug + Clone + 'static;
+    type AllocExtra: Debug + Clone + 'tcx;
 
     /// Type for the bytes of the allocation.
     type Bytes: AllocBytes + 'static;
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index a3764a7d142..d5b6a581a79 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -215,7 +215,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         self.allocate_raw_ptr(alloc, kind)
     }
 
-    /// This can fail only of `alloc` contains provenance.
+    /// This can fail only if `alloc` contains provenance.
     pub fn allocate_raw_ptr(
         &mut self,
         alloc: Allocation,
@@ -807,9 +807,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         DumpAllocs { ecx: self, allocs }
     }
 
-    /// Print leaked memory. Allocations reachable from `static_roots` or a `Global` allocation
-    /// are not considered leaked. Leaks whose kind `may_leak()` returns true are not reported.
-    pub fn leak_report(&self, static_roots: &[AllocId]) -> usize {
+    /// Find leaked allocations. Allocations reachable from `static_roots` or a `Global` allocation
+    /// are not considered leaked, as well as leaks whose kind's `may_leak()` returns true.
+    pub fn find_leaked_allocations(
+        &self,
+        static_roots: &[AllocId],
+    ) -> Vec<(AllocId, MemoryKind<M::MemoryKind>, Allocation<M::Provenance, M::AllocExtra, M::Bytes>)>
+    {
         // Collect the set of allocations that are *reachable* from `Global` allocations.
         let reachable = {
             let mut reachable = FxHashSet::default();
@@ -833,14 +837,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         };
 
         // All allocations that are *not* `reachable` and *not* `may_leak` are considered leaking.
-        let leaks: Vec<_> = self.memory.alloc_map.filter_map_collect(|&id, &(kind, _)| {
-            if kind.may_leak() || reachable.contains(&id) { None } else { Some(id) }
-        });
-        let n = leaks.len();
-        if n > 0 {
-            eprintln!("The following memory was leaked: {:?}", self.dump_allocs(leaks));
-        }
-        n
+        self.memory.alloc_map.filter_map_collect(|id, (kind, alloc)| {
+            if kind.may_leak() || reachable.contains(id) {
+                None
+            } else {
+                Some((*id, *kind, alloc.clone()))
+            }
+        })
     }
 }
 
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index c0f5b3725b3..4fe842856aa 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -14,6 +14,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
 use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty};
 use rustc_middle::ty::{Binder, TraitRef};
+use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind};
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::sym;
 use rustc_span::{BytePos, Pos, Span, Symbol};
@@ -21,7 +22,6 @@ use rustc_trait_selection::traits::SelectionContext;
 
 use super::ConstCx;
 use crate::errors;
-use crate::util::{call_kind, CallDesugaringKind, CallKind};
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum Status {
diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs
index c0aabd77cee..7641f560714 100644
--- a/compiler/rustc_const_eval/src/util/mod.rs
+++ b/compiler/rustc_const_eval/src/util/mod.rs
@@ -1,14 +1,9 @@
 mod alignment;
-mod call_kind;
 mod check_validity_requirement;
-pub mod collect_writes;
 mod compare_types;
-mod find_self_call;
 mod type_name;
 
 pub use self::alignment::is_disaligned;
-pub use self::call_kind::{call_kind, CallDesugaringKind, CallKind};
 pub use self::check_validity_requirement::check_validity_requirement;
 pub use self::compare_types::{is_equal_up_to_subtyping, is_subtype};
-pub use self::find_self_call::find_self_call;
 pub use self::type_name::type_name;
diff --git a/compiler/rustc_data_structures/src/aligned.rs b/compiler/rustc_data_structures/src/aligned.rs
new file mode 100644
index 00000000000..0e5ecfd9bff
--- /dev/null
+++ b/compiler/rustc_data_structures/src/aligned.rs
@@ -0,0 +1,33 @@
+use std::ptr::Alignment;
+
+/// Returns the ABI-required minimum alignment of a type in bytes.
+///
+/// This is equivalent to [`mem::align_of`], but also works for some unsized
+/// types (e.g. slices or rustc's `List`s).
+///
+/// [`mem::align_of`]: std::mem::align_of
+pub const fn align_of<T: ?Sized + Aligned>() -> Alignment {
+    T::ALIGN
+}
+
+/// A type with a statically known alignment.
+///
+/// # Safety
+///
+/// `Self::ALIGN` must be equal to the alignment of `Self`. For sized types it
+/// is [`mem::align_of<Self>()`], for unsized types it depends on the type, for
+/// example `[T]` has alignment of `T`.
+///
+/// [`mem::align_of<Self>()`]: std::mem::align_of
+pub unsafe trait Aligned {
+    /// Alignment of `Self`.
+    const ALIGN: Alignment;
+}
+
+unsafe impl<T> Aligned for T {
+    const ALIGN: Alignment = Alignment::of::<Self>();
+}
+
+unsafe impl<T> Aligned for [T] {
+    const ALIGN: Alignment = Alignment::of::<T>();
+}
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index e373bd18402..7768e0fdeb1 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -29,6 +29,8 @@
 #![feature(get_mut_unchecked)]
 #![feature(lint_reasons)]
 #![feature(unwrap_infallible)]
+#![feature(strict_provenance)]
+#![feature(ptr_alignment_type)]
 #![allow(rustc::default_hash_types)]
 #![allow(rustc::potential_query_instability)]
 #![deny(rustc::untranslatable_diagnostic)]
@@ -82,6 +84,7 @@ pub mod transitive_relation;
 pub mod vec_linked_list;
 pub mod work_queue;
 pub use atomic_ref::AtomicRef;
+pub mod aligned;
 pub mod frozen;
 pub mod owned_slice;
 pub mod sso;
diff --git a/compiler/rustc_data_structures/src/sso/map.rs b/compiler/rustc_data_structures/src/sso/map.rs
index 89b8c852649..99581ed2375 100644
--- a/compiler/rustc_data_structures/src/sso/map.rs
+++ b/compiler/rustc_data_structures/src/sso/map.rs
@@ -256,12 +256,9 @@ impl<K: Eq + Hash, V> SsoHashMap<K, V> {
     pub fn remove(&mut self, key: &K) -> Option<V> {
         match self {
             SsoHashMap::Array(array) => {
-                if let Some(index) = array.iter().position(|(k, _v)| k == key) {
-                    Some(array.swap_remove(index).1)
-                } else {
-                    None
-                }
+                array.iter().position(|(k, _v)| k == key).map(|index| array.swap_remove(index).1)
             }
+
             SsoHashMap::Map(map) => map.remove(key),
         }
     }
diff --git a/compiler/rustc_data_structures/src/svh.rs b/compiler/rustc_data_structures/src/svh.rs
index 61654b9e8f5..b955df94f16 100644
--- a/compiler/rustc_data_structures/src/svh.rs
+++ b/compiler/rustc_data_structures/src/svh.rs
@@ -5,40 +5,30 @@
 //! mismatches where we have two versions of the same crate that were
 //! compiled from distinct sources.
 
-use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
+use crate::fingerprint::Fingerprint;
 use std::fmt;
-use std::hash::{Hash, Hasher};
 
 use crate::stable_hasher;
 
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, Hash)]
 pub struct Svh {
-    hash: u64,
+    hash: Fingerprint,
 }
 
 impl Svh {
     /// Creates a new `Svh` given the hash. If you actually want to
     /// compute the SVH from some HIR, you want the `calculate_svh`
     /// function found in `rustc_incremental`.
-    pub fn new(hash: u64) -> Svh {
+    pub fn new(hash: Fingerprint) -> Svh {
         Svh { hash }
     }
 
     pub fn as_u64(&self) -> u64 {
-        self.hash
+        self.hash.to_smaller_hash()
     }
 
     pub fn to_string(&self) -> String {
-        format!("{:016x}", self.hash)
-    }
-}
-
-impl Hash for Svh {
-    fn hash<H>(&self, state: &mut H)
-    where
-        H: Hasher,
-    {
-        self.hash.to_le().hash(state);
+        format!("{:016x}", self.hash.to_smaller_hash())
     }
 }
 
@@ -48,18 +38,6 @@ impl fmt::Display for Svh {
     }
 }
 
-impl<S: Encoder> Encodable<S> for Svh {
-    fn encode(&self, s: &mut S) {
-        s.emit_u64(self.as_u64().to_le());
-    }
-}
-
-impl<D: Decoder> Decodable<D> for Svh {
-    fn decode(d: &mut D) -> Svh {
-        Svh::new(u64::from_le(d.read_u64()))
-    }
-}
-
 impl<T> stable_hasher::HashStable<T> for Svh {
     #[inline]
     fn hash_stable(&self, ctx: &mut T, hasher: &mut stable_hasher::StableHasher) {
diff --git a/compiler/rustc_data_structures/src/tagged_ptr.rs b/compiler/rustc_data_structures/src/tagged_ptr.rs
index 651bc556c98..c26bffac678 100644
--- a/compiler/rustc_data_structures/src/tagged_ptr.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr.rs
@@ -3,166 +3,262 @@
 //! In order to utilize the pointer packing, you must have two types: a pointer,
 //! and a tag.
 //!
-//! The pointer must implement the `Pointer` trait, with the primary requirement
-//! being conversion to and from a usize. Note that the pointer must be
-//! dereferenceable, so raw pointers generally cannot implement the `Pointer`
-//! trait. This implies that the pointer must also be nonzero.
+//! The pointer must implement the [`Pointer`] trait, with the primary
+//! requirement being convertible to and from a raw pointer. Note that the
+//! pointer must be dereferenceable, so raw pointers generally cannot implement
+//! the [`Pointer`] trait. This implies that the pointer must also be non-null.
 //!
-//! Many common pointer types already implement the `Pointer` trait.
+//! Many common pointer types already implement the [`Pointer`] trait.
 //!
-//! The tag must implement the `Tag` trait. We assert that the tag and `Pointer`
-//! are compatible at compile time.
+//! The tag must implement the [`Tag`] trait.
+//!
+//! We assert that the tag and the [`Pointer`] types are compatible at compile
+//! time.
 
-use std::mem::ManuallyDrop;
 use std::ops::Deref;
+use std::ptr::NonNull;
 use std::rc::Rc;
 use std::sync::Arc;
 
+use crate::aligned::Aligned;
+
 mod copy;
 mod drop;
 
 pub use copy::CopyTaggedPtr;
 pub use drop::TaggedPtr;
 
-/// This describes the pointer type encapsulated by TaggedPtr.
+/// This describes the pointer type encapsulated by [`TaggedPtr`] and
+/// [`CopyTaggedPtr`].
 ///
 /// # Safety
 ///
-/// The usize returned from `into_usize` must be a valid, dereferenceable,
-/// pointer to `<Self as Deref>::Target`. Note that pointers to `Pointee` must
-/// be thin, even though `Pointee` may not be sized.
+/// The pointer returned from [`into_ptr`] must be a [valid], pointer to
+/// [`<Self as Deref>::Target`].
 ///
-/// Note that the returned pointer from `into_usize` should be castable to `&mut
-/// <Self as Deref>::Target` if `Pointer: DerefMut`.
+/// Note that if `Self` implements [`DerefMut`] the pointer returned from
+/// [`into_ptr`] must be valid for writes (and thus calling [`NonNull::as_mut`]
+/// on it must be safe).
 ///
-/// The BITS constant must be correct. At least `BITS` bits, least-significant,
-/// must be zero on all returned pointers from `into_usize`.
+/// The [`BITS`] constant must be correct. [`BITS`] least-significant bits,
+/// must be zero on all pointers returned from [`into_ptr`].
 ///
-/// For example, if the alignment of `Pointee` is 2, then `BITS` should be 1.
+/// For example, if the alignment of [`Self::Target`] is 2, then `BITS` should be 1.
+///
+/// [`BITS`]: Pointer::BITS
+/// [`into_ptr`]: Pointer::into_ptr
+/// [valid]: std::ptr#safety
+/// [`<Self as Deref>::Target`]: Deref::Target
+/// [`Self::Target`]: Deref::Target
+/// [`DerefMut`]: std::ops::DerefMut
 pub unsafe trait Pointer: Deref {
+    /// Number of unused (always zero) **least-significant bits** in this
+    /// pointer, usually related to the pointees alignment.
+    ///
+    /// For example if [`BITS`] = `2`, then given `ptr = Self::into_ptr(..)`,
+    /// `ptr.addr() & 0b11 == 0` must be true.
+    ///
     /// Most likely the value you want to use here is the following, unless
-    /// your Pointee type is unsized (e.g., `ty::List<T>` in rustc) in which
-    /// case you'll need to manually figure out what the right type to pass to
-    /// align_of is.
+    /// your [`Self::Target`] type is unsized (e.g., `ty::List<T>` in rustc)
+    /// or your pointer is over/under aligned, in which case you'll need to
+    /// manually figure out what the right type to pass to [`bits_for`] is, or
+    /// what the value to set here.
     ///
-    /// ```ignore UNSOLVED (what to do about the Self)
+    /// ```rust
     /// # use std::ops::Deref;
-    /// std::mem::align_of::<<Self as Deref>::Target>().trailing_zeros() as usize;
+    /// # use rustc_data_structures::tagged_ptr::bits_for;
+    /// # struct T;
+    /// # impl Deref for T { type Target = u8; fn deref(&self) -> &u8 { &0 } }
+    /// # impl T {
+    /// const BITS: u32 = bits_for::<<Self as Deref>::Target>();
+    /// # }
     /// ```
-    const BITS: usize;
-    fn into_usize(self) -> usize;
+    ///
+    /// [`BITS`]: Pointer::BITS
+    /// [`Self::Target`]: Deref::Target
+    const BITS: u32;
 
-    /// # Safety
+    /// Turns this pointer into a raw, non-null pointer.
+    ///
+    /// The inverse of this function is [`from_ptr`].
     ///
-    /// The passed `ptr` must be returned from `into_usize`.
+    /// This function guarantees that the least-significant [`Self::BITS`] bits
+    /// are zero.
     ///
-    /// This acts as `ptr::read` semantically, it should not be called more than
-    /// once on non-`Copy` `Pointer`s.
-    unsafe fn from_usize(ptr: usize) -> Self;
+    /// [`from_ptr`]: Pointer::from_ptr
+    /// [`Self::BITS`]: Pointer::BITS
+    fn into_ptr(self) -> NonNull<Self::Target>;
 
-    /// This provides a reference to the `Pointer` itself, rather than the
-    /// `Deref::Target`. It is used for cases where we want to call methods that
-    /// may be implement differently for the Pointer than the Pointee (e.g.,
-    /// `Rc::clone` vs cloning the inner value).
+    /// Re-creates the original pointer, from a raw pointer returned by [`into_ptr`].
     ///
     /// # Safety
     ///
-    /// The passed `ptr` must be returned from `into_usize`.
-    unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R;
+    /// The passed `ptr` must be returned from [`into_ptr`].
+    ///
+    /// This acts as [`ptr::read::<Self>()`] semantically, it should not be called more than
+    /// once on non-[`Copy`] `Pointer`s.
+    ///
+    /// [`into_ptr`]: Pointer::into_ptr
+    /// [`ptr::read::<Self>()`]: std::ptr::read
+    unsafe fn from_ptr(ptr: NonNull<Self::Target>) -> Self;
 }
 
-/// This describes tags that the `TaggedPtr` struct can hold.
+/// This describes tags that the [`TaggedPtr`] struct can hold.
 ///
 /// # Safety
 ///
-/// The BITS constant must be correct.
+/// The [`BITS`] constant must be correct.
+///
+/// No more than [`BITS`] least-significant bits may be set in the returned usize.
 ///
-/// No more than `BITS` least significant bits may be set in the returned usize.
+/// [`BITS`]: Tag::BITS
 pub unsafe trait Tag: Copy {
-    const BITS: usize;
+    /// Number of least-significant bits in the return value of [`into_usize`]
+    /// which may be non-zero. In other words this is the bit width of the
+    /// value.
+    ///
+    /// [`into_usize`]: Tag::into_usize
+    const BITS: u32;
 
+    /// Turns this tag into an integer.
+    ///
+    /// The inverse of this function is [`from_usize`].
+    ///
+    /// This function guarantees that only the least-significant [`Self::BITS`]
+    /// bits can be non-zero.
+    ///
+    /// [`from_usize`]: Tag::from_usize
+    /// [`Self::BITS`]: Tag::BITS
     fn into_usize(self) -> usize;
 
+    /// Re-creates the tag from the integer returned by [`into_usize`].
+    ///
     /// # Safety
     ///
-    /// The passed `tag` must be returned from `into_usize`.
+    /// The passed `tag` must be returned from [`into_usize`].
+    ///
+    /// [`into_usize`]: Tag::into_usize
     unsafe fn from_usize(tag: usize) -> Self;
 }
 
-unsafe impl<T> Pointer for Box<T> {
-    const BITS: usize = std::mem::align_of::<T>().trailing_zeros() as usize;
+unsafe impl<T: ?Sized + Aligned> Pointer for Box<T> {
+    const BITS: u32 = bits_for::<Self::Target>();
+
     #[inline]
-    fn into_usize(self) -> usize {
-        Box::into_raw(self) as usize
+    fn into_ptr(self) -> NonNull<T> {
+        // Safety: pointers from `Box::into_raw` are valid & non-null
+        unsafe { NonNull::new_unchecked(Box::into_raw(self)) }
     }
+
     #[inline]
-    unsafe fn from_usize(ptr: usize) -> Self {
-        Box::from_raw(ptr as *mut T)
-    }
-    unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R {
-        let raw = ManuallyDrop::new(Self::from_usize(ptr));
-        f(&raw)
+    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 impl<T> Pointer for Rc<T> {
-    const BITS: usize = std::mem::align_of::<T>().trailing_zeros() as usize;
+unsafe impl<T: ?Sized + Aligned> Pointer for Rc<T> {
+    const BITS: u32 = bits_for::<Self::Target>();
+
     #[inline]
-    fn into_usize(self) -> usize {
-        Rc::into_raw(self) as usize
+    fn into_ptr(self) -> NonNull<T> {
+        // Safety: pointers from `Rc::into_raw` are valid & non-null
+        unsafe { NonNull::new_unchecked(Rc::into_raw(self).cast_mut()) }
+    }
+
+    #[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 impl<T: ?Sized + Aligned> Pointer for Arc<T> {
+    const BITS: u32 = bits_for::<Self::Target>();
+
     #[inline]
-    unsafe fn from_usize(ptr: usize) -> Self {
-        Rc::from_raw(ptr as *const T)
+    fn into_ptr(self) -> NonNull<T> {
+        // Safety: pointers from `Arc::into_raw` are valid & non-null
+        unsafe { NonNull::new_unchecked(Arc::into_raw(self).cast_mut()) }
     }
-    unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R {
-        let raw = ManuallyDrop::new(Self::from_usize(ptr));
-        f(&raw)
+
+    #[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 impl<T> Pointer for Arc<T> {
-    const BITS: usize = std::mem::align_of::<T>().trailing_zeros() as usize;
+unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a T {
+    const BITS: u32 = bits_for::<Self::Target>();
+
     #[inline]
-    fn into_usize(self) -> usize {
-        Arc::into_raw(self) as usize
+    fn into_ptr(self) -> NonNull<T> {
+        NonNull::from(self)
     }
+
     #[inline]
-    unsafe fn from_usize(ptr: usize) -> Self {
-        Arc::from_raw(ptr as *const T)
-    }
-    unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R {
-        let raw = ManuallyDrop::new(Self::from_usize(ptr));
-        f(&raw)
+    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 impl<'a, T: 'a> Pointer for &'a T {
-    const BITS: usize = std::mem::align_of::<T>().trailing_zeros() as usize;
+unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T {
+    const BITS: u32 = bits_for::<Self::Target>();
+
     #[inline]
-    fn into_usize(self) -> usize {
-        self as *const T as usize
+    fn into_ptr(self) -> NonNull<T> {
+        NonNull::from(self)
     }
+
     #[inline]
-    unsafe fn from_usize(ptr: usize) -> Self {
-        &*(ptr as *const T)
-    }
-    unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R {
-        f(&*(&ptr as *const usize as *const Self))
+    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 impl<'a, T: 'a> Pointer for &'a mut T {
-    const BITS: usize = std::mem::align_of::<T>().trailing_zeros() as usize;
-    #[inline]
+/// Returns the number of bits available for use for tags in a pointer to `T`
+/// (this is based on `T`'s alignment).
+pub const fn bits_for<T: ?Sized + Aligned>() -> u32 {
+    crate::aligned::align_of::<T>().as_nonzero().trailing_zeros()
+}
+
+/// A tag type used in [`CopyTaggedPtr`] and [`TaggedPtr`] tests.
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[cfg(test)]
+enum Tag2 {
+    B00 = 0b00,
+    B01 = 0b01,
+    B10 = 0b10,
+    B11 = 0b11,
+}
+
+#[cfg(test)]
+unsafe impl Tag for Tag2 {
+    const BITS: u32 = 2;
+
     fn into_usize(self) -> usize {
-        self as *mut T as usize
+        self as _
     }
-    #[inline]
-    unsafe fn from_usize(ptr: usize) -> Self {
-        &mut *(ptr as *mut T)
+
+    unsafe fn from_usize(tag: usize) -> Self {
+        match tag {
+            0b00 => Tag2::B00,
+            0b01 => Tag2::B01,
+            0b10 => Tag2::B10,
+            0b11 => Tag2::B11,
+            _ => unreachable!(),
+        }
     }
-    unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R {
-        f(&*(&ptr as *const usize as *const Self))
+}
+
+#[cfg(test)]
+impl<HCX> crate::stable_hasher::HashStable<HCX> for Tag2 {
+    fn hash_stable(&self, hcx: &mut HCX, hasher: &mut crate::stable_hasher::StableHasher) {
+        (*self as u8).hash_stable(hcx, hasher);
     }
 }
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
index e1d3e0bd35a..691e92f196a 100644
--- a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
@@ -1,78 +1,92 @@
 use super::{Pointer, Tag};
 use crate::stable_hasher::{HashStable, StableHasher};
 use std::fmt;
+use std::hash::{Hash, Hasher};
 use std::marker::PhantomData;
+use std::mem::ManuallyDrop;
 use std::num::NonZeroUsize;
+use std::ops::{Deref, DerefMut};
+use std::ptr::NonNull;
 
-/// A `Copy` TaggedPtr.
+/// A [`Copy`] tagged pointer.
 ///
-/// You should use this instead of the `TaggedPtr` type in all cases where
-/// `P: Copy`.
+/// This is essentially `{ pointer: P, tag: T }` packed in a single pointer.
+///
+/// You should use this instead of the [`TaggedPtr`] type in all cases where
+/// `P` implements [`Copy`].
 ///
 /// If `COMPARE_PACKED` is true, then the pointers will be compared and hashed without
-/// unpacking. Otherwise we don't implement PartialEq/Eq/Hash; if you want that,
-/// wrap the TaggedPtr.
+/// unpacking. Otherwise we don't implement [`PartialEq`], [`Eq`] and [`Hash`];
+/// if you want that, wrap the [`CopyTaggedPtr`].
+///
+/// [`TaggedPtr`]: crate::tagged_ptr::TaggedPtr
 pub struct CopyTaggedPtr<P, T, const COMPARE_PACKED: bool>
 where
     P: Pointer,
     T: Tag,
 {
-    packed: NonZeroUsize,
-    data: PhantomData<(P, T)>,
-}
-
-impl<P, T, const COMPARE_PACKED: bool> Copy for CopyTaggedPtr<P, T, COMPARE_PACKED>
-where
-    P: Pointer,
-    T: Tag,
-    P: Copy,
-{
-}
-
-impl<P, T, const COMPARE_PACKED: bool> Clone for CopyTaggedPtr<P, T, COMPARE_PACKED>
-where
-    P: Pointer,
-    T: Tag,
-    P: Copy,
-{
-    fn clone(&self) -> Self {
-        *self
-    }
+    /// This is semantically a pair of `pointer: P` and `tag: T` fields,
+    /// however we pack them in a single pointer, to save space.
+    ///
+    /// We pack the tag into the **most**-significant bits of the pointer to
+    /// ease retrieval of the value. A left shift is a multiplication and
+    /// those are embeddable in instruction encoding, for example:
+    ///
+    /// ```asm
+    /// // (<https://godbolt.org/z/jqcYPWEr3>)
+    /// example::shift_read3:
+    ///     mov     eax, dword ptr [8*rdi]
+    ///     ret
+    ///
+    /// example::mask_read3:
+    ///     and     rdi, -8
+    ///     mov     eax, dword ptr [rdi]
+    ///     ret
+    /// ```
+    ///
+    /// This is ASM outputted by rustc for reads of values behind tagged
+    /// pointers for different approaches of tagging:
+    /// - `shift_read3` uses `<< 3` (the tag is in the most-significant bits)
+    /// - `mask_read3` uses `& !0b111` (the tag is in the least-significant bits)
+    ///
+    /// The shift approach thus produces less instructions and is likely faster
+    /// (see <https://godbolt.org/z/Y913sMdWb>).
+    ///
+    /// Encoding diagram:
+    /// ```text
+    /// [ packed.addr                     ]
+    /// [ tag ] [ pointer.addr >> T::BITS ] <-- usize::BITS - T::BITS bits
+    ///    ^
+    ///    |
+    /// T::BITS bits
+    /// ```
+    ///
+    /// The tag can be retrieved by `packed.addr() >> T::BITS` and the pointer
+    /// can be retrieved by `packed.map_addr(|addr| addr << T::BITS)`.
+    packed: NonNull<P::Target>,
+    tag_ghost: PhantomData<T>,
 }
 
-// We pack the tag into the *upper* bits of the pointer to ease retrieval of the
-// value; a left shift is a multiplication and those are embeddable in
-// instruction encoding.
-impl<P, T, const COMPARE_PACKED: bool> CopyTaggedPtr<P, T, COMPARE_PACKED>
+// Note that even though `CopyTaggedPtr` is only really expected to work with
+// `P: Copy`, can't add `P: Copy` bound, because `CopyTaggedPtr` is used in the
+// `TaggedPtr`'s implementation.
+impl<P, T, const CP: bool> CopyTaggedPtr<P, T, CP>
 where
     P: Pointer,
     T: Tag,
 {
-    const TAG_BIT_SHIFT: usize = usize::BITS as usize - T::BITS;
-    const ASSERTION: () = {
-        assert!(T::BITS <= P::BITS);
-        // Used for the transmute_copy's below
-        assert!(std::mem::size_of::<&P::Target>() == std::mem::size_of::<usize>());
-    };
-
+    /// Tags `pointer` with `tag`.
+    ///
+    /// Note that this leaks `pointer`: it won't be dropped when
+    /// `CopyTaggedPtr` is dropped. If you have a pointer with a significant
+    /// drop, use [`TaggedPtr`] instead.
+    ///
+    /// [`TaggedPtr`]: crate::tagged_ptr::TaggedPtr
     pub fn new(pointer: P, tag: T) -> Self {
-        // Trigger assert!
-        let () = Self::ASSERTION;
-        let packed_tag = tag.into_usize() << Self::TAG_BIT_SHIFT;
-
-        Self {
-            // SAFETY: We know that the pointer is non-null, as it must be
-            // dereferenceable per `Pointer` safety contract.
-            packed: unsafe {
-                NonZeroUsize::new_unchecked((P::into_usize(pointer) >> T::BITS) | packed_tag)
-            },
-            data: PhantomData,
-        }
+        Self { packed: Self::pack(P::into_ptr(pointer), tag), tag_ghost: PhantomData }
     }
 
-    pub(super) fn pointer_raw(&self) -> usize {
-        self.packed.get() << T::BITS
-    }
+    /// Retrieves the pointer.
     pub fn pointer(self) -> P
     where
         P: Copy,
@@ -81,66 +95,138 @@ where
         //
         // Note that this isn't going to double-drop or anything because we have
         // P: Copy
-        unsafe { P::from_usize(self.pointer_raw()) }
-    }
-    pub fn pointer_ref(&self) -> &P::Target {
-        // SAFETY: pointer_raw returns the original pointer
-        unsafe { std::mem::transmute_copy(&self.pointer_raw()) }
-    }
-    pub fn pointer_mut(&mut self) -> &mut P::Target
-    where
-        P: std::ops::DerefMut,
-    {
-        // SAFETY: pointer_raw returns the original pointer
-        unsafe { std::mem::transmute_copy(&self.pointer_raw()) }
+        unsafe { P::from_ptr(self.pointer_raw()) }
     }
+
+    /// Retrieves the tag.
     #[inline]
     pub fn tag(&self) -> T {
-        unsafe { T::from_usize(self.packed.get() >> Self::TAG_BIT_SHIFT) }
+        // Unpack the tag, according to the `self.packed` encoding scheme
+        let tag = self.packed.addr().get() >> Self::TAG_BIT_SHIFT;
+
+        // Safety:
+        // The shift retrieves the original value from `T::into_usize`,
+        // satisfying `T::from_usize`'s preconditions.
+        unsafe { T::from_usize(tag) }
     }
+
+    /// Sets the tag to a new value.
     #[inline]
     pub fn set_tag(&mut self, tag: T) {
-        let mut packed = self.packed.get();
-        let new_tag = T::into_usize(tag) << Self::TAG_BIT_SHIFT;
-        let tag_mask = (1 << T::BITS) - 1;
-        packed &= !(tag_mask << Self::TAG_BIT_SHIFT);
-        packed |= new_tag;
-        self.packed = unsafe { NonZeroUsize::new_unchecked(packed) };
+        self.packed = Self::pack(self.pointer_raw(), tag);
+    }
+
+    const TAG_BIT_SHIFT: u32 = usize::BITS - T::BITS;
+    const ASSERTION: () = { assert!(T::BITS <= P::BITS) };
+
+    /// Pack pointer `ptr` that comes from [`P::into_ptr`] with a `tag`,
+    /// according to `self.packed` encoding scheme.
+    ///
+    /// [`P::into_ptr`]: Pointer::into_ptr
+    fn pack(ptr: NonNull<P::Target>, tag: T) -> NonNull<P::Target> {
+        // Trigger assert!
+        let () = Self::ASSERTION;
+
+        let packed_tag = tag.into_usize() << Self::TAG_BIT_SHIFT;
+
+        ptr.map_addr(|addr| {
+            // Safety:
+            // - The pointer is `NonNull` => it's address is `NonZeroUsize`
+            // - `P::BITS` least significant bits are always zero (`Pointer` contract)
+            // - `T::BITS <= P::BITS` (from `Self::ASSERTION`)
+            //
+            // Thus `addr >> T::BITS` is guaranteed to be non-zero.
+            //
+            // `{non_zero} | packed_tag` can't make the value zero.
+
+            let packed = (addr.get() >> T::BITS) | packed_tag;
+            unsafe { NonZeroUsize::new_unchecked(packed) }
+        })
+    }
+
+    /// Retrieves the original raw pointer from `self.packed`.
+    pub(super) fn pointer_raw(&self) -> NonNull<P::Target> {
+        self.packed.map_addr(|addr| unsafe { NonZeroUsize::new_unchecked(addr.get() << T::BITS) })
+    }
+
+    /// This provides a reference to the `P` pointer itself, rather than the
+    /// `Deref::Target`. It is used for cases where we want to call methods
+    /// that may be implement differently for the Pointer than the Pointee
+    /// (e.g., `Rc::clone` vs cloning the inner value).
+    pub(super) fn with_pointer_ref<R>(&self, f: impl FnOnce(&P) -> R) -> R {
+        // Safety:
+        // - `self.raw.pointer_raw()` is originally returned from `P::into_ptr`
+        //   and as such is valid for `P::from_ptr`.
+        //   - This also allows us to not care whatever `f` panics or not.
+        // - Even though we create a copy of the pointer, we store it inside
+        //   `ManuallyDrop` and only access it by-ref, so we don't double-drop.
+        //
+        // Semantically this is just `f(&self.pointer)` (where `self.pointer`
+        // is non-packed original pointer).
+        //
+        // Note that even though `CopyTaggedPtr` is only really expected to
+        // work with `P: Copy`, we have to assume `P: ?Copy`, because
+        // `CopyTaggedPtr` is used in the `TaggedPtr`'s implementation.
+        let ptr = unsafe { ManuallyDrop::new(P::from_ptr(self.pointer_raw())) };
+        f(&ptr)
     }
 }
 
-impl<P, T, const COMPARE_PACKED: bool> std::ops::Deref for CopyTaggedPtr<P, T, COMPARE_PACKED>
+impl<P, T, const CP: bool> Copy for CopyTaggedPtr<P, T, CP>
+where
+    P: Pointer + Copy,
+    T: Tag,
+{
+}
+
+impl<P, T, const CP: bool> Clone for CopyTaggedPtr<P, T, CP>
+where
+    P: Pointer + Copy,
+    T: Tag,
+{
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+impl<P, T, const CP: bool> Deref for CopyTaggedPtr<P, T, CP>
 where
     P: Pointer,
     T: Tag,
 {
     type Target = P::Target;
+
     fn deref(&self) -> &Self::Target {
-        self.pointer_ref()
+        // Safety:
+        // `pointer_raw` returns the original pointer from `P::into_ptr` which,
+        // by the `Pointer`'s contract, must be valid.
+        unsafe { self.pointer_raw().as_ref() }
     }
 }
 
-impl<P, T, const COMPARE_PACKED: bool> std::ops::DerefMut for CopyTaggedPtr<P, T, COMPARE_PACKED>
+impl<P, T, const CP: bool> DerefMut for CopyTaggedPtr<P, T, CP>
 where
-    P: Pointer + std::ops::DerefMut,
+    P: Pointer + DerefMut,
     T: Tag,
 {
     fn deref_mut(&mut self) -> &mut Self::Target {
-        self.pointer_mut()
+        // Safety:
+        // `pointer_raw` returns the original pointer from `P::into_ptr` which,
+        // by the `Pointer`'s contract, must be valid for writes if
+        // `P: DerefMut`.
+        unsafe { self.pointer_raw().as_mut() }
     }
 }
 
-impl<P, T, const COMPARE_PACKED: bool> fmt::Debug for CopyTaggedPtr<P, T, COMPARE_PACKED>
+impl<P, T, const CP: bool> fmt::Debug for CopyTaggedPtr<P, T, CP>
 where
-    P: Pointer,
-    P::Target: fmt::Debug,
+    P: Pointer + fmt::Debug,
     T: Tag + fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("CopyTaggedPtr")
-            .field("pointer", &self.pointer_ref())
-            .field("tag", &self.tag())
-            .finish()
+        self.with_pointer_ref(|ptr| {
+            f.debug_struct("CopyTaggedPtr").field("pointer", ptr).field("tag", &self.tag()).finish()
+        })
     }
 }
 
@@ -161,25 +247,73 @@ where
 {
 }
 
-impl<P, T> std::hash::Hash for CopyTaggedPtr<P, T, true>
+impl<P, T> Hash for CopyTaggedPtr<P, T, true>
 where
     P: Pointer,
     T: Tag,
 {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+    fn hash<H: Hasher>(&self, state: &mut H) {
         self.packed.hash(state);
     }
 }
 
-impl<P, T, HCX, const COMPARE_PACKED: bool> HashStable<HCX> for CopyTaggedPtr<P, T, COMPARE_PACKED>
+impl<P, T, HCX, const CP: bool> HashStable<HCX> for CopyTaggedPtr<P, T, CP>
 where
     P: Pointer + HashStable<HCX>,
     T: Tag + HashStable<HCX>,
 {
     fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
-        unsafe {
-            Pointer::with_ref(self.pointer_raw(), |p: &P| p.hash_stable(hcx, hasher));
-        }
+        self.with_pointer_ref(|ptr| ptr.hash_stable(hcx, hasher));
         self.tag().hash_stable(hcx, hasher);
     }
 }
+
+// Safety:
+// `CopyTaggedPtr<P, T, ..>` is semantically just `{ ptr: P, tag: T }`, as such
+// it's ok to implement `Sync` as long as `P: Sync, T: Sync`
+unsafe impl<P, T, const CP: bool> Sync for CopyTaggedPtr<P, T, CP>
+where
+    P: Sync + Pointer,
+    T: Sync + Tag,
+{
+}
+
+// Safety:
+// `CopyTaggedPtr<P, T, ..>` is semantically just `{ ptr: P, tag: T }`, as such
+// it's ok to implement `Send` as long as `P: Send, T: Send`
+unsafe impl<P, T, const CP: bool> Send for CopyTaggedPtr<P, T, CP>
+where
+    P: Send + Pointer,
+    T: Send + Tag,
+{
+}
+
+/// Test that `new` does not compile if there is not enough alignment for the
+/// tag in the pointer.
+///
+/// ```compile_fail,E0080
+/// use rustc_data_structures::tagged_ptr::{CopyTaggedPtr, Tag};
+///
+/// #[derive(Copy, Clone, Debug, PartialEq, Eq)]
+/// enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, B11 = 0b11 };
+///
+/// unsafe impl Tag for Tag2 {
+///     const BITS: u32 = 2;
+///
+///     fn into_usize(self) -> usize { todo!() }
+///     unsafe fn from_usize(tag: usize) -> Self { todo!() }
+/// }
+///
+/// let value = 12u16;
+/// let reference = &value;
+/// let tag = Tag2::B01;
+///
+/// let _ptr = CopyTaggedPtr::<_, _, true>::new(reference, tag);
+/// ```
+// For some reason miri does not get the compile error
+// probably it `check`s instead of `build`ing?
+#[cfg(not(miri))]
+const _: () = ();
+
+#[cfg(test)]
+mod tests;
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs
new file mode 100644
index 00000000000..bfcc2e603de
--- /dev/null
+++ b/compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs
@@ -0,0 +1,50 @@
+use std::ptr;
+
+use crate::stable_hasher::{HashStable, StableHasher};
+use crate::tagged_ptr::{CopyTaggedPtr, Pointer, Tag, Tag2};
+
+#[test]
+fn smoke() {
+    let value = 12u32;
+    let reference = &value;
+    let tag = Tag2::B01;
+
+    let ptr = tag_ptr(reference, tag);
+
+    assert_eq!(ptr.tag(), tag);
+    assert_eq!(*ptr, 12);
+    assert!(ptr::eq(ptr.pointer(), reference));
+
+    let copy = ptr;
+
+    let mut ptr = ptr;
+    ptr.set_tag(Tag2::B00);
+    assert_eq!(ptr.tag(), Tag2::B00);
+
+    assert_eq!(copy.tag(), tag);
+    assert_eq!(*copy, 12);
+    assert!(ptr::eq(copy.pointer(), reference));
+}
+
+#[test]
+fn stable_hash_hashes_as_tuple() {
+    let hash_packed = {
+        let mut hasher = StableHasher::new();
+        tag_ptr(&12, Tag2::B11).hash_stable(&mut (), &mut hasher);
+
+        hasher.finalize()
+    };
+
+    let hash_tupled = {
+        let mut hasher = StableHasher::new();
+        (&12, Tag2::B11).hash_stable(&mut (), &mut hasher);
+        hasher.finalize()
+    };
+
+    assert_eq!(hash_packed, hash_tupled);
+}
+
+/// Helper to create tagged pointers without specifying `COMPARE_PACKED` if it does not matter.
+fn tag_ptr<P: Pointer, T: Tag>(ptr: P, tag: T) -> CopyTaggedPtr<P, T, true> {
+    CopyTaggedPtr::new(ptr, tag)
+}
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/drop.rs b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs
index b0315c93d93..d418c06b7eb 100644
--- a/compiler/rustc_data_structures/src/tagged_ptr/drop.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs
@@ -1,14 +1,21 @@
-use super::{Pointer, Tag};
-use crate::stable_hasher::{HashStable, StableHasher};
 use std::fmt;
+use std::hash::{Hash, Hasher};
+use std::ops::{Deref, DerefMut};
 
 use super::CopyTaggedPtr;
+use super::{Pointer, Tag};
+use crate::stable_hasher::{HashStable, StableHasher};
 
-/// A TaggedPtr implementing `Drop`.
+/// A tagged pointer that supports pointers that implement [`Drop`].
+///
+/// This is essentially `{ pointer: P, tag: T }` packed in a single pointer.
+///
+/// You should use [`CopyTaggedPtr`] instead of the this type in all cases
+/// where `P` implements [`Copy`].
 ///
 /// If `COMPARE_PACKED` is true, then the pointers will be compared and hashed without
-/// unpacking. Otherwise we don't implement PartialEq/Eq/Hash; if you want that,
-/// wrap the TaggedPtr.
+/// unpacking. Otherwise we don't implement [`PartialEq`], [`Eq`] and [`Hash`];
+/// if you want that, wrap the [`TaggedPtr`].
 pub struct TaggedPtr<P, T, const COMPARE_PACKED: bool>
 where
     P: Pointer,
@@ -17,58 +24,61 @@ where
     raw: CopyTaggedPtr<P, T, COMPARE_PACKED>,
 }
 
-impl<P, T, const COMPARE_PACKED: bool> Clone for TaggedPtr<P, T, COMPARE_PACKED>
-where
-    P: Pointer + Clone,
-    T: Tag,
-{
-    fn clone(&self) -> Self {
-        unsafe { Self::new(P::with_ref(self.raw.pointer_raw(), |p| p.clone()), self.raw.tag()) }
-    }
-}
-
-// We pack the tag into the *upper* bits of the pointer to ease retrieval of the
-// value; a right shift is a multiplication and those are embeddable in
-// instruction encoding.
-impl<P, T, const COMPARE_PACKED: bool> TaggedPtr<P, T, COMPARE_PACKED>
+impl<P, T, const CP: bool> TaggedPtr<P, T, CP>
 where
     P: Pointer,
     T: Tag,
 {
+    /// Tags `pointer` with `tag`.
     pub fn new(pointer: P, tag: T) -> Self {
         TaggedPtr { raw: CopyTaggedPtr::new(pointer, tag) }
     }
 
-    pub fn pointer_ref(&self) -> &P::Target {
-        self.raw.pointer_ref()
-    }
+    /// Retrieves the tag.
     pub fn tag(&self) -> T {
         self.raw.tag()
     }
+
+    /// Sets the tag to a new value.
+    pub fn set_tag(&mut self, tag: T) {
+        self.raw.set_tag(tag)
+    }
 }
 
-impl<P, T, const COMPARE_PACKED: bool> std::ops::Deref for TaggedPtr<P, T, COMPARE_PACKED>
+impl<P, T, const CP: bool> Clone for TaggedPtr<P, T, CP>
+where
+    P: Pointer + Clone,
+    T: Tag,
+{
+    fn clone(&self) -> Self {
+        let ptr = self.raw.with_pointer_ref(P::clone);
+
+        Self::new(ptr, self.tag())
+    }
+}
+
+impl<P, T, const CP: bool> Deref for TaggedPtr<P, T, CP>
 where
     P: Pointer,
     T: Tag,
 {
     type Target = P::Target;
     fn deref(&self) -> &Self::Target {
-        self.raw.pointer_ref()
+        self.raw.deref()
     }
 }
 
-impl<P, T, const COMPARE_PACKED: bool> std::ops::DerefMut for TaggedPtr<P, T, COMPARE_PACKED>
+impl<P, T, const CP: bool> DerefMut for TaggedPtr<P, T, CP>
 where
-    P: Pointer + std::ops::DerefMut,
+    P: Pointer + DerefMut,
     T: Tag,
 {
     fn deref_mut(&mut self) -> &mut Self::Target {
-        self.raw.pointer_mut()
+        self.raw.deref_mut()
     }
 }
 
-impl<P, T, const COMPARE_PACKED: bool> Drop for TaggedPtr<P, T, COMPARE_PACKED>
+impl<P, T, const CP: bool> Drop for TaggedPtr<P, T, CP>
 where
     P: Pointer,
     T: Tag,
@@ -76,22 +86,20 @@ where
     fn drop(&mut self) {
         // No need to drop the tag, as it's Copy
         unsafe {
-            drop(P::from_usize(self.raw.pointer_raw()));
+            drop(P::from_ptr(self.raw.pointer_raw()));
         }
     }
 }
 
-impl<P, T, const COMPARE_PACKED: bool> fmt::Debug for TaggedPtr<P, T, COMPARE_PACKED>
+impl<P, T, const CP: bool> fmt::Debug for TaggedPtr<P, T, CP>
 where
-    P: Pointer,
-    P::Target: fmt::Debug,
+    P: Pointer + fmt::Debug,
     T: Tag + fmt::Debug,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("TaggedPtr")
-            .field("pointer", &self.pointer_ref())
-            .field("tag", &self.tag())
-            .finish()
+        self.raw.with_pointer_ref(|ptr| {
+            f.debug_struct("TaggedPtr").field("pointer", ptr).field("tag", &self.tag()).finish()
+        })
     }
 }
 
@@ -112,17 +120,17 @@ where
 {
 }
 
-impl<P, T> std::hash::Hash for TaggedPtr<P, T, true>
+impl<P, T> Hash for TaggedPtr<P, T, true>
 where
     P: Pointer,
     T: Tag,
 {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+    fn hash<H: Hasher>(&self, state: &mut H) {
         self.raw.hash(state);
     }
 }
 
-impl<P, T, HCX, const COMPARE_PACKED: bool> HashStable<HCX> for TaggedPtr<P, T, COMPARE_PACKED>
+impl<P, T, HCX, const CP: bool> HashStable<HCX> for TaggedPtr<P, T, CP>
 where
     P: Pointer + HashStable<HCX>,
     T: Tag + HashStable<HCX>,
@@ -131,3 +139,33 @@ where
         self.raw.hash_stable(hcx, hasher);
     }
 }
+
+/// Test that `new` does not compile if there is not enough alignment for the
+/// tag in the pointer.
+///
+/// ```compile_fail,E0080
+/// use rustc_data_structures::tagged_ptr::{TaggedPtr, Tag};
+///
+/// #[derive(Copy, Clone, Debug, PartialEq, Eq)]
+/// enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, B11 = 0b11 };
+///
+/// unsafe impl Tag for Tag2 {
+///     const BITS: u32 = 2;
+///
+///     fn into_usize(self) -> usize { todo!() }
+///     unsafe fn from_usize(tag: usize) -> Self { todo!() }
+/// }
+///
+/// let value = 12u16;
+/// let reference = &value;
+/// let tag = Tag2::B01;
+///
+/// let _ptr = TaggedPtr::<_, _, true>::new(reference, tag);
+/// ```
+// For some reason miri does not get the compile error
+// probably it `check`s instead of `build`ing?
+#[cfg(not(miri))]
+const _: () = ();
+
+#[cfg(test)]
+mod tests;
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/drop/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/drop/tests.rs
new file mode 100644
index 00000000000..2c17d678d3a
--- /dev/null
+++ b/compiler/rustc_data_structures/src/tagged_ptr/drop/tests.rs
@@ -0,0 +1,71 @@
+use std::{ptr, sync::Arc};
+
+use crate::tagged_ptr::{Pointer, Tag, Tag2, TaggedPtr};
+
+#[test]
+fn smoke() {
+    let value = 12u32;
+    let reference = &value;
+    let tag = Tag2::B01;
+
+    let ptr = tag_ptr(reference, tag);
+
+    assert_eq!(ptr.tag(), tag);
+    assert_eq!(*ptr, 12);
+
+    let clone = ptr.clone();
+    assert_eq!(clone.tag(), tag);
+    assert_eq!(*clone, 12);
+
+    let mut ptr = ptr;
+    ptr.set_tag(Tag2::B00);
+    assert_eq!(ptr.tag(), Tag2::B00);
+
+    assert_eq!(clone.tag(), tag);
+    assert_eq!(*clone, 12);
+    assert!(ptr::eq(&*ptr, &*clone))
+}
+
+#[test]
+fn boxed() {
+    let value = 12u32;
+    let boxed = Box::new(value);
+    let tag = Tag2::B01;
+
+    let ptr = tag_ptr(boxed, tag);
+
+    assert_eq!(ptr.tag(), tag);
+    assert_eq!(*ptr, 12);
+
+    let clone = ptr.clone();
+    assert_eq!(clone.tag(), tag);
+    assert_eq!(*clone, 12);
+
+    let mut ptr = ptr;
+    ptr.set_tag(Tag2::B00);
+    assert_eq!(ptr.tag(), Tag2::B00);
+
+    assert_eq!(clone.tag(), tag);
+    assert_eq!(*clone, 12);
+    assert!(!ptr::eq(&*ptr, &*clone))
+}
+
+#[test]
+fn arclones() {
+    let value = 12u32;
+    let arc = Arc::new(value);
+    let tag = Tag2::B01;
+
+    let ptr = tag_ptr(arc, tag);
+
+    assert_eq!(ptr.tag(), tag);
+    assert_eq!(*ptr, 12);
+
+    let clone = ptr.clone();
+    assert!(ptr::eq(&*ptr, &*clone))
+}
+
+/// Helper to create tagged pointers without specifying `COMPARE_PACKED` if it does not matter.
+fn tag_ptr<P: Pointer, T: Tag>(ptr: P, tag: T) -> TaggedPtr<P, T, true> {
+    TaggedPtr::new(ptr, tag)
+}
diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs
index c89e7eb75f8..3e5b3c498ee 100644
--- a/compiler/rustc_hir/src/arena.rs
+++ b/compiler/rustc_hir/src/arena.rs
@@ -51,6 +51,7 @@ macro_rules! arena_types {
             [] type_binding: rustc_hir::TypeBinding<'tcx>,
             [] variant: rustc_hir::Variant<'tcx>,
             [] where_predicate: rustc_hir::WherePredicate<'tcx>,
+            [] lit: rustc_hir::Lit,
         ]);
     )
 }
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 8c58129c800..30bf8c2ad10 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -234,10 +234,7 @@ impl DefKind {
 
     #[inline]
     pub fn is_fn_like(self) -> bool {
-        match self {
-            DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Generator => true,
-            _ => false,
-        }
+        matches!(self, DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Generator)
     }
 
     /// Whether `query get_codegen_attrs` should be used with this definition.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 35a72f868fb..b274e628079 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1957,7 +1957,7 @@ pub enum ExprKind<'hir> {
     /// A unary operation (e.g., `!x`, `*x`).
     Unary(UnOp, &'hir Expr<'hir>),
     /// A literal (e.g., `1`, `"foo"`).
-    Lit(Lit),
+    Lit(&'hir Lit),
     /// A cast (e.g., `foo as f64`).
     Cast(&'hir Expr<'hir>, &'hir Ty<'hir>),
     /// A type reference (e.g., `Foo`).
diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml
index fab16b80fb5..a64466884d8 100644
--- a/compiler/rustc_hir_analysis/Cargo.toml
+++ b/compiler/rustc_hir_analysis/Cargo.toml
@@ -23,7 +23,7 @@ rustc_span = { path = "../rustc_span" }
 rustc_index = { path = "../rustc_index" }
 rustc_infer = { path = "../rustc_infer" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
-rustc_lint = { path = "../rustc_lint" }
+rustc_lint_defs = { path = "../rustc_lint_defs" }
 rustc_type_ir = { path = "../rustc_type_ir" }
 rustc_feature = { path = "../rustc_feature" }
 thin-vec = "0.2.12"
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 0bb98fdf2a2..0c54fd70c9b 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -15,7 +15,7 @@ use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{DefiningAnchor, RegionVariableOrigin, TyCtxtInferExt};
 use rustc_infer::traits::{Obligation, TraitEngineExt as _};
-use rustc_lint::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
+use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::stability::EvalResult;
 use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 5d119a7737a..863a9977446 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -1317,7 +1317,7 @@ fn compare_number_of_generics<'tcx>(
                         impl_count,
                         kind,
                         pluralize!(impl_count),
-                        suffix.unwrap_or_else(String::new),
+                        suffix.unwrap_or_default(),
                     ),
                 );
             }
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index cbbaf8f857d..7c07a1ebaec 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1457,10 +1457,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
 }
 
 fn is_foreign_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
-    match tcx.hir().get_by_def_id(def_id) {
-        Node::ForeignItem(..) => true,
-        _ => false,
-    }
+    matches!(tcx.hir().get_by_def_id(def_id), Node::ForeignItem(..))
 }
 
 fn generator_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::GeneratorKind> {
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 0a45119ff05..4d240e90b14 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -105,7 +105,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
             if let ty::RegionKind::ReEarlyBound(ebr) = r.kind() {
                 self.variances[ebr.index as usize] = ty::Invariant;
             }
-            r.super_visit_with(self)
+            ControlFlow::Continue(())
         }
 
         #[instrument(level = "trace", skip(self), ret)]
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 13442c31649..525acfdaa81 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -17,7 +17,6 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeFoldable};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{BytePos, Span, DUMMY_SP};
-use rustc_target::abi::FieldIdx;
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::ObligationCause;
 
@@ -875,7 +874,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     variant.fields.len() == 1
                 })
                 .filter_map(|variant| {
-                    let sole_field = &variant.fields[FieldIdx::from_u32(0)];
+                    let sole_field = &variant.single_field();
 
                     let field_is_local = sole_field.did.is_local();
                     let field_is_accessible =
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 6ffa0134f3d..ffc73d64fc0 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1735,10 +1735,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             } else {
                 self.check_expr_has_type_or_error(base_expr, adt_ty, |_| {
                     let base_ty = self.typeck_results.borrow().expr_ty(*base_expr);
-                    let same_adt = match (adt_ty.kind(), base_ty.kind()) {
-                        (ty::Adt(adt, _), ty::Adt(base_adt, _)) if adt == base_adt => true,
-                        _ => false,
-                    };
+                    let same_adt = matches!((adt_ty.kind(), base_ty.kind()),
+                        (ty::Adt(adt, _), ty::Adt(base_adt, _)) if adt == base_adt);
                     if self.tcx.sess.is_nightly_build() && same_adt {
                         feature_err(
                             &self.tcx.sess.parse_sess,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 5fda4e191c2..e82821850d6 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1252,7 +1252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 node: rustc_ast::LitKind::Int(lit, rustc_ast::LitIntType::Unsuffixed),
                 span,
             }) => {
-                let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) else { return false; };
+                let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(*span) else { return false; };
                 if !(snippet.starts_with("0x") || snippet.starts_with("0X")) {
                     return false;
                 }
@@ -1311,7 +1311,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // We have satisfied all requirements to provide a suggestion. Emit it.
         err.span_suggestion(
-            span,
+            *span,
             format!("if you meant to create a null pointer, use `{null_path_str}()`"),
             null_path_str + "()",
             Applicability::MachineApplicable,
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index 106f5bcd755..0fdb29a5e48 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -4,7 +4,7 @@ use rustc_hir as hir;
 use rustc_index::vec::Idx;
 use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
-use rustc_target::abi::{FieldIdx, Pointer, VariantIdx};
+use rustc_target::abi::{Pointer, VariantIdx};
 
 use super::FnCtxt;
 
@@ -28,7 +28,7 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
         }
 
         if def.variant(data_idx).fields.len() == 1 {
-            return def.variant(data_idx).fields[FieldIdx::from_u32(0)].ty(tcx, substs);
+            return def.variant(data_idx).single_field().ty(tcx, substs);
         }
     }
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 22c1e387117..27c3b796d14 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -312,13 +312,10 @@ pub fn suggest_new_region_bound(
                             Applicability::MaybeIncorrect,
                         );
                     }
-                } else if opaque.bounds.iter().any(|arg| match arg {
-                    GenericBound::Outlives(Lifetime { ident, .. })
-                        if ident.name.to_string() == lifetime_name =>
-                    {
-                        true
-                    }
-                    _ => false,
+                } else if opaque.bounds.iter().any(|arg| {
+                    matches!(arg,
+                        GenericBound::Outlives(Lifetime { ident, .. })
+                        if ident.name.to_string() == lifetime_name )
                 }) {
                 } else {
                     // get a lifetime name of existing named lifetimes if any
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index 2875448ee15..ce70bcc5c85 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -13,7 +13,7 @@ use rustc_hir::intravisit::Visitor;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::error::ExpectedFound;
 use rustc_middle::ty::print::RegionHighlightMode;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
 use rustc_span::Span;
 
 use std::ops::ControlFlow;
@@ -81,7 +81,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                     self.highlight.highlighting_region(r, self.counter);
                     self.counter += 1;
                 }
-                r.super_visit_with(self)
+                ControlFlow::Continue(())
             }
         }
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index 4dc5fc451dd..d885d040707 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -10,7 +10,6 @@ use rustc_middle::traits::{
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self as ty, GenericArgKind, IsSuggestable, Ty, TypeVisitableExt};
 use rustc_span::{sym, BytePos, Span};
-use rustc_target::abi::FieldIdx;
 
 use crate::errors::{
     ConsiderAddingAwait, FnConsiderCasting, FnItemsAreDistinct, FnUniqTypes,
@@ -114,7 +113,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn)
                     })
                     .filter_map(|variant| {
-                        let sole_field = &variant.fields[FieldIdx::from_u32(0)];
+                        let sole_field = &variant.single_field();
                         let sole_field_ty = sole_field.ty(self.tcx, substs);
                         if self.same_type_modulo_infer(sole_field_ty, exp_found.found) {
                             let variant_path =
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 66f51328bbe..f263a0773e4 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1577,10 +1577,10 @@ impl<'tcx> InferCtxt<'tcx> {
             (TyOrConstInferVar::Ty(ty_var), Ok(inner)) => {
                 use self::type_variable::TypeVariableValue;
 
-                match inner.try_type_variables_probe_ref(ty_var) {
-                    Some(TypeVariableValue::Unknown { .. }) => true,
-                    _ => false,
-                }
+                matches!(
+                    inner.try_type_variables_probe_ref(ty_var),
+                    Some(TypeVariableValue::Unknown { .. })
+                )
             }
             _ => false,
         };
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index e01b6caf430..9dd4f0a8e4c 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -89,10 +89,10 @@ impl<'tcx> PredicateObligation<'tcx> {
 impl<'tcx> TraitObligation<'tcx> {
     /// Returns `true` if the trait predicate is considered `const` in its ParamEnv.
     pub fn is_const(&self) -> bool {
-        match (self.predicate.skip_binder().constness, self.param_env.constness()) {
-            (ty::BoundConstness::ConstIfConst, hir::Constness::Const) => true,
-            _ => false,
-        }
+        matches!(
+            (self.predicate.skip_binder().constness, self.param_env.constness()),
+            (ty::BoundConstness::ConstIfConst, hir::Constness::Const)
+        )
     }
 
     pub fn derived_cause(
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 1159d11e5c0..d677d51881e 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -569,36 +569,50 @@ trait UnusedDelimLint {
             }
         }
 
-        // Prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`
-        let lhs_needs_parens = {
+        // Check if LHS needs parens to prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`.
+        {
             let mut innermost = inner;
             loop {
                 innermost = match &innermost.kind {
-                    ExprKind::Binary(_, lhs, _rhs) => lhs,
+                    ExprKind::Binary(_op, lhs, _rhs) => lhs,
                     ExprKind::Call(fn_, _params) => fn_,
                     ExprKind::Cast(expr, _ty) => expr,
                     ExprKind::Type(expr, _ty) => expr,
                     ExprKind::Index(base, _subscript) => base,
-                    _ => break false,
+                    _ => break,
                 };
                 if !classify::expr_requires_semi_to_be_stmt(innermost) {
-                    break true;
+                    return true;
                 }
             }
-        };
+        }
 
-        lhs_needs_parens
-            || (followed_by_block
-                && match &inner.kind {
-                    ExprKind::Ret(_)
-                    | ExprKind::Break(..)
-                    | ExprKind::Yield(..)
-                    | ExprKind::Yeet(..) => true,
-                    ExprKind::Range(_lhs, Some(rhs), _limits) => {
-                        matches!(rhs.kind, ExprKind::Block(..))
-                    }
-                    _ => parser::contains_exterior_struct_lit(&inner),
-                })
+        // Check if RHS needs parens to prevent false-positives in cases like `if (() == return) {}`.
+        if !followed_by_block {
+            return false;
+        }
+        let mut innermost = inner;
+        loop {
+            innermost = match &innermost.kind {
+                ExprKind::Unary(_op, expr) => expr,
+                ExprKind::Binary(_op, _lhs, rhs) => rhs,
+                ExprKind::AssignOp(_op, _lhs, rhs) => rhs,
+                ExprKind::Assign(_lhs, rhs, _span) => rhs,
+
+                ExprKind::Ret(_) | ExprKind::Yield(..) | ExprKind::Yeet(..) => return true,
+
+                ExprKind::Break(_label, None) => return false,
+                ExprKind::Break(_label, Some(break_expr)) => {
+                    return matches!(break_expr.kind, ExprKind::Block(..));
+                }
+
+                ExprKind::Range(_lhs, Some(rhs), _limits) => {
+                    return matches!(rhs.kind, ExprKind::Block(..));
+                }
+
+                _ => return parser::contains_exterior_struct_lit(&inner),
+            }
+        }
     }
 
     fn emit_unused_delims_expr(
@@ -636,20 +650,14 @@ trait UnusedDelimLint {
             return;
         }
         let spans = match value.kind {
-            ast::ExprKind::Block(ref block, None) if block.stmts.len() == 1 => {
-                if let Some(span) = block.stmts[0].span.find_ancestor_inside(value.span) {
-                    Some((value.span.with_hi(span.lo()), value.span.with_lo(span.hi())))
-                } else {
-                    None
-                }
-            }
+            ast::ExprKind::Block(ref block, None) if block.stmts.len() == 1 => block.stmts[0]
+                .span
+                .find_ancestor_inside(value.span)
+                .map(|span| (value.span.with_hi(span.lo()), value.span.with_lo(span.hi()))),
             ast::ExprKind::Paren(ref expr) => {
-                let expr_span = expr.span.find_ancestor_inside(value.span);
-                if let Some(expr_span) = expr_span {
-                    Some((value.span.with_hi(expr_span.lo()), value.span.with_lo(expr_span.hi())))
-                } else {
-                    None
-                }
+                expr.span.find_ancestor_inside(value.span).map(|expr_span| {
+                    (value.span.with_hi(expr_span.lo()), value.span.with_lo(expr_span.hi()))
+                })
             }
             _ => return,
         };
@@ -928,11 +936,10 @@ impl UnusedParens {
                 // Otherwise proceed with linting.
                 _ => {}
             }
-            let spans = if let Some(inner) = inner.span.find_ancestor_inside(value.span) {
-                Some((value.span.with_hi(inner.lo()), value.span.with_lo(inner.hi())))
-            } else {
-                None
-            };
+            let spans = inner
+                .span
+                .find_ancestor_inside(value.span)
+                .map(|inner| (value.span.with_hi(inner.lo()), value.span.with_lo(inner.hi())));
             self.emit_unused_delims(cx, value.span, spans, "pattern", keep_space);
         }
     }
@@ -1043,11 +1050,11 @@ impl EarlyLintPass for UnusedParens {
                         if self.with_self_ty_parens && b.generic_params.len() > 0 => {}
                     ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {}
                     _ => {
-                        let spans = if let Some(r) = r.span.find_ancestor_inside(ty.span) {
-                            Some((ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi())))
-                        } else {
-                            None
-                        };
+                        let spans = r
+                            .span
+                            .find_ancestor_inside(ty.span)
+                            .map(|r| (ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi())));
+
                         self.emit_unused_delims(cx, ty.span, spans, "type", (false, false));
                     }
                 }
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index f85ba38003c..a8b25ff66d7 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -112,9 +112,6 @@ struct QueryModifiers {
     /// Use a separate query provider for local and extern crates
     separate_provide_extern: Option<Ident>,
 
-    /// Always remap the ParamEnv's constness before hashing.
-    remap_env_constness: Option<Ident>,
-
     /// Generate a `feed` method to set the query's value from another query.
     feedable: Option<Ident>,
 }
@@ -130,7 +127,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
     let mut eval_always = None;
     let mut depth_limit = None;
     let mut separate_provide_extern = None;
-    let mut remap_env_constness = None;
     let mut feedable = None;
 
     while !input.is_empty() {
@@ -189,8 +185,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
             try_insert!(depth_limit = modifier);
         } else if modifier == "separate_provide_extern" {
             try_insert!(separate_provide_extern = modifier);
-        } else if modifier == "remap_env_constness" {
-            try_insert!(remap_env_constness = modifier);
         } else if modifier == "feedable" {
             try_insert!(feedable = modifier);
         } else {
@@ -211,7 +205,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
         eval_always,
         depth_limit,
         separate_provide_extern,
-        remap_env_constness,
         feedable,
     })
 }
@@ -332,7 +325,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
             eval_always,
             depth_limit,
             separate_provide_extern,
-            remap_env_constness,
         );
 
         if modifiers.cache.is_some() {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 657b903e0a8..1109e308cf0 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -823,6 +823,7 @@ fn should_encode_span(def_kind: DefKind) -> bool {
         | DefKind::TraitAlias
         | DefKind::AssocTy
         | DefKind::TyParam
+        | DefKind::ConstParam
         | DefKind::Fn
         | DefKind::Const
         | DefKind::Static(_)
@@ -837,8 +838,7 @@ fn should_encode_span(def_kind: DefKind) -> bool {
         | DefKind::Impl { .. }
         | DefKind::Closure
         | DefKind::Generator => true,
-        DefKind::ConstParam
-        | DefKind::ExternCrate
+        DefKind::ExternCrate
         | DefKind::Use
         | DefKind::ForeignMod
         | DefKind::ImplTraitPlaceholder
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index e551c76f8db..64aff27744f 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -1199,7 +1199,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
         stable_hasher.finish()
     });
 
-    Svh::new(crate_hash.to_smaller_hash())
+    Svh::new(crate_hash)
 }
 
 fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index b5b712c367d..c4e41e00520 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -348,14 +348,6 @@ impl<'tcx, R> Canonical<'tcx, QueryResponse<'tcx, R>> {
     }
 }
 
-impl<'tcx, R> Canonical<'tcx, ty::ParamEnvAnd<'tcx, R>> {
-    #[inline]
-    pub fn without_const(mut self) -> Self {
-        self.value = self.value.without_const();
-        self
-    }
-}
-
 impl<'tcx, V> Canonical<'tcx, V> {
     /// Allows you to map the `value` of a canonical while keeping the
     /// same set of bound variables.
@@ -400,10 +392,8 @@ pub type QueryOutlivesConstraint<'tcx> =
     (ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>, ConstraintCategory<'tcx>);
 
 TrivialTypeTraversalAndLiftImpls! {
-    for <'tcx> {
-        crate::infer::canonical::Certainty,
-        crate::infer::canonical::CanonicalTyVarKind,
-    }
+    crate::infer::canonical::Certainty,
+    crate::infer::canonical::CanonicalTyVarKind,
 }
 
 impl<'tcx> CanonicalVarValues<'tcx> {
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index b4edb02f6c4..2fa769d3abb 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -59,6 +59,7 @@
 #![feature(result_option_inspect)]
 #![feature(const_option)]
 #![feature(trait_alias)]
+#![feature(ptr_alignment_type)]
 #![recursion_limit = "512"]
 #![allow(rustc::potential_query_instability)]
 
@@ -99,13 +100,9 @@ pub mod mir;
 pub mod thir;
 pub mod traits;
 pub mod ty;
+pub mod util;
 mod values;
 
-pub mod util {
-    pub mod bug;
-    pub mod common;
-}
-
 // Allows macros to refer to this crate as `::rustc_middle`
 extern crate self as rustc_middle;
 
diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs
index 89014f62d4d..cd1c6c330bc 100644
--- a/compiler/rustc_middle/src/macros.rs
+++ b/compiler/rustc_middle/src/macros.rs
@@ -43,34 +43,26 @@ macro_rules! span_bug {
 
 #[macro_export]
 macro_rules! CloneLiftImpls {
-    (for <$tcx:lifetime> { $($ty:ty,)+ }) => {
+    ($($ty:ty,)+) => {
         $(
-            impl<$tcx> $crate::ty::Lift<$tcx> for $ty {
+            impl<'tcx> $crate::ty::Lift<'tcx> for $ty {
                 type Lifted = Self;
-                fn lift_to_tcx(self, _: $crate::ty::TyCtxt<$tcx>) -> Option<Self> {
+                fn lift_to_tcx(self, _: $crate::ty::TyCtxt<'tcx>) -> Option<Self> {
                     Some(self)
                 }
             }
         )+
     };
-
-    ($($ty:ty,)+) => {
-        CloneLiftImpls! {
-            for <'tcx> {
-                $($ty,)+
-            }
-        }
-    };
 }
 
 /// Used for types that are `Copy` and which **do not care arena
 /// allocated data** (i.e., don't need to be folded).
 #[macro_export]
 macro_rules! TrivialTypeTraversalImpls {
-    (for <$tcx:lifetime> { $($ty:ty,)+ }) => {
+    ($($ty:ty,)+) => {
         $(
-            impl<$tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<$tcx>> for $ty {
-                fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$crate::ty::TyCtxt<$tcx>>>(
+            impl<'tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<'tcx>> for $ty {
+                fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$crate::ty::TyCtxt<'tcx>>>(
                     self,
                     _: &mut F,
                 ) -> ::std::result::Result<Self, F::Error> {
@@ -78,7 +70,7 @@ macro_rules! TrivialTypeTraversalImpls {
                 }
 
                 #[inline]
-                fn fold_with<F: $crate::ty::fold::TypeFolder<$crate::ty::TyCtxt<$tcx>>>(
+                fn fold_with<F: $crate::ty::fold::TypeFolder<$crate::ty::TyCtxt<'tcx>>>(
                     self,
                     _: &mut F,
                 ) -> Self {
@@ -86,9 +78,9 @@ macro_rules! TrivialTypeTraversalImpls {
                 }
             }
 
-            impl<$tcx> $crate::ty::visit::TypeVisitable<$crate::ty::TyCtxt<$tcx>> for $ty {
+            impl<'tcx> $crate::ty::visit::TypeVisitable<$crate::ty::TyCtxt<'tcx>> for $ty {
                 #[inline]
-                fn visit_with<F: $crate::ty::visit::TypeVisitor<$crate::ty::TyCtxt<$tcx>>>(
+                fn visit_with<F: $crate::ty::visit::TypeVisitor<$crate::ty::TyCtxt<'tcx>>>(
                     &self,
                     _: &mut F)
                     -> ::std::ops::ControlFlow<F::BreakTy>
@@ -98,14 +90,6 @@ macro_rules! TrivialTypeTraversalImpls {
             }
         )+
     };
-
-    ($($ty:ty,)+) => {
-        TrivialTypeTraversalImpls! {
-            for<'tcx> {
-                $($ty,)+
-            }
-        }
-    };
 }
 
 #[macro_export]
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs
index dcb56a1755e..d4dd56a42c1 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs
@@ -5,7 +5,9 @@ use std::hash;
 use std::iter;
 use std::ops::Range;
 
+use rustc_serialize::{Decodable, Encodable};
 use rustc_target::abi::Size;
+use rustc_type_ir::{TyDecoder, TyEncoder};
 
 use super::AllocRange;
 
@@ -182,11 +184,39 @@ impl InitMask {
 /// The actual materialized blocks of the bitmask, when we can't keep the `InitMask` lazy.
 // Note: for performance reasons when interning, some of the fields can be partially
 // hashed. (see the `Hash` impl below for more details), so the impl is not derived.
-#[derive(Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, HashStable)]
+#[derive(Clone, Debug, Eq, PartialEq, HashStable)]
 struct InitMaskMaterialized {
     blocks: Vec<Block>,
 }
 
+// `Block` is a `u64`, but it is a bitmask not a numeric value. If we were to just derive
+// Encodable and Decodable we would apply varint encoding to the bitmasks, which is slower
+// and also produces more output when the high bits of each `u64` are occupied.
+// Note: There is probably a remaining optimization for masks that do not use an entire
+// `Block`.
+impl<E: TyEncoder> Encodable<E> for InitMaskMaterialized {
+    fn encode(&self, encoder: &mut E) {
+        encoder.emit_usize(self.blocks.len());
+        for block in &self.blocks {
+            encoder.emit_raw_bytes(&block.to_le_bytes());
+        }
+    }
+}
+
+// This implementation is deliberately not derived, see the matching `Encodable` impl.
+impl<D: TyDecoder> Decodable<D> for InitMaskMaterialized {
+    fn decode(decoder: &mut D) -> Self {
+        let num_blocks = decoder.read_usize();
+        let mut blocks = Vec::with_capacity(num_blocks);
+        for _ in 0..num_blocks {
+            let bytes = decoder.read_raw_bytes(8);
+            let block = u64::from_le_bytes(bytes.try_into().unwrap());
+            blocks.push(block);
+        }
+        InitMaskMaterialized { blocks }
+    }
+}
+
 // Const allocations are only hashed for interning. However, they can be large, making the hashing
 // expensive especially since it uses `FxHash`: it's better suited to short keys, not potentially
 // big buffers like the allocation's init mask. We can partially hash some fields when they're
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 2ea8602af12..f985aae9a22 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -714,9 +714,7 @@ pub enum BindingForm<'tcx> {
 }
 
 TrivialTypeTraversalAndLiftImpls! {
-    for<'tcx> {
-        BindingForm<'tcx>,
-    }
+    BindingForm<'tcx>,
 }
 
 mod binding_form_impl {
diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs
index 9881583214e..ace856b9f95 100644
--- a/compiler/rustc_middle/src/mir/type_foldable.rs
+++ b/compiler/rustc_middle/src/mir/type_foldable.rs
@@ -25,9 +25,7 @@ TrivialTypeTraversalAndLiftImpls! {
 }
 
 TrivialTypeTraversalImpls! {
-    for <'tcx> {
-        ConstValue<'tcx>,
-    }
+    ConstValue<'tcx>,
 }
 
 impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [InlineAsmTemplatePiece] {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 7a5a1603585..6fc9190b090 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1094,7 +1094,6 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
     ) -> Option<mir::DestructuredConstant<'tcx>> {
         desc { "destructuring MIR constant"}
-        remap_env_constness
     }
 
     /// Dereference a constant reference or raw pointer and turn the result into a constant
@@ -1103,7 +1102,6 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
     ) -> mir::ConstantKind<'tcx> {
         desc { "dereferencing MIR constant" }
-        remap_env_constness
     }
 
     query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> {
@@ -1346,32 +1344,26 @@ rustc_queries! {
     /// `ty.is_copy()`, etc, since that will prune the environment where possible.
     query is_copy_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "computing whether `{}` is `Copy`", env.value }
-        remap_env_constness
     }
     /// Query backing `Ty::is_sized`.
     query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "computing whether `{}` is `Sized`", env.value }
-        remap_env_constness
     }
     /// Query backing `Ty::is_freeze`.
     query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "computing whether `{}` is freeze", env.value }
-        remap_env_constness
     }
     /// Query backing `Ty::is_unpin`.
     query is_unpin_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "computing whether `{}` is `Unpin`", env.value }
-        remap_env_constness
     }
     /// Query backing `Ty::needs_drop`.
     query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "computing whether `{}` needs drop", env.value }
-        remap_env_constness
     }
     /// Query backing `Ty::has_significant_drop_raw`.
     query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
         desc { "computing whether `{}` has a significant drop", env.value }
-        remap_env_constness
     }
 
     /// Query backing `Ty::is_structural_eq_shallow`.
@@ -1411,7 +1403,6 @@ rustc_queries! {
     ) -> Result<ty::layout::TyAndLayout<'tcx>, ty::layout::LayoutError<'tcx>> {
         depth_limit
         desc { "computing layout of `{}`", key.value }
-        remap_env_constness
     }
 
     /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
@@ -1422,7 +1413,6 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
     ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> {
         desc { "computing call ABI of `{}` function pointers", key.value.0 }
-        remap_env_constness
     }
 
     /// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for
@@ -1434,7 +1424,6 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
     ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> {
         desc { "computing call ABI of `{}`", key.value.0 }
-        remap_env_constness
     }
 
     query dylib_dependency_formats(_: CrateNum)
@@ -1937,7 +1926,6 @@ rustc_queries! {
         NoSolution,
     > {
         desc { "normalizing `{}`", goal.value.value }
-        remap_env_constness
     }
 
     /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead.
@@ -1945,7 +1933,6 @@ rustc_queries! {
         goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>
     ) -> Result<GenericArg<'tcx>, NoSolution> {
         desc { "normalizing `{}`", goal.value }
-        remap_env_constness
     }
 
     query implied_outlives_bounds(
@@ -1955,7 +1942,6 @@ rustc_queries! {
         NoSolution,
     > {
         desc { "computing implied outlives bounds for `{}`", goal.value.value }
-        remap_env_constness
     }
 
     /// Do not call this query directly:
@@ -1967,7 +1953,6 @@ rustc_queries! {
         NoSolution,
     > {
         desc { "computing dropck types for `{}`", goal.value.value }
-        remap_env_constness
     }
 
     /// Do not call this query directly: invoke `infcx.predicate_may_hold()` or
@@ -1995,7 +1980,6 @@ rustc_queries! {
         NoSolution,
     > {
         desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal.value.value }
-        remap_env_constness
     }
 
     /// Do not call this query directly: part of the `Eq` type-op
@@ -2006,7 +1990,6 @@ rustc_queries! {
         NoSolution,
     > {
         desc { "evaluating `type_op_eq` `{:?}`", goal.value.value }
-        remap_env_constness
     }
 
     /// Do not call this query directly: part of the `Subtype` type-op
@@ -2017,7 +2000,6 @@ rustc_queries! {
         NoSolution,
     > {
         desc { "evaluating `type_op_subtype` `{:?}`", goal.value.value }
-        remap_env_constness
     }
 
     /// Do not call this query directly: part of the `ProvePredicate` type-op
@@ -2038,7 +2020,6 @@ rustc_queries! {
         NoSolution,
     > {
         desc { "normalizing `{}`", goal.value.value.value }
-        remap_env_constness
     }
 
     /// Do not call this query directly: part of the `Normalize` type-op
@@ -2049,7 +2030,6 @@ rustc_queries! {
         NoSolution,
     > {
         desc { "normalizing `{:?}`", goal.value.value.value }
-        remap_env_constness
     }
 
     /// Do not call this query directly: part of the `Normalize` type-op
@@ -2060,7 +2040,6 @@ rustc_queries! {
         NoSolution,
     > {
         desc { "normalizing `{:?}`", goal.value.value.value }
-        remap_env_constness
     }
 
     /// Do not call this query directly: part of the `Normalize` type-op
@@ -2071,7 +2050,6 @@ rustc_queries! {
         NoSolution,
     > {
         desc { "normalizing `{:?}`", goal.value.value.value }
-        remap_env_constness
     }
 
     query subst_and_check_impossible_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool {
@@ -2093,7 +2071,6 @@ rustc_queries! {
         goal: CanonicalTyGoal<'tcx>
     ) -> MethodAutoderefStepsResult<'tcx> {
         desc { "computing autoderef types for `{}`", goal.value.value }
-        remap_env_constness
     }
 
     query supported_target_features(_: CrateNum) -> &'tcx FxHashMap<String, Option<Symbol>> {
@@ -2138,7 +2115,6 @@ rustc_queries! {
         key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>
     ) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> {
         desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
-        remap_env_constness
     }
 
     query resolve_instance_of_const_arg(
@@ -2148,7 +2124,6 @@ rustc_queries! {
             "resolving instance of the const argument `{}`",
             ty::Instance::new(key.value.0.to_def_id(), key.value.2),
         }
-        remap_env_constness
     }
 
     query reveal_opaque_types_in_bounds(key: &'tcx ty::List<ty::Predicate<'tcx>>) -> &'tcx ty::List<ty::Predicate<'tcx>> {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 63f7cc2ee73..e5356581e6e 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1329,9 +1329,12 @@ nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariable
 // This is the impl for `&'a InternalSubsts<'a>`.
 nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
 
-CloneLiftImpls! { for<'tcx> {
-    Constness, traits::WellFormedLoc, ImplPolarity, crate::mir::ReturnConstraint,
-} }
+CloneLiftImpls! {
+    Constness,
+    traits::WellFormedLoc,
+    ImplPolarity,
+    crate::mir::ReturnConstraint,
+}
 
 macro_rules! sty_debug_print {
     ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index 203e16bea27..25890eb15cd 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -37,7 +37,8 @@ where
     }
 
     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        let r = r.super_fold_with(self);
+        // This one is a little different, because `super_fold_with` is not
+        // implemented on non-recursive `Region`.
         (self.lt_op)(r)
     }
 
diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs
index 79365ef281b..30f036e471c 100644
--- a/compiler/rustc_middle/src/ty/list.rs
+++ b/compiler/rustc_middle/src/ty/list.rs
@@ -1,4 +1,5 @@
 use crate::arena::Arena;
+use rustc_data_structures::aligned::{align_of, Aligned};
 use rustc_serialize::{Encodable, Encoder};
 use std::alloc::Layout;
 use std::cmp::Ordering;
@@ -198,22 +199,17 @@ impl<'a, T: Copy> IntoIterator for &'a List<T> {
 
 unsafe impl<T: Sync> Sync for List<T> {}
 
-unsafe impl<'a, T: 'a> rustc_data_structures::tagged_ptr::Pointer for &'a List<T> {
-    const BITS: usize = std::mem::align_of::<usize>().trailing_zeros() as usize;
-
-    #[inline]
-    fn into_usize(self) -> usize {
-        self as *const List<T> as usize
-    }
-
-    #[inline]
-    unsafe fn from_usize(ptr: usize) -> &'a List<T> {
-        &*(ptr as *const List<T>)
-    }
+// Safety:
+// Layouts of `Equivalent<T>` and `List<T>` are the same, modulo opaque tail,
+// thus aligns of `Equivalent<T>` and `List<T>` must be the same.
+unsafe impl<T> Aligned for List<T> {
+    const ALIGN: ptr::Alignment = {
+        #[repr(C)]
+        struct Equivalent<T> {
+            _len: usize,
+            _data: [T; 0],
+        }
 
-    unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R {
-        // `Self` is `&'a List<T>` which impls `Copy`, so this is fine.
-        let ptr = Self::from_usize(ptr);
-        f(&ptr)
-    }
+        align_of::<Equivalent<T>>()
+    };
 }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 2e516f291bc..1061c320793 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1627,7 +1627,8 @@ struct ParamTag {
 }
 
 unsafe impl rustc_data_structures::tagged_ptr::Tag for ParamTag {
-    const BITS: usize = 2;
+    const BITS: u32 = 2;
+
     #[inline]
     fn into_usize(self) -> usize {
         match self {
@@ -1637,6 +1638,7 @@ unsafe impl rustc_data_structures::tagged_ptr::Tag for ParamTag {
             Self { reveal: traits::Reveal::All, constness: hir::Constness::Const } => 3,
         }
     }
+
     #[inline]
     unsafe fn from_usize(ptr: usize) -> Self {
         match ptr {
@@ -1850,12 +1852,6 @@ impl<'tcx, T> ParamEnvAnd<'tcx, T> {
     pub fn into_parts(self) -> (ParamEnv<'tcx>, T) {
         (self.param_env, self.value)
     }
-
-    #[inline]
-    pub fn without_const(mut self) -> Self {
-        self.param_env = self.param_env.without_const();
-        self
-    }
 }
 
 #[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
@@ -1969,6 +1965,16 @@ impl VariantDef {
     pub fn ctor_def_id(&self) -> Option<DefId> {
         self.ctor.map(|(_, def_id)| def_id)
     }
+
+    /// Returns the one field in this variant.
+    ///
+    /// `panic!`s if there are no fields or multiple fields.
+    #[inline]
+    pub fn single_field(&self) -> &FieldDef {
+        assert!(self.fields.len() == 1);
+
+        &self.fields[FieldIdx::from_u32(0)]
+    }
 }
 
 impl PartialEq for VariantDef {
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 72caadaf661..af76cf7cc4e 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2518,7 +2518,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                     self.used_region_names.insert(name);
                 }
 
-                r.super_visit_with(self)
+                ControlFlow::Continue(())
             }
 
             // We collect types in order to prevent really large types from compiling for
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index fa9fea72344..97592cbc567 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -202,16 +202,6 @@ macro_rules! separate_provide_extern_default {
     };
 }
 
-macro_rules! opt_remap_env_constness {
-    ([][$name:ident]) => {};
-    ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
-        let $name = $name.without_const();
-    };
-    ([$other:tt $($modifiers:tt)*][$name:ident]) => {
-        opt_remap_env_constness!([$($modifiers)*][$name])
-    };
-}
-
 macro_rules! define_callbacks {
     (
      $($(#[$attr:meta])*
@@ -353,7 +343,6 @@ macro_rules! define_callbacks {
             #[inline(always)]
             pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
                 let key = key.into_query_param();
-                opt_remap_env_constness!([$($modifiers)*][key]);
 
                 match try_get_cached(self.tcx, &self.tcx.query_system.caches.$name, &key) {
                     Some(_) => return,
@@ -372,7 +361,6 @@ macro_rules! define_callbacks {
             #[inline(always)]
             pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
                 let key = key.into_query_param();
-                opt_remap_env_constness!([$($modifiers)*][key]);
 
                 match try_get_cached(self.tcx, &self.tcx.query_system.caches.$name, &key) {
                     Some(_) => return,
@@ -402,7 +390,6 @@ macro_rules! define_callbacks {
             pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V
             {
                 let key = key.into_query_param();
-                opt_remap_env_constness!([$($modifiers)*][key]);
 
                 restore::<$V>(match try_get_cached(self.tcx, &self.tcx.query_system.caches.$name, &key) {
                     Some(value) => value,
@@ -492,7 +479,6 @@ macro_rules! define_feedable {
             #[inline(always)]
             pub fn $name(self, value: query_provided::$name<'tcx>) -> $V {
                 let key = self.key().into_query_param();
-                opt_remap_env_constness!([$($modifiers)*][key]);
 
                 let tcx = self.tcx;
                 let erased = query_provided_to_value::$name(tcx, value);
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 5c604bb6db2..7706fdddeb8 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -276,9 +276,7 @@ TrivialTypeTraversalAndLiftImpls! {
 }
 
 TrivialTypeTraversalAndLiftImpls! {
-    for<'tcx> {
-        ty::ValTree<'tcx>,
-    }
+    ty::ValTree<'tcx>,
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -583,24 +581,6 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> {
     }
 }
 
-impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> {
-    fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
-        self,
-        _folder: &mut F,
-    ) -> Result<Self, F::Error> {
-        Ok(self)
-    }
-}
-
-impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> {
-    fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(
-        &self,
-        _visitor: &mut V,
-    ) -> ControlFlow<V::BreakTy> {
-        ControlFlow::Continue(())
-    }
-}
-
 impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
     fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
         self,
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs
index 08a62c900f9..24a1f04c7e3 100644
--- a/compiler/rustc_middle/src/ty/visit.rs
+++ b/compiler/rustc_middle/src/ty/visit.rs
@@ -364,7 +364,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> {
             _ => (),
         };
 
-        r.super_visit_with(self)
+        ControlFlow::Continue(())
     }
 }
 
diff --git a/compiler/rustc_const_eval/src/util/call_kind.rs b/compiler/rustc_middle/src/util/call_kind.rs
index 995363c0edd..627c84c388c 100644
--- a/compiler/rustc_const_eval/src/util/call_kind.rs
+++ b/compiler/rustc_middle/src/util/call_kind.rs
@@ -2,10 +2,10 @@
 //! as well as errors when attempting to call a non-const function in a const
 //! context.
 
+use crate::ty::subst::SubstsRef;
+use crate::ty::{AssocItemContainer, Instance, ParamEnv, Ty, TyCtxt};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{lang_items, LangItem};
-use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{AssocItemContainer, Instance, ParamEnv, Ty, TyCtxt};
 use rustc_span::symbol::Ident;
 use rustc_span::{sym, DesugaringKind, Span};
 
diff --git a/compiler/rustc_const_eval/src/util/find_self_call.rs b/compiler/rustc_middle/src/util/find_self_call.rs
index 33ad128eeeb..0eab0adf07e 100644
--- a/compiler/rustc_const_eval/src/util/find_self_call.rs
+++ b/compiler/rustc_middle/src/util/find_self_call.rs
@@ -1,6 +1,6 @@
-use rustc_middle::mir::*;
-use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, TyCtxt};
+use crate::mir::*;
+use crate::ty::subst::SubstsRef;
+use crate::ty::{self, TyCtxt};
 use rustc_span::def_id::DefId;
 
 /// Checks if the specified `local` is used as the `self` parameter of a method call
diff --git a/compiler/rustc_middle/src/util/mod.rs b/compiler/rustc_middle/src/util/mod.rs
new file mode 100644
index 00000000000..53b4257899b
--- /dev/null
+++ b/compiler/rustc_middle/src/util/mod.rs
@@ -0,0 +1,7 @@
+pub mod bug;
+pub mod call_kind;
+pub mod common;
+pub mod find_self_call;
+
+pub use call_kind::{call_kind, CallDesugaringKind, CallKind};
+pub use find_self_call::find_self_call;
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 43e787db41a..dcdeaf008d6 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -384,13 +384,8 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
             diag.span_note(span, fluent::mir_build_def_note);
         }
 
-        let is_variant_list_non_exhaustive = match self.ty.kind() {
-            ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local() => {
-                true
-            }
-            _ => false,
-        };
-
+        let is_variant_list_non_exhaustive = matches!(self.ty.kind(),
+            ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local());
         if is_variant_list_non_exhaustive {
             diag.note(fluent::mir_build_non_exhaustive_type_note);
         } else {
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 bac46db2b1e..0ef48c42f87 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -671,10 +671,8 @@ fn non_exhaustive_match<'p, 'tcx>(
         };
     };
 
-    let is_variant_list_non_exhaustive = match scrut_ty.kind() {
-        ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local() => true,
-        _ => false,
-    };
+    let is_variant_list_non_exhaustive = matches!(scrut_ty.kind(),
+        ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local());
 
     adt_defined_here(cx, &mut err, scrut_ty, &witnesses);
     err.note(&format!(
diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
index 3d32c586554..57b24c9c552 100644
--- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
+++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
@@ -134,7 +134,12 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> {
                 // the `self` parameter of a method call (as the terminator of our current
                 // BasicBlock). If so, we emit a more specific lint.
                 let method_did = self.target_local.and_then(|target_local| {
-                    crate::util::find_self_call(self.tcx, &self.body, target_local, loc.block)
+                    rustc_middle::util::find_self_call(
+                        self.tcx,
+                        &self.body,
+                        target_local,
+                        loc.block,
+                    )
                 });
                 let lint_loc =
                     if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc };
diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index 699fe44892b..3a105a2abae 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -493,7 +493,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         cond: &Operand<'tcx>,
         location: Location,
     ) -> Option<!> {
-        let ref value = self.eval_operand(&cond, location)?;
+        let value = &self.eval_operand(&cond, location)?;
         trace!("assertion on {:?} should be {:?}", value, expected);
 
         let expected = Scalar::from_bool(expected);
diff --git a/compiler/rustc_mir_transform/src/coverage/debug.rs b/compiler/rustc_mir_transform/src/coverage/debug.rs
index 725883b83fa..e554c470646 100644
--- a/compiler/rustc_mir_transform/src/coverage/debug.rs
+++ b/compiler/rustc_mir_transform/src/coverage/debug.rs
@@ -292,10 +292,8 @@ impl DebugCounters {
     }
 
     pub fn some_block_label(&self, operand: ExpressionOperandId) -> Option<&String> {
-        self.some_counters.as_ref().map_or(None, |counters| {
-            counters
-                .get(&operand)
-                .map_or(None, |debug_counter| debug_counter.some_block_label.as_ref())
+        self.some_counters.as_ref().and_then(|counters| {
+            counters.get(&operand).and_then(|debug_counter| debug_counter.some_block_label.as_ref())
         })
     }
 
diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
index e5c3fa5646a..8ee08c5be34 100644
--- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
+++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
@@ -9,7 +9,7 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::{Body, Local, Location, Operand, Terminator, TerminatorKind, RETURN_PLACE};
-use rustc_middle::ty::{self, DeducedParamAttrs, ParamEnv, Ty, TyCtxt};
+use rustc_middle::ty::{self, DeducedParamAttrs, Ty, TyCtxt};
 use rustc_session::config::OptLevel;
 
 /// A visitor that determines which arguments have been mutated. We can't use the mutability field
@@ -198,11 +198,12 @@ pub fn deduced_param_attrs<'tcx>(
     // see [1].
     //
     // [1]: https://github.com/rust-lang/rust/pull/103172#discussion_r999139997
+    let param_env = tcx.param_env_reveal_all_normalized(def_id);
     let mut deduced_param_attrs = tcx.arena.alloc_from_iter(
         body.local_decls.iter().skip(1).take(body.arg_count).enumerate().map(
             |(arg_index, local_decl)| DeducedParamAttrs {
                 read_only: !deduce_read_only.mutable_args.contains(arg_index)
-                    && local_decl.ty.is_freeze(tcx, ParamEnv::reveal_all()),
+                    && local_decl.ty.is_freeze(tcx, param_env),
             },
         ),
     );
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index f0cb317f449..1525933aee3 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -350,14 +350,8 @@ impl<'tcx> Inliner<'tcx> {
         callsite: &CallSite<'tcx>,
         callee_attrs: &CodegenFnAttrs,
     ) -> Result<(), &'static str> {
-        match callee_attrs.inline {
-            InlineAttr::Never => return Err("never inline hint"),
-            InlineAttr::Always | InlineAttr::Hint => {}
-            InlineAttr::None => {
-                if self.tcx.sess.mir_opt_level() <= 2 {
-                    return Err("at mir-opt-level=2, only #[inline] is inlined");
-                }
-            }
+        if let InlineAttr::Never = callee_attrs.inline {
+            return Err("never inline hint");
         }
 
         // Only inline local functions if they would be eligible for cross-crate
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index e3e7c63e344..e1db19557cf 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -45,10 +45,10 @@ impl<'a> Parser<'a> {
                     Some(InnerAttrForbiddenReason::AfterOuterDocComment {
                         prev_doc_comment_span: prev_outer_attr_sp.unwrap(),
                     })
-                } else if let Some(prev_outer_attr_sp) = prev_outer_attr_sp {
-                    Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp })
                 } else {
-                    None
+                    prev_outer_attr_sp.map(|prev_outer_attr_sp| {
+                        InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp }
+                    })
                 };
                 let inner_parse_policy = InnerAttrPolicy::Forbidden(inner_error_reason);
                 just_parsed_doc_comment = false;
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 6422b8ac1ba..f5fef6ad019 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2577,14 +2577,12 @@ impl<'a> Parser<'a> {
     }
 
     fn recover_self_param(&mut self) -> bool {
-        match self
-            .parse_outer_attributes()
-            .and_then(|_| self.parse_self_param())
-            .map_err(|e| e.cancel())
-        {
-            Ok(Some(_)) => true,
-            _ => false,
-        }
+        matches!(
+            self.parse_outer_attributes()
+                .and_then(|_| self.parse_self_param())
+                .map_err(|e| e.cancel()),
+            Ok(Some(_))
+        )
     }
 }
 
diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index 7a4d53ed8bb..adb0d372a40 100644
--- a/compiler/rustc_parse/src/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -20,12 +20,10 @@ impl<'a> Parser<'a> {
     pub fn nonterminal_may_begin_with(kind: NonterminalKind, token: &Token) -> bool {
         /// Checks whether the non-terminal may contain a single (non-keyword) identifier.
         fn may_be_ident(nt: &token::Nonterminal) -> bool {
-            match *nt {
-                token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) | token::NtLifetime(_) => {
-                    false
-                }
-                _ => true,
-            }
+            !matches!(
+                *nt,
+                token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) | token::NtLifetime(_)
+            )
         }
 
         match kind {
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index b354dca7cc4..055682a1509 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -627,9 +627,9 @@ passes_attr_application_struct_enum_union =
     attribute should be applied to a struct, enum, or union
     .label = not a struct, enum, or union
 
-passes_attr_application_struct_enum_function_union =
-    attribute should be applied to a struct, enum, function, or union
-    .label = not a struct, enum, function, or union
+passes_attr_application_struct_enum_function_method_union =
+    attribute should be applied to a struct, enum, function, associated function, or union
+    .label = not a struct, enum, function, associated function, or union
 
 passes_transparent_incompatible =
     transparent {$target} cannot have other repr hints
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 80a93da2b45..085a28626ea 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1728,7 +1728,9 @@ impl CheckAttrVisitor<'_> {
                     }
                 }
                 sym::align => {
-                    if let (Target::Fn, false) = (target, self.tcx.features().fn_align) {
+                    if let (Target::Fn | Target::Method(MethodKind::Inherent), false) =
+                        (target, self.tcx.features().fn_align)
+                    {
                         feature_err(
                             &self.tcx.sess.parse_sess,
                             sym::fn_align,
@@ -1739,10 +1741,14 @@ impl CheckAttrVisitor<'_> {
                     }
 
                     match target {
-                        Target::Struct | Target::Union | Target::Enum | Target::Fn => continue,
+                        Target::Struct
+                        | Target::Union
+                        | Target::Enum
+                        | Target::Fn
+                        | Target::Method(_) => continue,
                         _ => {
                             self.tcx.sess.emit_err(
-                                errors::AttrApplication::StructEnumFunctionUnion {
+                                errors::AttrApplication::StructEnumFunctionMethodUnion {
                                     hint_span: hint.span(),
                                     span,
                                 },
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 139ba8c9677..e8603b3a2f1 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1355,8 +1355,8 @@ pub enum AttrApplication {
         #[label]
         span: Span,
     },
-    #[diag(passes_attr_application_struct_enum_function_union, code = "E0517")]
-    StructEnumFunctionUnion {
+    #[diag(passes_attr_application_struct_enum_function_method_union, code = "E0517")]
+    StructEnumFunctionMethodUnion {
         #[primary_span]
         hint_span: Span,
         #[label]
diff --git a/compiler/rustc_query_system/src/dep_graph/query.rs b/compiler/rustc_query_system/src/dep_graph/query.rs
index 27b3b5e1366..9dcc41e2726 100644
--- a/compiler/rustc_query_system/src/dep_graph/query.rs
+++ b/compiler/rustc_query_system/src/dep_graph/query.rs
@@ -24,10 +24,7 @@ impl<K: DepKind> DepGraphQuery<K> {
 
     pub fn push(&mut self, index: DepNodeIndex, node: DepNode<K>, edges: &[DepNodeIndex]) {
         let source = self.graph.add_node(node);
-        if index.index() >= self.dep_index_to_index.len() {
-            self.dep_index_to_index.resize(index.index() + 1, None);
-        }
-        self.dep_index_to_index[index] = Some(source);
+        self.dep_index_to_index.insert(index, source);
         self.indices.insert(node, source);
 
         for &target in edges.iter() {
diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs
index 0bc811eb044..8865ecf3e05 100644
--- a/compiler/rustc_query_system/src/ich/impls_syntax.rs
+++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs
@@ -75,7 +75,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
             ref normalized_pos,
         } = *self;
 
-        (name_hash as u64).hash_stable(hcx, hasher);
+        name_hash.hash_stable(hcx, hasher);
 
         src_hash.hash_stable(hcx, hasher);
 
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 0c9d306081e..4b7048eac04 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -663,15 +663,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         Ident::with_dummy_span(name),
                         Namespace::ValueNS,
                         &parent_scope,
-                        &|res: Res| match res {
-                            Res::Def(
-                                DefKind::Ctor(CtorOf::Variant, CtorKind::Const)
-                                | DefKind::Ctor(CtorOf::Struct, CtorKind::Const)
-                                | DefKind::Const
-                                | DefKind::AssocConst,
-                                _,
-                            ) => true,
-                            _ => false,
+                        &|res: Res| {
+                            matches!(
+                                res,
+                                Res::Def(
+                                    DefKind::Ctor(CtorOf::Variant, CtorKind::Const)
+                                        | DefKind::Ctor(CtorOf::Struct, CtorKind::Const)
+                                        | DefKind::Const
+                                        | DefKind::AssocConst,
+                                    _,
+                                )
+                            )
                         },
                     );
 
@@ -1867,15 +1869,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 Some(LexicalScopeBinding::Item(name_binding)) => Some(name_binding.span),
                 _ => None,
             };
-            let suggestion = if let Some(span) = match_span {
-                Some((
+            let suggestion = match_span.map(|span| {
+                (
                     vec![(span, String::from(""))],
                     format!("`{}` is defined here, but is not a type", ident),
                     Applicability::MaybeIncorrect,
-                ))
-            } else {
-                None
-            };
+                )
+            });
 
             (format!("use of undeclared type `{}`", ident), suggestion)
         } else {
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index aa8859ed1a3..911d6902c98 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -1663,10 +1663,11 @@ impl SourceFile {
 
         if let Some(ref src) = self.src {
             Some(Cow::from(get_until_newline(src, begin)))
-        } else if let Some(src) = self.external_src.borrow().get_source() {
-            Some(Cow::Owned(String::from(get_until_newline(src, begin))))
         } else {
-            None
+            self.external_src
+                .borrow()
+                .get_source()
+                .map(|src| Cow::Owned(String::from(get_until_newline(src, begin))))
         }
     }
 
@@ -2159,9 +2160,7 @@ where
         };
 
         Hash::hash(&TAG_VALID_SPAN, hasher);
-        // We truncate the stable ID hash and line and column numbers. The chances
-        // of causing a collision this way should be minimal.
-        Hash::hash(&(file.name_hash as u64), hasher);
+        Hash::hash(&file.name_hash, hasher);
 
         // Hash both the length and the end location (line/column) of a span. If we
         // hash only the length, for example, then two otherwise equal spans with
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 88e3674f899..29a7e74a816 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -906,10 +906,8 @@ impl SourceMap {
 
             let snippet = if let Some(ref src) = local_begin.sf.src {
                 Some(&src[start_index..])
-            } else if let Some(src) = src.get_source() {
-                Some(&src[start_index..])
             } else {
-                None
+                src.get_source().map(|src| &src[start_index..])
             };
 
             match snippet {
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index c29b5b04e00..bb574954587 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -649,7 +649,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         // FIXME(transmutability): This really should be returning nested goals for `Answer::If*`
         match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
             ObligationCause::dummy(),
-            ty::Binder::dummy(src_and_dst),
+            src_and_dst,
             scope,
             assume,
         ) {
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 ada868705c7..dfdd52720a0 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -11,12 +11,13 @@
 use super::{CanonicalGoal, Certainty, EvalCtxt, Goal};
 use crate::solve::canonicalize::{CanonicalizeMode, Canonicalizer};
 use crate::solve::{CanonicalResponse, QueryResult, Response};
+use rustc_index::vec::IndexVec;
 use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
 use rustc_infer::infer::canonical::CanonicalVarValues;
 use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{ExternalConstraints, ExternalConstraintsData};
-use rustc_middle::ty::{self, GenericArgKind};
+use rustc_middle::ty::{self, BoundVar, GenericArgKind};
 use rustc_span::DUMMY_SP;
 use std::iter;
 use std::ops::Deref;
@@ -139,25 +140,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         //
         // We therefore instantiate the existential variable in the canonical response with the
         // inference variable of the input right away, which is more performant.
-        let mut opt_values = vec![None; response.variables.len()];
+        let mut opt_values = IndexVec::from_elem_n(None, response.variables.len());
         for (original_value, result_value) in iter::zip(original_values, var_values.var_values) {
             match result_value.unpack() {
                 GenericArgKind::Type(t) => {
                     if let &ty::Bound(debruijn, b) = t.kind() {
                         assert_eq!(debruijn, ty::INNERMOST);
-                        opt_values[b.var.index()] = Some(*original_value);
+                        opt_values[b.var] = Some(*original_value);
                     }
                 }
                 GenericArgKind::Lifetime(r) => {
                     if let ty::ReLateBound(debruijn, br) = *r {
                         assert_eq!(debruijn, ty::INNERMOST);
-                        opt_values[br.var.index()] = Some(*original_value);
+                        opt_values[br.var] = Some(*original_value);
                     }
                 }
                 GenericArgKind::Const(c) => {
                     if let ty::ConstKind::Bound(debrujin, b) = c.kind() {
                         assert_eq!(debrujin, ty::INNERMOST);
-                        opt_values[b.index()] = Some(*original_value);
+                        opt_values[b] = Some(*original_value);
                     }
                 }
             }
@@ -180,7 +181,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                     // more placeholders then they should be able to. However the inference variables have
                     // to "come from somewhere", so by equating them with the original values of the caller
                     // later on, we pull them down into their correct universe again.
-                    if let Some(v) = opt_values[index] {
+                    if let Some(v) = opt_values[BoundVar::from_usize(index)] {
                         v
                     } else {
                         self.infcx.instantiate_canonical_var(DUMMY_SP, info, |_| prev_universe)
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 cef982fcb41..0352f0f380d 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -742,7 +742,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         {
                             // Recompute the safe transmute reason and use that for the error reporting
                             self.get_safe_transmute_error_and_reason(
-                                trait_predicate,
                                 obligation.clone(),
                                 trait_ref,
                                 span,
@@ -1629,7 +1628,6 @@ trait InferCtxtPrivExt<'tcx> {
 
     fn get_safe_transmute_error_and_reason(
         &self,
-        trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
         obligation: Obligation<'tcx, ty::Predicate<'tcx>>,
         trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
         span: Span,
@@ -2921,18 +2919,20 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
     fn get_safe_transmute_error_and_reason(
         &self,
-        trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
         obligation: Obligation<'tcx, ty::Predicate<'tcx>>,
         trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
         span: Span,
     ) -> (String, Option<String>) {
-        let src_and_dst = trait_predicate.map_bound(|p| rustc_transmute::Types {
-            dst: p.trait_ref.substs.type_at(0),
-            src: p.trait_ref.substs.type_at(1),
-        });
-        let scope = trait_ref.skip_binder().substs.type_at(2);
+        // Erase regions because layout code doesn't particularly care about regions.
+        let trait_ref = self.tcx.erase_regions(self.tcx.erase_late_bound_regions(trait_ref));
+
+        let src_and_dst = rustc_transmute::Types {
+            dst: trait_ref.substs.type_at(0),
+            src: trait_ref.substs.type_at(1),
+        };
+        let scope = trait_ref.substs.type_at(2);
         let Some(assume) =
-            rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, trait_ref.skip_binder().substs.const_at(3)) else {
+            rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, trait_ref.substs.const_at(3)) else {
                 span_bug!(span, "Unable to construct rustc_transmute::Assume where it was previously possible");
             };
         match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
@@ -2942,8 +2942,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             assume,
         ) {
             rustc_transmute::Answer::No(reason) => {
-                let dst = trait_ref.skip_binder().substs.type_at(0);
-                let src = trait_ref.skip_binder().substs.type_at(1);
+                let dst = trait_ref.substs.type_at(0);
+                let src = trait_ref.substs.type_at(1);
                 let custom_err_msg = format!(
                     "`{src}` cannot be safely transmuted into `{dst}` in the defining scope of `{scope}`"
                 );
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 8a203dec86b..ed82b9c0152 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -450,7 +450,7 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI
             {
                 return ControlFlow::Break(());
             }
-            r.super_visit_with(self)
+            ControlFlow::Continue(())
         }
         fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
             if let ty::ConstKind::Param(param) = ct.kind()
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
index b63da28e274..baa2fbb6751 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
@@ -32,14 +32,8 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
 
     fn perform_query(
         tcx: TyCtxt<'tcx>,
-        mut canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>,
+        canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>,
     ) -> Fallible<CanonicalQueryResponse<'tcx, ()>> {
-        match canonicalized.value.value.predicate.kind().skip_binder() {
-            ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => {
-                canonicalized.value.param_env.remap_constness_with(pred.constness);
-            }
-            _ => canonicalized.value.param_env = canonicalized.value.param_env.without_const(),
-        }
         tcx.type_op_prove_predicate(canonicalized)
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 5e60bc01bb6..3bba11262f5 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -275,33 +275,35 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ) -> Result<ImplSourceBuiltinData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
         debug!(?obligation, "confirm_transmutability_candidate");
 
-        let predicate = obligation.predicate;
-
-        let type_at = |i| predicate.map_bound(|p| p.trait_ref.substs.type_at(i));
-        let const_at = |i| predicate.skip_binder().trait_ref.substs.const_at(i);
-
-        let src_and_dst = predicate.map_bound(|p| rustc_transmute::Types {
-            dst: p.trait_ref.substs.type_at(0),
-            src: p.trait_ref.substs.type_at(1),
-        });
-
-        let scope = type_at(2).skip_binder();
-
-        let Some(assume) =
-            rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, const_at(3)) else {
-                return Err(Unimplemented);
-            };
-
-        let cause = obligation.cause.clone();
+        // We erase regions here because transmutability calls layout queries,
+        // which does not handle inference regions and doesn't particularly
+        // care about other regions. Erasing late-bound regions is equivalent
+        // to instantiating the binder with placeholders then erasing those
+        // placeholder regions.
+        let predicate =
+            self.tcx().erase_regions(self.tcx().erase_late_bound_regions(obligation.predicate));
+
+        let Some(assume) = rustc_transmute::Assume::from_const(
+            self.infcx.tcx,
+            obligation.param_env,
+            predicate.trait_ref.substs.const_at(3)
+        ) else {
+            return Err(Unimplemented);
+        };
 
         let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx);
-
-        let maybe_transmutable = transmute_env.is_transmutable(cause, src_and_dst, scope, assume);
-
-        use rustc_transmute::Answer;
+        let maybe_transmutable = transmute_env.is_transmutable(
+            obligation.cause.clone(),
+            rustc_transmute::Types {
+                dst: predicate.trait_ref.substs.type_at(0),
+                src: predicate.trait_ref.substs.type_at(1),
+            },
+            predicate.trait_ref.substs.type_at(2),
+            assume,
+        );
 
         match maybe_transmutable {
-            Answer::Yes => Ok(ImplSourceBuiltinData { nested: vec![] }),
+            rustc_transmute::Answer::Yes => Ok(ImplSourceBuiltinData { nested: vec![] }),
             _ => Err(Unimplemented),
         }
     }
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 20357d4d250..7792ceabe7e 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -243,16 +243,11 @@ pub fn get_vtable_index_of_object_method<'tcx, N>(
 ) -> Option<usize> {
     // Count number of methods preceding the one we are selecting and
     // add them to the total offset.
-    if let Some(index) = tcx
-        .own_existential_vtable_entries(object.upcast_trait_ref.def_id())
+    tcx.own_existential_vtable_entries(object.upcast_trait_ref.def_id())
         .iter()
         .copied()
         .position(|def_id| def_id == method_def_id)
-    {
-        Some(object.vtable_base + index)
-    } else {
-        None
-    }
+        .map(|index| object.vtable_base + index)
 }
 
 pub fn closure_trait_ref_and_return_type<'tcx>(
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index 2be72879b7b..31eea22d72b 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -998,7 +998,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for BoundVarsCollector<'tcx> {
             _ => (),
         };
 
-        r.super_visit_with(self)
+        ControlFlow::Continue(())
     }
 }
 
@@ -1048,7 +1048,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for NamedBoundVarSubstitutor<'a, 'tcx> {
             _ => (),
         };
 
-        r.super_fold_with(self)
+        r
     }
 }
 
@@ -1142,7 +1142,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamsSubstitutor<'tcx> {
                 }
             },
 
-            _ => r.super_fold_with(self),
+            _ => r,
         }
     }
 }
@@ -1223,6 +1223,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for PlaceholdersCollector {
             _ => (),
         };
 
-        r.super_visit_with(self)
+        ControlFlow::Continue(())
     }
 }
diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs
index e0fd487b3d3..19622112f2a 100644
--- a/compiler/rustc_traits/src/type_op.rs
+++ b/compiler/rustc_traits/src/type_op.rs
@@ -89,6 +89,7 @@ fn relate_mir_and_user_substs<'tcx>(
     def_id: hir::def_id::DefId,
     user_substs: UserSubsts<'tcx>,
 ) -> Result<(), NoSolution> {
+    let param_env = param_env.without_const();
     let UserSubsts { user_self_ty, substs } = user_substs;
     let tcx = ocx.infcx.tcx;
     let cause = ObligationCause::dummy_with_span(span);
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index 2a89494c80b..a6d88b1342a 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -196,7 +196,7 @@ pub(crate) mod rustc {
         fn from(err: LayoutError<'tcx>) -> Self {
             match err {
                 LayoutError::Unknown(..) => Self::Unknown,
-                err @ _ => unimplemented!("{:?}", err),
+                err => unimplemented!("{:?}", err),
             }
         }
     }
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index a93a42987ed..8be02c1d988 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -64,7 +64,6 @@ mod rustc {
     use rustc_infer::infer::InferCtxt;
     use rustc_macros::{TypeFoldable, TypeVisitable};
     use rustc_middle::traits::ObligationCause;
-    use rustc_middle::ty::Binder;
     use rustc_middle::ty::Const;
     use rustc_middle::ty::ParamEnv;
     use rustc_middle::ty::Ty;
@@ -92,15 +91,13 @@ mod rustc {
         pub fn is_transmutable(
             &mut self,
             cause: ObligationCause<'tcx>,
-            src_and_dst: Binder<'tcx, Types<'tcx>>,
+            types: Types<'tcx>,
             scope: Ty<'tcx>,
             assume: crate::Assume,
         ) -> crate::Answer<crate::layout::rustc::Ref<'tcx>> {
-            let src = src_and_dst.map_bound(|types| types.src).skip_binder();
-            let dst = src_and_dst.map_bound(|types| types.dst).skip_binder();
             crate::maybe_transmutable::MaybeTransmutableQuery::new(
-                src,
-                dst,
+                types.src,
+                types.dst,
                 scope,
                 assume,
                 self.infcx.tcx,
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 0a6c118093e..47cd7af221d 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -234,15 +234,12 @@ fn resolve_associated_item<'tcx>(
             _ => None,
         },
         traits::ImplSource::Object(ref data) => {
-            if let Some(index) = traits::get_vtable_index_of_object_method(tcx, data, trait_item_id)
-            {
-                Some(Instance {
+            traits::get_vtable_index_of_object_method(tcx, data, trait_item_id).map(|index| {
+                Instance {
                     def: ty::InstanceDef::Virtual(trait_item_id, index),
                     substs: rcvr_substs,
-                })
-            } else {
-                None
-            }
+                }
+            })
         }
         traits::ImplSource::Builtin(..) => {
             let lang_items = tcx.lang_items();
diff --git a/compiler/rustc_ty_utils/src/structural_match.rs b/compiler/rustc_ty_utils/src/structural_match.rs
index a55bb7e7e90..9cb0fc10594 100644
--- a/compiler/rustc_ty_utils/src/structural_match.rs
+++ b/compiler/rustc_ty_utils/src/structural_match.rs
@@ -13,7 +13,7 @@ use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
 /// Note that this does *not* recursively check if the substructure of `adt_ty`
 /// implements the traits.
 fn has_structural_eq_impls<'tcx>(tcx: TyCtxt<'tcx>, adt_ty: Ty<'tcx>) -> bool {
-    let ref infcx = tcx.infer_ctxt().build();
+    let infcx = &tcx.infer_ctxt().build();
     let cause = ObligationCause::dummy();
 
     let ocx = ObligationCtxt::new(infcx);
diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs
index 3a053d4c6a9..371c6119122 100644
--- a/compiler/rustc_type_ir/src/fold.rs
+++ b/compiler/rustc_type_ir/src/fold.rs
@@ -16,8 +16,10 @@
 //!   - Types of interest, for which the methods delegate to the folder.
 //!   - All other types, including generic containers like `Vec` and `Option`.
 //!     It defines a "skeleton" of how they should be folded.
-//! - `TypeSuperFoldable`. This is implemented only for each type of interest,
-//!   and defines the folding "skeleton" for these types.
+//! - `TypeSuperFoldable`. This is implemented only for recursive types of
+//!   interest, and defines the folding "skeleton" for these types. (This
+//!   excludes `Region` because it is non-recursive, i.e. it never contains
+//!   other types of interest.)
 //! - `TypeFolder`/`FallibleTypeFolder`. One of these is implemented for each
 //!   folder. This defines how types of interest are folded.
 //!
@@ -72,9 +74,9 @@ pub trait TypeFoldable<I: Interner>: TypeVisitable<I> {
 
 // This trait is implemented for types of interest.
 pub trait TypeSuperFoldable<I: Interner>: TypeFoldable<I> {
-    /// Provides a default fold for a type of interest. This should only be
-    /// called within `TypeFolder` methods, when a non-custom traversal is
-    /// desired for the value of the type of interest passed to that method.
+    /// Provides a default fold for a recursive type of interest. This should
+    /// only be called within `TypeFolder` methods, when a non-custom traversal
+    /// is desired for the value of the type of interest passed to that method.
     /// For example, in `MyFolder::try_fold_ty(ty)`, it is valid to call
     /// `ty.try_super_fold_with(self)`, but any other folding should be done
     /// with `xyz.try_fold_with(self)`.
@@ -118,11 +120,11 @@ pub trait TypeFolder<I: Interner>: FallibleTypeFolder<I, Error = !> {
         t.super_fold_with(self)
     }
 
-    fn fold_region(&mut self, r: I::Region) -> I::Region
-    where
-        I::Region: TypeSuperFoldable<I>,
-    {
-        r.super_fold_with(self)
+    // The default region folder is a no-op because `Region` is non-recursive
+    // and has no `super_visit_with` method to call. That also explains the
+    // lack of `I::Region: TypeSuperFoldable<I>` bound on this method.
+    fn fold_region(&mut self, r: I::Region) -> I::Region {
+        r
     }
 
     fn fold_const(&mut self, c: I::Const) -> I::Const
@@ -167,11 +169,11 @@ pub trait FallibleTypeFolder<I: Interner>: Sized {
         t.try_super_fold_with(self)
     }
 
-    fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, Self::Error>
-    where
-        I::Region: TypeSuperFoldable<I>,
-    {
-        r.try_super_fold_with(self)
+    // The default region folder is a no-op because `Region` is non-recursive
+    // and has no `super_visit_with` method to call. That also explains the
+    // lack of `I::Region: TypeSuperFoldable<I>` bound on this method.
+    fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, Self::Error> {
+        Ok(r)
     }
 
     fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, Self::Error>
@@ -216,10 +218,7 @@ where
         Ok(self.fold_ty(t))
     }
 
-    fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, !>
-    where
-        I::Region: TypeSuperFoldable<I>,
-    {
+    fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, !> {
         Ok(self.fold_region(r))
     }
 
diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs
index 6c181039730..8c3cb228322 100644
--- a/compiler/rustc_type_ir/src/macros.rs
+++ b/compiler/rustc_type_ir/src/macros.rs
@@ -33,144 +33,3 @@ macro_rules! TrivialTypeTraversalImpls {
         )+
     };
 }
-
-macro_rules! EnumTypeTraversalImpl {
-    (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path {
-        $($variants:tt)*
-    } $(where $($wc:tt)*)*) => {
-        impl<$($p),*> $crate::fold::TypeFoldable<$tcx> for $s
-            $(where $($wc)*)*
-        {
-            fn try_fold_with<V: $crate::fold::FallibleTypeFolder<$tcx>>(
-                self,
-                folder: &mut V,
-            ) -> ::std::result::Result<Self, V::Error> {
-                EnumTypeTraversalImpl!(@FoldVariants(self, folder) input($($variants)*) output())
-            }
-        }
-    };
-
-    (impl<$($p:tt),*> TypeVisitable<$tcx:tt> for $s:path {
-        $($variants:tt)*
-    } $(where $($wc:tt)*)*) => {
-        impl<$($p),*> $crate::visit::TypeVisitable<$tcx> for $s
-            $(where $($wc)*)*
-        {
-            fn visit_with<V: $crate::visit::TypeVisitor<$tcx>>(
-                &self,
-                visitor: &mut V,
-            ) -> ::std::ops::ControlFlow<V::BreakTy> {
-                EnumTypeTraversalImpl!(@VisitVariants(self, visitor) input($($variants)*) output())
-            }
-        }
-    };
-
-    (@FoldVariants($this:expr, $folder:expr) input() output($($output:tt)*)) => {
-        Ok(match $this {
-            $($output)*
-        })
-    };
-
-    (@FoldVariants($this:expr, $folder:expr)
-     input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
-     output( $($output:tt)*) ) => {
-        EnumTypeTraversalImpl!(
-            @FoldVariants($this, $folder)
-                input($($input)*)
-                output(
-                    $variant ( $($variant_arg),* ) => {
-                        $variant (
-                            $($crate::fold::TypeFoldable::try_fold_with($variant_arg, $folder)?),*
-                        )
-                    }
-                    $($output)*
-                )
-        )
-    };
-
-    (@FoldVariants($this:expr, $folder:expr)
-     input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*)
-     output( $($output:tt)*) ) => {
-        EnumTypeTraversalImpl!(
-            @FoldVariants($this, $folder)
-                input($($input)*)
-                output(
-                    $variant { $($variant_arg),* } => {
-                        $variant {
-                            $($variant_arg: $crate::fold::TypeFoldable::fold_with(
-                                $variant_arg, $folder
-                            )?),* }
-                    }
-                    $($output)*
-                )
-        )
-    };
-
-    (@FoldVariants($this:expr, $folder:expr)
-     input( ($variant:path), $($input:tt)*)
-     output( $($output:tt)*) ) => {
-        EnumTypeTraversalImpl!(
-            @FoldVariants($this, $folder)
-                input($($input)*)
-                output(
-                    $variant => { $variant }
-                    $($output)*
-                )
-        )
-    };
-
-    (@VisitVariants($this:expr, $visitor:expr) input() output($($output:tt)*)) => {
-        match $this {
-            $($output)*
-        }
-    };
-
-    (@VisitVariants($this:expr, $visitor:expr)
-     input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*)
-     output( $($output:tt)*) ) => {
-        EnumTypeTraversalImpl!(
-            @VisitVariants($this, $visitor)
-                input($($input)*)
-                output(
-                    $variant ( $($variant_arg),* ) => {
-                        $($crate::visit::TypeVisitable::visit_with(
-                            $variant_arg, $visitor
-                        )?;)*
-                        ::std::ops::ControlFlow::Continue(())
-                    }
-                    $($output)*
-                )
-        )
-    };
-
-    (@VisitVariants($this:expr, $visitor:expr)
-     input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*)
-     output( $($output:tt)*) ) => {
-        EnumTypeTraversalImpl!(
-            @VisitVariants($this, $visitor)
-                input($($input)*)
-                output(
-                    $variant { $($variant_arg),* } => {
-                        $($crate::visit::TypeVisitable::visit_with(
-                            $variant_arg, $visitor
-                        )?;)*
-                        ::std::ops::ControlFlow::Continue(())
-                    }
-                    $($output)*
-                )
-        )
-    };
-
-    (@VisitVariants($this:expr, $visitor:expr)
-     input( ($variant:path), $($input:tt)*)
-     output( $($output:tt)*) ) => {
-        EnumTypeTraversalImpl!(
-            @VisitVariants($this, $visitor)
-                input($($input)*)
-                output(
-                    $variant => { ::std::ops::ControlFlow::Continue(()) }
-                    $($output)*
-                )
-        )
-    };
-}
diff --git a/compiler/rustc_type_ir/src/structural_impls.rs b/compiler/rustc_type_ir/src/structural_impls.rs
index 3ebe241042f..c90c86b7690 100644
--- a/compiler/rustc_type_ir/src/structural_impls.rs
+++ b/compiler/rustc_type_ir/src/structural_impls.rs
@@ -70,30 +70,40 @@ impl<I: Interner, A: TypeVisitable<I>, B: TypeVisitable<I>, C: TypeVisitable<I>>
     }
 }
 
-EnumTypeTraversalImpl! {
-    impl<I, T> TypeFoldable<I> for Option<T> {
-        (Some)(a),
-        (None),
-    } where I: Interner, T: TypeFoldable<I>
-}
-EnumTypeTraversalImpl! {
-    impl<I, T> TypeVisitable<I> for Option<T> {
-        (Some)(a),
-        (None),
-    } where I: Interner, T: TypeVisitable<I>
-}
-
-EnumTypeTraversalImpl! {
-    impl<I, T, E> TypeFoldable<I> for Result<T, E> {
-        (Ok)(a),
-        (Err)(a),
-    } where I: Interner, T: TypeFoldable<I>, E: TypeFoldable<I>,
-}
-EnumTypeTraversalImpl! {
-    impl<I, T, E> TypeVisitable<I> for Result<T, E> {
-        (Ok)(a),
-        (Err)(a),
-    } where I: Interner, T: TypeVisitable<I>, E: TypeVisitable<I>,
+impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Option<T> {
+    fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
+        Ok(match self {
+            Some(v) => Some(v.try_fold_with(folder)?),
+            None => None,
+        })
+    }
+}
+
+impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Option<T> {
+    fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+        match self {
+            Some(v) => v.visit_with(visitor),
+            None => ControlFlow::Continue(()),
+        }
+    }
+}
+
+impl<I: Interner, T: TypeFoldable<I>, E: TypeFoldable<I>> TypeFoldable<I> for Result<T, E> {
+    fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
+        Ok(match self {
+            Ok(v) => Ok(v.try_fold_with(folder)?),
+            Err(e) => Err(e.try_fold_with(folder)?),
+        })
+    }
+}
+
+impl<I: Interner, T: TypeVisitable<I>, E: TypeVisitable<I>> TypeVisitable<I> for Result<T, E> {
+    fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+        match self {
+            Ok(v) => v.visit_with(visitor),
+            Err(e) => e.visit_with(visitor),
+        }
+    }
 }
 
 impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Rc<T> {
diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs
index 62239fd2006..878c7aec6c1 100644
--- a/compiler/rustc_type_ir/src/visit.rs
+++ b/compiler/rustc_type_ir/src/visit.rs
@@ -13,8 +13,11 @@
 //!   - Types of interest, for which the methods delegate to the visitor.
 //!   - All other types, including generic containers like `Vec` and `Option`.
 //!     It defines a "skeleton" of how they should be visited.
-//! - `TypeSuperVisitable`. This is implemented only for each type of interest,
-//!   and defines the visiting "skeleton" for these types.
+//! - `TypeSuperVisitable`. This is implemented only for recursive types of
+//!   interest, and defines the visiting "skeleton" for these types. (This
+//!   excludes `Region` because it is non-recursive, i.e. it never contains
+//!   other types of interest.)
+//!
 //! - `TypeVisitor`. This is implemented for each visitor. This defines how
 //!   types of interest are visited.
 //!
@@ -62,12 +65,13 @@ pub trait TypeVisitable<I: Interner>: fmt::Debug + Clone {
     fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
 }
 
+// This trait is implemented for types of interest.
 pub trait TypeSuperVisitable<I: Interner>: TypeVisitable<I> {
-    /// Provides a default visit for a type of interest. This should only be
-    /// called within `TypeVisitor` methods, when a non-custom traversal is
-    /// desired for the value of the type of interest passed to that method.
-    /// For example, in `MyVisitor::visit_ty(ty)`, it is valid to call
-    /// `ty.super_visit_with(self)`, but any other visiting should be done
+    /// Provides a default visit for a recursive type of interest. This should
+    /// only be called within `TypeVisitor` methods, when a non-custom
+    /// traversal is desired for the value of the type of interest passed to
+    /// that method. For example, in `MyVisitor::visit_ty(ty)`, it is valid to
+    /// call `ty.super_visit_with(self)`, but any other visiting should be done
     /// with `xyz.visit_with(self)`.
     fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
 }
@@ -92,11 +96,11 @@ pub trait TypeVisitor<I: Interner>: Sized {
         t.super_visit_with(self)
     }
 
-    fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy>
-    where
-        I::Region: TypeSuperVisitable<I>,
-    {
-        r.super_visit_with(self)
+    // The default region visitor is a no-op because `Region` is non-recursive
+    // and has no `super_visit_with` method to call. That also explains the
+    // lack of `I::Region: TypeSuperVisitable<I>` bound.
+    fn visit_region(&mut self, _r: I::Region) -> ControlFlow<Self::BreakTy> {
+        ControlFlow::Continue(())
     }
 
     fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy>
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index a7c100e1b23..ba03da411e3 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2519,7 +2519,9 @@ pub(crate) fn is_valid_allocation_size<T>(len: usize) -> bool {
 pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -> bool {
     let src_usize = src.addr();
     let dst_usize = dst.addr();
-    let size = mem::size_of::<T>().checked_mul(count).unwrap();
+    let size = mem::size_of::<T>()
+        .checked_mul(count)
+        .expect("is_nonoverlapping: `size_of::<T>() * count` overflows a usize");
     let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize };
     // If the absolute distance between the ptrs is at least as big as the size of the buffer,
     // they do not overlap.
diff --git a/library/core/tests/num/ieee754.rs b/library/core/tests/num/ieee754.rs
index f6e5dfc98c7..48ab75b6f17 100644
--- a/library/core/tests/num/ieee754.rs
+++ b/library/core/tests/num/ieee754.rs
@@ -39,7 +39,6 @@ macro_rules! assert_biteq {
 
 // ToString uses the default fmt::Display impl without special concerns, and bypasses other parts
 // of the formatting infrastructure, which makes it ideal for testing here.
-#[allow(unused_macros)]
 macro_rules! roundtrip {
     ($f:expr => $t:ty) => {
         ($f).to_string().parse::<$t>().unwrap()
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs
index 77359abe429..bcc172b0fae 100644
--- a/library/std/src/sys/windows/mod.rs
+++ b/library/std/src/sys/windows/mod.rs
@@ -68,10 +68,13 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
         c::ERROR_ALREADY_EXISTS => return AlreadyExists,
         c::ERROR_FILE_EXISTS => return AlreadyExists,
         c::ERROR_BROKEN_PIPE => return BrokenPipe,
-        c::ERROR_FILE_NOT_FOUND => return NotFound,
-        c::ERROR_PATH_NOT_FOUND => return NotFound,
+        c::ERROR_FILE_NOT_FOUND
+        | c::ERROR_PATH_NOT_FOUND
+        | c::ERROR_INVALID_DRIVE
+        | c::ERROR_BAD_NETPATH
+        | c::ERROR_BAD_NET_NAME => return NotFound,
         c::ERROR_NO_DATA => return BrokenPipe,
-        c::ERROR_INVALID_NAME => return InvalidFilename,
+        c::ERROR_INVALID_NAME | c::ERROR_BAD_PATHNAME => return InvalidFilename,
         c::ERROR_INVALID_PARAMETER => return InvalidInput,
         c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return OutOfMemory,
         c::ERROR_SEM_TIMEOUT
diff --git a/src/bootstrap/bolt.rs b/src/bootstrap/bolt.rs
index 10e6d2e7d6d..5384181ea68 100644
--- a/src/bootstrap/bolt.rs
+++ b/src/bootstrap/bolt.rs
@@ -40,7 +40,7 @@ pub fn optimize_with_bolt(path: &Path, profile_path: &Path, output_path: &Path)
         // Reorder functions within the binary
         .arg("-reorder-functions=hfsort+")
         // Split function code into hot and code regions
-        .arg("-split-functions=2")
+        .arg("-split-functions")
         // Split as many basic blocks as possible
         .arg("-split-all-cold")
         // Move jump tables to a separate section
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 025145244c4..0f3a9f96826 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -822,7 +822,8 @@ class RustBuild(object):
         if self.use_vendored_sources:
             vendor_dir = os.path.join(self.rust_root, 'vendor')
             if not os.path.exists(vendor_dir):
-                sync_dirs = "--sync ./src/tools/rust-analyzer/Cargo.toml " \
+                sync_dirs = "--sync ./src/tools/cargo/Cargo.toml " \
+                            "--sync ./src/tools/rust-analyzer/Cargo.toml " \
                             "--sync ./compiler/rustc_codegen_cranelift/Cargo.toml " \
                             "--sync ./src/bootstrap/Cargo.toml "
                 print('error: vendoring required, but vendor directory does not exist.')
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 9498b772f58..372d0708c5b 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -996,12 +996,15 @@ impl Step for PlainSourceTarball {
         // If we're building from git sources, we need to vendor a complete distribution.
         if builder.rust_info().is_managed_git_subrepository() {
             // Ensure we have the submodules checked out.
+            builder.update_submodule(Path::new("src/tools/cargo"));
             builder.update_submodule(Path::new("src/tools/rust-analyzer"));
 
             // Vendor all Cargo dependencies
             let mut cmd = Command::new(&builder.initial_cargo);
             cmd.arg("vendor")
                 .arg("--sync")
+                .arg(builder.src.join("./src/tools/cargo/Cargo.toml"))
+                .arg("--sync")
                 .arg(builder.src.join("./src/tools/rust-analyzer/Cargo.toml"))
                 .arg("--sync")
                 .arg(builder.src.join("./compiler/rustc_codegen_cranelift/Cargo.toml"))
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 419bcbc63cf..bfdb029951f 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -238,8 +238,6 @@ pub struct Build {
     ci_env: CiEnv,
     delayed_failures: RefCell<Vec<String>>,
     prerelease_version: Cell<Option<u32>>,
-    tool_artifacts:
-        RefCell<HashMap<TargetSelection, HashMap<String, (&'static str, PathBuf, Vec<String>)>>>,
 
     #[cfg(feature = "build-metrics")]
     metrics: metrics::BuildMetrics,
@@ -458,7 +456,6 @@ impl Build {
             ci_env: CiEnv::current(),
             delayed_failures: RefCell::new(Vec::new()),
             prerelease_version: Cell::new(None),
-            tool_artifacts: Default::default(),
 
             #[cfg(feature = "build-metrics")]
             metrics: metrics::BuildMetrics::init(),
diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs
index bba4d65e8c3..597aefadcfe 100644
--- a/src/bootstrap/metadata.rs
+++ b/src/bootstrap/metadata.rs
@@ -7,12 +7,16 @@ use crate::cache::INTERNER;
 use crate::util::output;
 use crate::{Build, Crate};
 
-#[derive(Deserialize)]
+/// For more information, see the output of
+/// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
+#[derive(Debug, Deserialize)]
 struct Output {
     packages: Vec<Package>,
 }
 
-#[derive(Deserialize)]
+/// For more information, see the output of
+/// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
+#[derive(Debug, Deserialize)]
 struct Package {
     name: String,
     source: Option<String>,
@@ -20,25 +24,18 @@ struct Package {
     dependencies: Vec<Dependency>,
 }
 
-#[derive(Deserialize)]
+/// For more information, see the output of
+/// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
+#[derive(Debug, Deserialize)]
 struct Dependency {
     name: String,
     source: Option<String>,
 }
 
+/// Collects and stores package metadata of each workspace members into `build`,
+/// by executing `cargo metadata` commands.
 pub fn build(build: &mut Build) {
-    // Run `cargo metadata` to figure out what crates we're testing.
-    let mut cargo = Command::new(&build.initial_cargo);
-    cargo
-        .arg("metadata")
-        .arg("--format-version")
-        .arg("1")
-        .arg("--no-deps")
-        .arg("--manifest-path")
-        .arg(build.src.join("Cargo.toml"));
-    let output = output(&mut cargo);
-    let output: Output = serde_json::from_str(&output).unwrap();
-    for package in output.packages {
+    for package in workspace_members(build) {
         if package.source.is_none() {
             let name = INTERNER.intern_string(package.name);
             let mut path = PathBuf::from(package.manifest_path);
@@ -57,3 +54,35 @@ pub fn build(build: &mut Build) {
         }
     }
 }
+
+/// Invokes `cargo metadata` to get package metadata of each workspace member.
+///
+/// Note that `src/tools/cargo` is no longer a workspace member but we still
+/// treat it as one here, by invoking an additional `cargo metadata` command.
+fn workspace_members(build: &Build) -> impl Iterator<Item = Package> {
+    let cmd_metadata = |manifest_path| {
+        let mut cargo = Command::new(&build.initial_cargo);
+        cargo
+            .arg("metadata")
+            .arg("--format-version")
+            .arg("1")
+            .arg("--no-deps")
+            .arg("--manifest-path")
+            .arg(manifest_path);
+        cargo
+    };
+
+    // Collects `metadata.packages` from the root workspace.
+    let root_manifest_path = build.src.join("Cargo.toml");
+    let root_output = output(&mut cmd_metadata(&root_manifest_path));
+    let Output { packages, .. } = serde_json::from_str(&root_output).unwrap();
+
+    // Collects `metadata.packages` from src/tools/cargo separately.
+    let cargo_manifest_path = build.src.join("src/tools/cargo/Cargo.toml");
+    let cargo_output = output(&mut cmd_metadata(&cargo_manifest_path));
+    let Output { packages: cargo_packages, .. } = serde_json::from_str(&cargo_output).unwrap();
+
+    // We only care about the root package from `src/tool/cargo` workspace.
+    let cargo_package = cargo_packages.into_iter().find(|pkg| pkg.name == "cargo").into_iter();
+    packages.into_iter().chain(cargo_package)
+}
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index aedf1ecab13..3814dc63ed4 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1804,6 +1804,10 @@ note: if you're sure you want to do this, please open an issue as to why. In the
 
         cmd.arg("--channel").arg(&builder.config.channel);
 
+        if !builder.config.omit_git_hash {
+            cmd.arg("--git-hash");
+        }
+
         if let Some(commit) = builder.config.download_rustc_commit() {
             cmd.env("FAKE_DOWNLOAD_RUSTC_PREFIX", format!("/rustc/{commit}"));
         }
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index d1fd2e8c42c..79fab00efe7 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -1,4 +1,3 @@
-use std::collections::HashSet;
 use std::env;
 use std::fs;
 use std::path::PathBuf;
@@ -120,135 +119,9 @@ impl Step for ToolBuild {
             &self.target,
         );
         builder.info(&msg);
-        let mut duplicates = Vec::new();
-        let is_expected = compile::stream_cargo(builder, cargo, vec![], &mut |msg| {
-            // Only care about big things like the RLS/Cargo for now
-            match tool {
-                "rls" | "cargo" | "clippy-driver" | "miri" | "rustfmt" => {}
 
-                _ => return,
-            }
-            let (id, features, filenames) = match msg {
-                compile::CargoMessage::CompilerArtifact {
-                    package_id,
-                    features,
-                    filenames,
-                    target: _,
-                } => (package_id, features, filenames),
-                _ => return,
-            };
-            let features = features.iter().map(|s| s.to_string()).collect::<Vec<_>>();
-
-            for path in filenames {
-                let val = (tool, PathBuf::from(&*path), features.clone());
-                // we're only interested in deduplicating rlibs for now
-                if val.1.extension().and_then(|s| s.to_str()) != Some("rlib") {
-                    continue;
-                }
-
-                // Don't worry about compiles that turn out to be host
-                // dependencies or build scripts. To skip these we look for
-                // anything that goes in `.../release/deps` but *doesn't* go in
-                // `$target/release/deps`. This ensure that outputs in
-                // `$target/release` are still considered candidates for
-                // deduplication.
-                if let Some(parent) = val.1.parent() {
-                    if parent.ends_with("release/deps") {
-                        let maybe_target = parent
-                            .parent()
-                            .and_then(|p| p.parent())
-                            .and_then(|p| p.file_name())
-                            .and_then(|p| p.to_str())
-                            .unwrap();
-                        if maybe_target != &*target.triple {
-                            continue;
-                        }
-                    }
-                }
-
-                // Record that we've built an artifact for `id`, and if one was
-                // already listed then we need to see if we reused the same
-                // artifact or produced a duplicate.
-                let mut artifacts = builder.tool_artifacts.borrow_mut();
-                let prev_artifacts = artifacts.entry(target).or_default();
-                let prev = match prev_artifacts.get(&*id) {
-                    Some(prev) => prev,
-                    None => {
-                        prev_artifacts.insert(id.to_string(), val);
-                        continue;
-                    }
-                };
-                if prev.1 == val.1 {
-                    return; // same path, same artifact
-                }
-
-                // If the paths are different and one of them *isn't* inside of
-                // `release/deps`, then it means it's probably in
-                // `$target/release`, or it's some final artifact like
-                // `libcargo.rlib`. In these situations Cargo probably just
-                // copied it up from `$target/release/deps/libcargo-xxxx.rlib`,
-                // so if the features are equal we can just skip it.
-                let prev_no_hash = prev.1.parent().unwrap().ends_with("release/deps");
-                let val_no_hash = val.1.parent().unwrap().ends_with("release/deps");
-                if prev.2 == val.2 || !prev_no_hash || !val_no_hash {
-                    return;
-                }
-
-                // ... and otherwise this looks like we duplicated some sort of
-                // compilation, so record it to generate an error later.
-                duplicates.push((id.to_string(), val, prev.clone()));
-            }
-        });
-
-        if is_expected && !duplicates.is_empty() {
-            eprintln!(
-                "duplicate artifacts found when compiling a tool, this \
-                      typically means that something was recompiled because \
-                      a transitive dependency has different features activated \
-                      than in a previous build:\n"
-            );
-            let (same, different): (Vec<_>, Vec<_>) =
-                duplicates.into_iter().partition(|(_, cur, prev)| cur.2 == prev.2);
-            if !same.is_empty() {
-                eprintln!(
-                    "the following dependencies are duplicated although they \
-                      have the same features enabled:"
-                );
-                for (id, cur, prev) in same {
-                    eprintln!("  {}", id);
-                    // same features
-                    eprintln!("    `{}` ({:?})\n    `{}` ({:?})", cur.0, cur.1, prev.0, prev.1);
-                }
-            }
-            if !different.is_empty() {
-                eprintln!("the following dependencies have different features:");
-                for (id, cur, prev) in different {
-                    eprintln!("  {}", id);
-                    let cur_features: HashSet<_> = cur.2.into_iter().collect();
-                    let prev_features: HashSet<_> = prev.2.into_iter().collect();
-                    eprintln!(
-                        "    `{}` additionally enabled features {:?} at {:?}",
-                        cur.0,
-                        &cur_features - &prev_features,
-                        cur.1
-                    );
-                    eprintln!(
-                        "    `{}` additionally enabled features {:?} at {:?}",
-                        prev.0,
-                        &prev_features - &cur_features,
-                        prev.1
-                    );
-                }
-            }
-            eprintln!();
-            eprintln!(
-                "to fix this you will probably want to edit the local \
-                      src/tools/rustc-workspace-hack/Cargo.toml crate, as \
-                      that will update the dependency graph to ensure that \
-                      these crates all share the same feature set"
-            );
-            panic!("tools should not compile multiple copies of the same crate");
-        }
+        let mut cargo = Command::from(cargo);
+        let is_expected = builder.try_run_quiet(&mut cargo);
 
         builder.save_toolstate(
             tool,
@@ -299,7 +172,9 @@ pub fn prepare_tool_cargo(
             || path.ends_with("rustfmt")
         {
             cargo.env("LIBZ_SYS_STATIC", "1");
-            features.push("rustc-workspace-hack/all-static".to_string());
+        }
+        if path.ends_with("cargo") {
+            features.push("all-static".to_string());
         }
     }
 
@@ -319,6 +194,12 @@ pub fn prepare_tool_cargo(
     cargo.env("CFG_VERSION", builder.rust_version());
     cargo.env("CFG_RELEASE_NUM", &builder.version);
     cargo.env("DOC_RUST_LANG_ORG_CHANNEL", builder.doc_rust_lang_org_channel());
+    if let Some(ref ver_date) = builder.rust_info().commit_date() {
+        cargo.env("CFG_VER_DATE", ver_date);
+    }
+    if let Some(ref ver_hash) = builder.rust_info().sha() {
+        cargo.env("CFG_VER_HASH", ver_hash);
+    }
 
     let info = GitInfo::new(builder.config.omit_git_hash, &dir);
     if let Some(sha) = info.sha() {
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 62347f169a5..d7c6a884fc8 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -84,8 +84,8 @@ Note: The [`-g` flag][option-g-debug] is an alias for `-C debuginfo=2`.
 This flag controls whether or not the linker includes its default libraries.
 It takes one of the following values:
 
-* `y`, `yes`, `on`, `true` or no value: include default libraries (the default).
-* `n`, `no`, `off` or `false`: exclude default libraries.
+* `y`, `yes`, `on`, `true`: include default libraries.
+* `n`, `no`, `off` or `false` or no value: exclude default libraries (the default).
 
 For example, for gcc flavor linkers, this issues the `-nodefaultlibs` flag to
 the linker.
diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md
index b0b2f419642..2535cd4f12c 100644
--- a/src/doc/rustc/src/instrument-coverage.md
+++ b/src/doc/rustc/src/instrument-coverage.md
@@ -117,7 +117,7 @@ $ ls formatjson5.profraw
 formatjson5.profraw
 ```
 
-If `LLVM_PROFILE_FILE` contains a path to a non-existent directory, the missing directory structure will be created. Additionally, the following special pattern strings are rewritten:
+If `LLVM_PROFILE_FILE` contains a path to a nonexistent directory, the missing directory structure will be created. Additionally, the following special pattern strings are rewritten:
 
 -   `%p` - The process ID.
 -   `%h` - The hostname of the machine running the program.
diff --git a/src/doc/rustc/src/json.md b/src/doc/rustc/src/json.md
index d8843280b84..11d7b5b5938 100644
--- a/src/doc/rustc/src/json.md
+++ b/src/doc/rustc/src/json.md
@@ -61,7 +61,7 @@ Diagnostics have the following format:
             /* The file where the span is located.
                Note that this path may not exist. For example, if the path
                points to the standard library, and the rust src is not
-               available in the sysroot, then it may point to a non-existent
+               available in the sysroot, then it may point to a nonexistent
                file. Beware that this may also point to the source of an
                external crate.
             */
diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md
index 09e03e4dc6f..e351ea00130 100644
--- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md
+++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md
@@ -66,7 +66,7 @@ After completing these steps you can use rust normally in a native environment.
 
 To cross compile, you'll need to:
 
-* Build the rust cross toochain using  [rust-bootstrap-armv7-unknown-linux-uclibceabi](https://github.com/lancethepants/rust-bootstrap-armv7-unknown-linux-uclibceabi) or your own built toolchain.
+* Build the rust cross toolchain using  [rust-bootstrap-armv7-unknown-linux-uclibceabi](https://github.com/lancethepants/rust-bootstrap-armv7-unknown-linux-uclibceabi) or your own built toolchain.
 * Link your built toolchain with
 
     ```text
diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md
index e2bdf73a929..03fa284620e 100644
--- a/src/doc/rustc/src/platform-support/unknown-uefi.md
+++ b/src/doc/rustc/src/platform-support/unknown-uefi.md
@@ -123,7 +123,7 @@ There are 3 common ways to compile native C code for UEFI targets:
   targets. Be wary of any includes that are not specifically suitable for UEFI
   targets (especially the C standard library includes are not always
   compatible). Freestanding compilations are recommended to avoid
-  incompatibilites.
+  incompatibilities.
 
 ## Ecosystem
 
diff --git a/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md b/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md
index eb2285ef906..72157b5cd9b 100644
--- a/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md
+++ b/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md
@@ -88,13 +88,16 @@ fn Foo() {}
 ```
 
 These prefixes will be stripped when displayed in the documentation, so `[struct@Foo]` will be
-rendered as `Foo`.
+rendered as `Foo`. The following prefixes are available: `struct`, `enum`, `trait`, `union`,
+`mod`, `module`, `const`, `constant`, `fn`, `function`, `method`, `derive`, `type`, `value`,
+`macro`, `prim` or `primitive`.
 
 You can also disambiguate for functions by adding `()` after the function name,
-or for macros by adding `!` after the macro name:
+or for macros by adding `!` after the macro name. The macro `!` can be followed by `()`, `{}`,
+or `[]`. Example:
 
 ```rust
-/// This is different from [`foo!`]
+/// This is different from [`foo!()`].
 fn foo() {}
 
 /// This is different from [`foo()`]
diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md
index 21668973194..2d203f264e6 100644
--- a/src/doc/style-guide/src/principles.md
+++ b/src/doc/style-guide/src/principles.md
@@ -6,7 +6,7 @@ following principles (in rough priority order):
 * readability
     - scan-ability
     - avoiding misleading formatting
-    - accessibility - readable and editable by users using the the widest
+    - accessibility - readable and editable by users using the widest
       variety of hardware, including non-visual accessibility interfaces
     - readability of code in contexts without syntax highlighting or IDE
       assistance, such as rustc error messages, diffs, grep, and other
diff --git a/src/doc/style-guide/src/types.md b/src/doc/style-guide/src/types.md
index 25861ddabb8..ae456ef21c8 100644
--- a/src/doc/style-guide/src/types.md
+++ b/src/doc/style-guide/src/types.md
@@ -6,7 +6,7 @@
 * `[T; expr]`, e.g., `[u32; 42]`, `[Vec<Foo>; 10 * 2 + foo()]` (space after colon, no spaces around square brackets)
 * `*const T`, `*mut T` (no space after `*`, space before type)
 * `&'a T`, `&T`, `&'a mut T`, `&mut T` (no space after `&`, single spaces separating other words)
-* `unsafe extern "C" fn<'a, 'b, 'c>(T, U, V) -> W` or `fn()` (single spaces around keyowrds and sigils, and after commas, no trailing commas, no spaces around brackets)
+* `unsafe extern "C" fn<'a, 'b, 'c>(T, U, V) -> W` or `fn()` (single spaces around keywords and sigils, and after commas, no trailing commas, no spaces around brackets)
 * `!` should be treated like any other type name, `Name`
 * `(A, B, C, D)` (spaces after commas, no spaces around parens, no trailing comma unless it is a one-tuple)
 * `<Baz<T> as SomeTrait>::Foo::Bar` or `Foo::Bar` or `::Foo::Bar` (no spaces around `::` or angle brackets, single spaces around `as`)
diff --git a/src/doc/unstable-book/src/compiler-flags/check-cfg.md b/src/doc/unstable-book/src/compiler-flags/check-cfg.md
index 321992f7b0d..10f0fbc5062 100644
--- a/src/doc/unstable-book/src/compiler-flags/check-cfg.md
+++ b/src/doc/unstable-book/src/compiler-flags/check-cfg.md
@@ -202,5 +202,5 @@ fn shoot_lasers() {}
 
 #[cfg(feature = "monkeys")] // This is UNEXPECTED, because "monkeys" is not in
                             // the values(feature) list
-fn write_shakespear() {}
+fn write_shakespeare() {}
 ```
diff --git a/src/doc/unstable-book/src/compiler-flags/move-size-limit.md b/src/doc/unstable-book/src/compiler-flags/move-size-limit.md
index 88f022af2ec..aea054ba911 100644
--- a/src/doc/unstable-book/src/compiler-flags/move-size-limit.md
+++ b/src/doc/unstable-book/src/compiler-flags/move-size-limit.md
@@ -6,5 +6,5 @@ The `-Zmove-size-limit=N` compiler flag enables `large_assignments` lints which
 will warn when moving objects whose size exceeds `N` bytes.
 
 Lint warns only about moves in functions that participate in code generation.
-Consequently it will be ineffective for compiler invocatation that emit
+Consequently it will be ineffective for compiler invocation that emit
 metadata only, i.e., `cargo check` like workflows.
diff --git a/src/doc/unstable-book/src/language-features/transparent-unions.md b/src/doc/unstable-book/src/language-features/transparent-unions.md
index 9b39b897164..bab88b148b2 100644
--- a/src/doc/unstable-book/src/language-features/transparent-unions.md
+++ b/src/doc/unstable-book/src/language-features/transparent-unions.md
@@ -65,7 +65,7 @@ pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable.
 pub const THIS_IS_OKAY: GenericUnion<()> = GenericUnion { field: () };
 ```
 
-Like transarent `struct`s, a transparent `union` of type `U` has the same
+Like transparent `struct`s, a transparent `union` of type `U` has the same
 layout, size, and ABI as its single non-ZST field. If it is generic over a type
 `T`, and all its fields are ZSTs except for exactly one field of type `T`, then
 it has the same layout and ABI as `T` (even if `T` is a ZST when monomorphized).
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 9479b3ee036..eeee12a4310 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -1,7 +1,7 @@
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::lang_items::LangItem;
-use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable, TypeSuperFoldable};
+use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable};
 use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult};
 use thin_vec::ThinVec;
 
@@ -141,7 +141,7 @@ where
         let f = auto_trait::AutoTraitFinder::new(tcx);
 
         debug!("get_auto_trait_impls({:?})", ty);
-        let auto_traits: Vec<_> = self.cx.auto_traits.iter().copied().collect();
+        let auto_traits: Vec<_> = self.cx.auto_traits.to_vec();
         let mut auto_traits: Vec<Item> = auto_traits
             .into_iter()
             .filter_map(|trait_def_id| {
@@ -740,10 +740,9 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionReplacer<'a, 'tcx> {
     }
 
     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        (match *r {
-            ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned(),
-            _ => None,
-        })
-        .unwrap_or_else(|| r.super_fold_with(self))
+        match *r {
+            ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned().unwrap_or(r),
+            _ => r,
+        }
     }
 }
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index cc5d13808b2..3f6a5d6d901 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -528,7 +528,7 @@ pub(crate) fn build_impl(
             items: trait_items,
             polarity,
             kind: if utils::has_doc_flag(tcx, did, sym::fake_variadic) {
-                ImplKind::FakeVaradic
+                ImplKind::FakeVariadic
             } else {
                 ImplKind::Normal
             },
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 5fa0c120fba..04379c2bca9 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2356,7 +2356,7 @@ fn clean_impl<'tcx>(
             items,
             polarity: tcx.impl_polarity(def_id),
             kind: if utils::has_doc_flag(tcx, def_id.to_def_id(), sym::fake_variadic) {
-                ImplKind::FakeVaradic
+                ImplKind::FakeVariadic
             } else {
                 ImplKind::Normal
             },
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 6d2ce9e2833..03129b972f2 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -156,7 +156,7 @@ impl ExternalCrate {
     }
 
     /// Attempts to find where an external crate is located, given that we're
-    /// rendering in to the specified source destination.
+    /// rendering into the specified source destination.
     pub(crate) fn location(
         &self,
         extern_url: Option<&str>,
@@ -751,7 +751,7 @@ pub(crate) enum ItemKind {
     PrimitiveItem(PrimitiveType),
     /// A required associated constant in a trait declaration.
     TyAssocConstItem(Type),
-    /// An associated associated constant in a trait impl or a provided one in a trait declaration.
+    /// An associated constant in a trait impl or a provided one in a trait declaration.
     AssocConstItem(Type, ConstantKind),
     /// A required associated type in a trait declaration.
     ///
@@ -2305,7 +2305,7 @@ impl Impl {
 pub(crate) enum ImplKind {
     Normal,
     Auto,
-    FakeVaradic,
+    FakeVariadic,
     Blanket(Box<Type>),
 }
 
@@ -2319,7 +2319,7 @@ impl ImplKind {
     }
 
     pub(crate) fn is_fake_variadic(&self) -> bool {
-        matches!(self, ImplKind::FakeVaradic)
+        matches!(self, ImplKind::FakeVariadic)
     }
 
     pub(crate) fn as_blanket_ty(&self) -> Option<&Type> {
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 1be4f364ead..b579e7f5ae9 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -491,7 +491,7 @@ impl Options {
                 //   https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset
                 //
                 // The original key values we have are the same as the DOM storage API keys and the
-                // command line options, so contain `-`.  Our Javascript needs to be able to look
+                // command line options, so contain `-`.  Our JavaScript needs to be able to look
                 // these values up both in `dataset` and in the storage API, so it needs to be able
                 // to convert the names back and forth.  Despite doing this kebab-case to
                 // StudlyCaps transformation automatically, the JS DOM API does not provide a
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index c0329182032..841abfab666 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -300,14 +300,13 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
                             ParentStackItem::Impl { for_, .. } => for_.def_id(&self.cache),
                             ParentStackItem::Type(item_id) => item_id.as_def_id(),
                         };
-                        let path = match did.and_then(|did| self.cache.paths.get(&did)) {
+                        let path = did
+                            .and_then(|did| self.cache.paths.get(&did))
                             // The current stack not necessarily has correlation
                             // for where the type was defined. On the other
                             // hand, `paths` always has the right
                             // information if present.
-                            Some((fqp, _)) => Some(&fqp[..fqp.len() - 1]),
-                            None => None,
-                        };
+                            .map(|(fqp, _)| &fqp[..fqp.len() - 1]);
                         ((did, path), true)
                     }
                 }
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index b61dd571458..946c85a205f 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -514,7 +514,7 @@ struct Classifier<'src> {
 
 impl<'src> Classifier<'src> {
     /// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
-    /// file span which will be used later on by the `span_correspondance_map`.
+    /// file span which will be used later on by the `span_correspondence_map`.
     fn new(src: &str, file_span: Span, decoration_info: Option<DecorationInfo>) -> Classifier<'_> {
         let tokens = PeekIter::new(TokenIter { src, cursor: Cursor::new(src) });
         let decorations = decoration_info.map(Decorations::new);
@@ -649,7 +649,7 @@ impl<'src> Classifier<'src> {
     ///
     /// `before` is the position of the given token in the `source` string and is used as "lo" byte
     /// in case we want to try to generate a link for this token using the
-    /// `span_correspondance_map`.
+    /// `span_correspondence_map`.
     fn advance(
         &mut self,
         token: TokenKind,
@@ -895,7 +895,7 @@ fn exit_span(out: &mut impl Write, closing_tag: &str) {
 /// flexible.
 ///
 /// Note that if `context` is not `None` and that the given `klass` contains a `Span`, the function
-/// will then try to find this `span` in the `span_correspondance_map`. If found, it'll then
+/// will then try to find this `span` in the `span_correspondence_map`. If found, it'll then
 /// generate a link for this element (which corresponds to where its definition is located).
 fn string<T: Display>(
     out: &mut impl Write,
@@ -916,7 +916,7 @@ fn string<T: Display>(
 /// * If `klass` is `Some` but `klass.get_span()` is `None`, it writes the text wrapped in a
 ///   `<span>` with the provided `klass`.
 /// * If `klass` is `Some` and has a [`rustc_span::Span`], it then tries to generate a link (`<a>`
-///   element) by retrieving the link information from the `span_correspondance_map` that was filled
+///   element) by retrieving the link information from the `span_correspondence_map` that was filled
 ///   in `span_map.rs::collect_spans_and_sources`. If it cannot retrieve the information, then it's
 ///   the same as the second point (`klass` is `Some` but doesn't have a [`rustc_span::Span`]).
 fn string_without_closing_tag<T: Display>(
@@ -963,7 +963,7 @@ fn string_without_closing_tag<T: Display>(
 
     if let Some(href_context) = href_context {
         if let Some(href) =
-            href_context.context.shared.span_correspondance_map.get(&def_span).and_then(|href| {
+            href_context.context.shared.span_correspondence_map.get(&def_span).and_then(|href| {
                 let context = href_context.context;
                 // FIXME: later on, it'd be nice to provide two links (if possible) for all items:
                 // one to the documentation page and one to the source definition.
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 00aadb8e82a..4b0aee9c3ad 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -1392,7 +1392,7 @@ static DEFAULT_ID_MAP: Lazy<FxHashMap<Cow<'static, str>, usize>> = Lazy::new(||
 
 fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
     let mut map = FxHashMap::default();
-    // This is the list of IDs used in Javascript.
+    // This is the list of IDs used in JavaScript.
     map.insert("help".into(), 1);
     map.insert("settings".into(), 1);
     map.insert("not-displayed".into(), 1);
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index ac5054ce1b6..a063c8c9f02 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -122,9 +122,9 @@ pub(crate) struct SharedContext<'tcx> {
     /// the crate.
     redirections: Option<RefCell<FxHashMap<String, String>>>,
 
-    /// Correspondance map used to link types used in the source code pages to allow to click on
+    /// Correspondence map used to link types used in the source code pages to allow to click on
     /// links to jump to the type's definition.
-    pub(crate) span_correspondance_map: FxHashMap<rustc_span::Span, LinkFromSrc>,
+    pub(crate) span_correspondence_map: FxHashMap<rustc_span::Span, LinkFromSrc>,
     /// The [`Cache`] used during rendering.
     pub(crate) cache: Cache,
 
@@ -531,7 +531,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             errors: receiver,
             redirections: if generate_redirect_map { Some(Default::default()) } else { None },
             show_type_layout,
-            span_correspondance_map: matches,
+            span_correspondence_map: matches,
             cache,
             call_locations,
         };
@@ -647,7 +647,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
                      </div>\
                      <noscript>\
                         <section>\
-                            You need to enable Javascript be able to update your settings.\
+                            You need to enable JavaScript be able to update your settings.\
                         </section>\
                      </noscript>\
                      <link rel=\"stylesheet\" \
@@ -709,7 +709,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
                      </div>\
                      <noscript>\
                         <section>\
-                            <p>You need to enable Javascript to use keyboard commands or search.</p>\
+                            <p>You need to enable JavaScript to use keyboard commands or search.</p>\
                             <p>For more information, browse the <a href=\"https://doc.rust-lang.org/rustdoc/\">rustdoc handbook</a>.</p>\
                         </section>\
                      </noscript>",
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 6f5987e68bf..93d657fd605 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -275,8 +275,7 @@ function preLoadCss(cssUrl) {
             document.title = searchState.titleBeforeSearch;
             // We also remove the query parameter from the URL.
             if (browserSupportsHistoryApi()) {
-                history.replaceState(null, window.currentCrate + " - Rust",
-                    getNakedUrl() + window.location.hash);
+                history.replaceState(null, "", getNakedUrl() + window.location.hash);
             }
         },
         getQueryStringParams: () => {
@@ -378,8 +377,7 @@ function preLoadCss(cssUrl) {
         searchState.clearInputTimeout();
         switchDisplayedElement(null);
         if (browserSupportsHistoryApi()) {
-            history.replaceState(null, window.currentCrate + " - Rust",
-                getNakedUrl() + window.location.hash);
+            history.replaceState(null, "", getNakedUrl() + window.location.hash);
         }
         ev.preventDefault();
         searchState.defocus();
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index cd6509607d5..edd046ab772 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -665,7 +665,7 @@ impl FromWithTcx<clean::Impl> for Impl {
         let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = impl_;
         // FIXME: use something like ImplKind in JSON?
         let (synthetic, blanket_impl) = match kind {
-            clean::ImplKind::Normal | clean::ImplKind::FakeVaradic => (false, None),
+            clean::ImplKind::Normal | clean::ImplKind::FakeVariadic => (false, None),
             clean::ImplKind::Auto => (true, None),
             clean::ImplKind::Blanket(ty) => (false, Some(*ty)),
         };
@@ -740,7 +740,7 @@ impl FromWithTcx<clean::Variant> for Variant {
 impl FromWithTcx<clean::Discriminant> for Discriminant {
     fn from_tcx(disr: clean::Discriminant, tcx: TyCtxt<'_>) -> Self {
         Discriminant {
-            // expr is only none if going through the inlineing path, which gets
+            // expr is only none if going through the inlining path, which gets
             // `rustc_middle` types, not `rustc_hir`, but because JSON never inlines
             // the expr is always some.
             expr: disr.expr(tcx).unwrap(),
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index a835bd2de3b..33e80df9ed7 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1419,6 +1419,7 @@ impl Disambiguator {
         if let Some(idx) = link.find('@') {
             let (prefix, rest) = link.split_at(idx);
             let d = match prefix {
+                // If you update this list, please also update the relevant rustdoc book section!
                 "struct" => Kind(DefKind::Struct),
                 "enum" => Kind(DefKind::Enum),
                 "trait" => Kind(DefKind::Trait),
@@ -1437,6 +1438,7 @@ impl Disambiguator {
             Ok(Some((d, &rest[1..], &rest[1..])))
         } else {
             let suffixes = [
+                // If you update this list, please also update the relevant rustdoc book section!
                 ("!()", DefKind::Macro(MacroKind::Bang)),
                 ("!{}", DefKind::Macro(MacroKind::Bang)),
                 ("![]", DefKind::Macro(MacroKind::Bang)),
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index f28c164d61d..dfa99ffcb7c 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -286,7 +286,7 @@ pub(crate) fn run(
         let (cx, _) = Context::init(krate, renderopts, cache, tcx).map_err(|e| e.to_string())?;
 
         // Collect CrateIds corresponding to provided target crates
-        // If two different versions of the crate in the dependency tree, then examples will be collcted from both.
+        // If two different versions of the crate in the dependency tree, then examples will be collected from both.
         let all_crates = tcx
             .crates(())
             .iter()
diff --git a/src/librustdoc/theme/tests.rs b/src/librustdoc/theme/tests.rs
index 08a174d27d3..2a28c19c3fe 100644
--- a/src/librustdoc/theme/tests.rs
+++ b/src/librustdoc/theme/tests.rs
@@ -13,11 +13,11 @@ rule d
 // another line comment
 e {}
 
-rule f/* a multine
+rule f/* a multiline
 
 comment*/{}
 
-rule g/* another multine
+rule g/* another multiline
 
 comment*/h
 
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 84b7041fd2745ee6b3b4a150314f81aabb78e6b
+Subproject d0a4cbcee614fdb7ba66e860e603a00a644d71f
diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
index 1d9096ea64d..8c3ad24eeed 100644
--- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
+++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
@@ -41,7 +41,7 @@ fn extract_bool_lit(e: &Expr<'_>) -> Option<bool> {
     }) = e.kind
         && !e.span.from_expansion()
     {
-        Some(b)
+        Some(*b)
     } else {
         None
     }
diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs
index c795c1d9a16..7d28c111624 100644
--- a/src/tools/clippy/clippy_lints/src/manual_strip.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs
@@ -159,7 +159,7 @@ fn eq_pattern_length<'tcx>(cx: &LateContext<'tcx>, pattern: &Expr<'_>, expr: &'t
         ..
     }) = expr.kind
     {
-        constant_length(cx, pattern).map_or(false, |length| length == n)
+        constant_length(cx, pattern).map_or(false, |length| length == *n)
     } else {
         len_arg(cx, expr).map_or(false, |arg| eq_expr_value(cx, pattern, arg))
     }
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
index 107fad32393..33bc20dad6b 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
@@ -162,7 +162,7 @@ fn find_bool_lit(ex: &ExprKind<'_>) -> Option<bool> {
                 node: LitKind::Bool(b), ..
             }) = exp.kind
             {
-                Some(b)
+                Some(*b)
             } else {
                 None
             }
diff --git a/src/tools/clippy/clippy_lints/src/methods/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs
index c6a27cdd6fa..23d23f25f14 100644
--- a/src/tools/clippy/clippy_lints/src/methods/open_options.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs
@@ -48,7 +48,7 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec
                         ..
                     } = *span
                     {
-                        if lit { Argument::True } else { Argument::False }
+                        if *lit { Argument::True } else { Argument::False }
                     } else {
                         // The function is called with a literal which is not a boolean literal.
                         // This is theoretically possible, but not very likely.
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index bc4adf1596d..2dac807c420 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -430,7 +430,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                 kind!("Unary(UnOp::{op:?}, {inner})");
                 self.expr(inner);
             },
-            ExprKind::Lit(ref lit) => {
+            ExprKind::Lit(lit) => {
                 bind!(self, lit);
                 kind!("Lit(ref {lit})");
                 self.lit(lit);
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index d2f494942cf..3f36cc5bbcc 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -303,6 +303,9 @@ pub struct Config {
     /// The current Rust channel
     pub channel: String,
 
+    /// Whether adding git commit information such as the commit hash has been enabled for building
+    pub git_hash: bool,
+
     /// The default Rust edition
     pub edition: Option<String>,
 
diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index 35d6179abaa..81179480ed8 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -115,6 +115,11 @@ pub(super) fn handle_needs(
             condition: cache.x86_64_dlltool,
             ignore_reason: "ignored when dlltool for x86_64 is not present",
         },
+        Need {
+            name: "needs-git-hash",
+            condition: config.git_hash,
+            ignore_reason: "ignored when git hashes have been omitted for building",
+        },
     ];
 
     let (name, comment) = match ln.split_once([':', ' ']) {
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index 9af7bd5e201..362fba11697 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -252,6 +252,16 @@ fn debugger() {
 }
 
 #[test]
+fn git_hash() {
+    let mut config = config();
+    config.git_hash = false;
+    assert!(check_ignore(&config, "// needs-git-hash"));
+
+    config.git_hash = true;
+    assert!(!check_ignore(&config, "// needs-git-hash"));
+}
+
+#[test]
 fn sanitizers() {
     let mut config = config();
 
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 4a2b9de8aee..c4bef998f31 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -159,6 +159,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         .optflag("", "nocapture", "")
         .optflag("h", "help", "show this message")
         .reqopt("", "channel", "current Rust channel", "CHANNEL")
+        .optflag("", "git-hash", "run tests which rely on commit version being compiled into the binaries")
         .optopt("", "edition", "default Rust edition", "EDITION");
 
     let (argv0, args_) = args.split_first().unwrap();
@@ -302,6 +303,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         rustfix_coverage: matches.opt_present("rustfix-coverage"),
         has_tidy,
         channel: matches.opt_str("channel").unwrap(),
+        git_hash: matches.opt_present("git-hash"),
         edition: matches.opt_str("edition"),
 
         cc: matches.opt_str("cc").unwrap(),
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 4c735187987..04a1d939d2e 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -301,6 +301,15 @@ environment variable. We first document the most relevant and most commonly used
 * `-Zmiri-disable-isolation` disables host isolation.  As a consequence,
   the program has access to host resources such as environment variables, file
   systems, and randomness.
+* `-Zmiri-disable-leak-backtraces` disables backtraces reports for memory leaks. By default, a
+  backtrace is captured for every allocation when it is created, just in case it leaks. This incurs
+  some memory overhead to store data that is almost never used. This flag is implied by
+  `-Zmiri-ignore-leaks`.
+* `-Zmiri-env-forward=<var>` forwards the `var` environment variable to the interpreted program. Can
+  be used multiple times to forward several variables. Execution will still be deterministic if the
+  value of forwarded variables stays the same. Has no effect if `-Zmiri-disable-isolation` is set.
+* `-Zmiri-ignore-leaks` disables the memory leak checker, and also allows some
+  remaining threads to exist when the main thread exits.
 * `-Zmiri-isolation-error=<action>` configures Miri's response to operations
   requiring host access while isolation is enabled. `abort`, `hide`, `warn`,
   and `warn-nobacktrace` are the supported actions. The default is to `abort`,
@@ -308,11 +317,6 @@ environment variable. We first document the most relevant and most commonly used
   execution with a "permission denied" error being returned to the program.
   `warn` prints a full backtrace when that happens; `warn-nobacktrace` is less
   verbose. `hide` hides the warning entirely.
-* `-Zmiri-env-forward=<var>` forwards the `var` environment variable to the interpreted program. Can
-  be used multiple times to forward several variables. Execution will still be deterministic if the
-  value of forwarded variables stays the same. Has no effect if `-Zmiri-disable-isolation` is set.
-* `-Zmiri-ignore-leaks` disables the memory leak checker, and also allows some
-  remaining threads to exist when the main thread exits.
 * `-Zmiri-num-cpus` states the number of available CPUs to be reported by miri. By default, the
   number of available CPUs is `1`. Note that this flag does not affect how miri handles threads in
   any way.
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 26a7ead2407..3aa71bb7e3c 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -359,6 +359,8 @@ fn main() {
                 isolation_enabled = Some(false);
             }
             miri_config.isolated_op = miri::IsolatedOp::Allow;
+        } else if arg == "-Zmiri-disable-leak-backtraces" {
+            miri_config.collect_leak_backtraces = false;
         } else if arg == "-Zmiri-disable-weak-memory-emulation" {
             miri_config.weak_memory_emulation = false;
         } else if arg == "-Zmiri-track-weak-memory-loads" {
@@ -385,6 +387,7 @@ fn main() {
             };
         } else if arg == "-Zmiri-ignore-leaks" {
             miri_config.ignore_leaks = true;
+            miri_config.collect_leak_backtraces = false;
         } else if arg == "-Zmiri-panic-on-unsupported" {
             miri_config.panic_on_unsupported = true;
         } else if arg == "-Zmiri-tag-raw-pointers" {
diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs
index ed958329f95..d54adb72887 100644
--- a/src/tools/miri/src/borrow_tracker/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/mod.rs
@@ -352,7 +352,7 @@ pub enum AllocState {
     TreeBorrows(Box<RefCell<tree_borrows::AllocState>>),
 }
 
-impl machine::AllocExtra {
+impl machine::AllocExtra<'_> {
     #[track_caller]
     pub fn borrow_tracker_sb(&self) -> &RefCell<stacked_borrows::AllocState> {
         match self.borrow_tracker {
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index 3c13118122c..7a726be00da 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -105,7 +105,7 @@ pub enum NonHaltingDiagnostic {
 }
 
 /// Level of Miri specific diagnostics
-enum DiagLevel {
+pub enum DiagLevel {
     Error,
     Warning,
     Note,
@@ -114,7 +114,7 @@ enum DiagLevel {
 /// Attempts to prune a stacktrace to omit the Rust runtime, and returns a bool indicating if any
 /// frames were pruned. If the stacktrace does not have any local frames, we conclude that it must
 /// be pointing to a problem in the Rust runtime itself, and do not prune it at all.
-fn prune_stacktrace<'tcx>(
+pub fn prune_stacktrace<'tcx>(
     mut stacktrace: Vec<FrameInfo<'tcx>>,
     machine: &MiriMachine<'_, 'tcx>,
 ) -> (Vec<FrameInfo<'tcx>>, bool) {
@@ -338,12 +338,45 @@ pub fn report_error<'tcx, 'mir>(
     None
 }
 
+pub fn report_leaks<'mir, 'tcx>(
+    ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>,
+    leaks: Vec<(AllocId, MemoryKind<MiriMemoryKind>, Allocation<Provenance, AllocExtra<'tcx>>)>,
+) {
+    let mut any_pruned = false;
+    for (id, kind, mut alloc) in leaks {
+        let Some(backtrace) = alloc.extra.backtrace.take() else {
+            continue;
+        };
+        let (backtrace, pruned) = prune_stacktrace(backtrace, &ecx.machine);
+        any_pruned |= pruned;
+        report_msg(
+            DiagLevel::Error,
+            &format!(
+                "memory leaked: {id:?} ({}, size: {:?}, align: {:?}), allocated here:",
+                kind,
+                alloc.size().bytes(),
+                alloc.align.bytes()
+            ),
+            vec![],
+            vec![],
+            vec![],
+            &backtrace,
+            &ecx.machine,
+        );
+    }
+    if any_pruned {
+        ecx.tcx.sess.diagnostic().note_without_error(
+            "some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace",
+        );
+    }
+}
+
 /// Report an error or note (depending on the `error` argument) with the given stacktrace.
 /// Also emits a full stacktrace of the interpreter stack.
 /// We want to present a multi-line span message for some errors. Diagnostics do not support this
 /// directly, so we pass the lines as a `Vec<String>` and display each line after the first with an
 /// additional `span_label` or `note` call.
-fn report_msg<'tcx>(
+pub fn report_msg<'tcx>(
     diag_level: DiagLevel,
     title: &str,
     span_msg: Vec<String>,
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index a32b18595b5..defd37c3775 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -10,6 +10,7 @@ use std::thread;
 use log::info;
 
 use crate::borrow_tracker::RetagFields;
+use crate::diagnostics::report_leaks;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::DefId;
@@ -145,6 +146,8 @@ pub struct MiriConfig {
     pub num_cpus: u32,
     /// Requires Miri to emulate pages of a certain size
     pub page_size: Option<u64>,
+    /// Whether to collect a backtrace when each allocation is created, just in case it leaks.
+    pub collect_leak_backtraces: bool,
 }
 
 impl Default for MiriConfig {
@@ -179,6 +182,7 @@ impl Default for MiriConfig {
             gc_interval: 10_000,
             num_cpus: 1,
             page_size: None,
+            collect_leak_backtraces: true,
         }
     }
 }
@@ -457,10 +461,17 @@ pub fn eval_entry<'tcx>(
         }
         // Check for memory leaks.
         info!("Additonal static roots: {:?}", ecx.machine.static_roots);
-        let leaks = ecx.leak_report(&ecx.machine.static_roots);
-        if leaks != 0 {
-            tcx.sess.err("the evaluated program leaked memory");
-            tcx.sess.note_without_error("pass `-Zmiri-ignore-leaks` to disable this check");
+        let leaks = ecx.find_leaked_allocations(&ecx.machine.static_roots);
+        if !leaks.is_empty() {
+            report_leaks(&ecx, leaks);
+            let leak_message = "the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check";
+            if ecx.machine.collect_leak_backtraces {
+                // If we are collecting leak backtraces, each leak is a distinct error diagnostic.
+                tcx.sess.note_without_error(leak_message);
+            } else {
+                // If we do not have backtraces, we just report an error without any span.
+                tcx.sess.err(leak_message);
+            };
             // Ignore the provided return code - let the reported error
             // determine the return code.
             return None;
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 477d8d33ebb..ecb3e13dd54 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -253,20 +253,25 @@ impl ProvenanceExtra {
 
 /// Extra per-allocation data
 #[derive(Debug, Clone)]
-pub struct AllocExtra {
+pub struct AllocExtra<'tcx> {
     /// Global state of the borrow tracker, if enabled.
     pub borrow_tracker: Option<borrow_tracker::AllocState>,
-    /// Data race detection via the use of a vector-clock,
-    ///  this is only added if it is enabled.
+    /// Data race detection via the use of a vector-clock.
+    /// This is only added if it is enabled.
     pub data_race: Option<data_race::AllocState>,
-    /// Weak memory emulation via the use of store buffers,
-    ///  this is only added if it is enabled.
+    /// Weak memory emulation via the use of store buffers.
+    /// This is only added if it is enabled.
     pub weak_memory: Option<weak_memory::AllocState>,
+    /// A backtrace to where this allocation was allocated.
+    /// As this is recorded for leak reports, it only exists
+    /// if this allocation is leakable. The backtrace is not
+    /// pruned yet; that should be done before printing it.
+    pub backtrace: Option<Vec<FrameInfo<'tcx>>>,
 }
 
-impl VisitTags for AllocExtra {
+impl VisitTags for AllocExtra<'_> {
     fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
-        let AllocExtra { borrow_tracker, data_race, weak_memory } = self;
+        let AllocExtra { borrow_tracker, data_race, weak_memory, backtrace: _ } = self;
 
         borrow_tracker.visit_tags(visit);
         data_race.visit_tags(visit);
@@ -467,12 +472,17 @@ pub struct MiriMachine<'mir, 'tcx> {
     pub(crate) gc_interval: u32,
     /// The number of blocks that passed since the last BorTag GC pass.
     pub(crate) since_gc: u32,
+
     /// The number of CPUs to be reported by miri.
     pub(crate) num_cpus: u32,
+
     /// Determines Miri's page size and associated values
     pub(crate) page_size: u64,
     pub(crate) stack_addr: u64,
     pub(crate) stack_size: u64,
+
+    /// Whether to collect a backtrace when each allocation is created, just in case it leaks.
+    pub(crate) collect_leak_backtraces: bool,
 }
 
 impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
@@ -581,6 +591,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
             page_size,
             stack_addr,
             stack_size,
+            collect_leak_backtraces: config.collect_leak_backtraces,
         }
     }
 
@@ -728,6 +739,7 @@ impl VisitTags for MiriMachine<'_, '_> {
             page_size: _,
             stack_addr: _,
             stack_size: _,
+            collect_leak_backtraces: _,
         } = self;
 
         threads.visit_tags(visit);
@@ -773,7 +785,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
     type ExtraFnVal = Dlsym;
 
     type FrameExtra = FrameExtra<'tcx>;
-    type AllocExtra = AllocExtra;
+    type AllocExtra = AllocExtra<'tcx>;
 
     type Provenance = Provenance;
     type ProvenanceExtra = ProvenanceExtra;
@@ -967,9 +979,24 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
             )
         });
         let buffer_alloc = ecx.machine.weak_memory.then(weak_memory::AllocState::new_allocation);
+
+        // If an allocation is leaked, we want to report a backtrace to indicate where it was
+        // allocated. We don't need to record a backtrace for allocations which are allowed to
+        // leak.
+        let backtrace = if kind.may_leak() || !ecx.machine.collect_leak_backtraces {
+            None
+        } else {
+            Some(ecx.generate_stacktrace())
+        };
+
         let alloc: Allocation<Provenance, Self::AllocExtra> = alloc.adjust_from_tcx(
             &ecx.tcx,
-            AllocExtra { borrow_tracker, data_race: race_alloc, weak_memory: buffer_alloc },
+            AllocExtra {
+                borrow_tracker,
+                data_race: race_alloc,
+                weak_memory: buffer_alloc,
+                backtrace,
+            },
             |ptr| ecx.global_base_pointer(ptr),
         )?;
         Ok(Cow::Owned(alloc))
@@ -1049,7 +1076,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
     fn before_memory_read(
         _tcx: TyCtxt<'tcx>,
         machine: &Self,
-        alloc_extra: &AllocExtra,
+        alloc_extra: &AllocExtra<'tcx>,
         (alloc_id, prov_extra): (AllocId, Self::ProvenanceExtra),
         range: AllocRange,
     ) -> InterpResult<'tcx> {
@@ -1069,7 +1096,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
     fn before_memory_write(
         _tcx: TyCtxt<'tcx>,
         machine: &mut Self,
-        alloc_extra: &mut AllocExtra,
+        alloc_extra: &mut AllocExtra<'tcx>,
         (alloc_id, prov_extra): (AllocId, Self::ProvenanceExtra),
         range: AllocRange,
     ) -> InterpResult<'tcx> {
@@ -1089,7 +1116,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
     fn before_memory_deallocation(
         _tcx: TyCtxt<'tcx>,
         machine: &mut Self,
-        alloc_extra: &mut AllocExtra,
+        alloc_extra: &mut AllocExtra<'tcx>,
         (alloc_id, prove_extra): (AllocId, Self::ProvenanceExtra),
         range: AllocRange,
     ) -> InterpResult<'tcx> {
diff --git a/src/tools/miri/src/tag_gc.rs b/src/tools/miri/src/tag_gc.rs
index c1194fe2216..cefdcc2b5b8 100644
--- a/src/tools/miri/src/tag_gc.rs
+++ b/src/tools/miri/src/tag_gc.rs
@@ -125,7 +125,7 @@ impl VisitTags for Operand<Provenance> {
     }
 }
 
-impl VisitTags for Allocation<Provenance, AllocExtra> {
+impl VisitTags for Allocation<Provenance, AllocExtra<'_>> {
     fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
         for prov in self.provenance().provenances() {
             prov.visit_tags(visit);
diff --git a/src/tools/miri/tests/fail/memleak.rs b/src/tools/miri/tests/fail/memleak.rs
index d384caf81a5..cbeb163b56c 100644
--- a/src/tools/miri/tests/fail/memleak.rs
+++ b/src/tools/miri/tests/fail/memleak.rs
@@ -1,4 +1,4 @@
-//@error-pattern: the evaluated program leaked memory
+//@error-pattern: memory leaked
 //@normalize-stderr-test: ".*│.*" -> "$$stripped$$"
 
 fn main() {
diff --git a/src/tools/miri/tests/fail/memleak.stderr b/src/tools/miri/tests/fail/memleak.stderr
index f8b62af3eb8..6d9b664c8f4 100644
--- a/src/tools/miri/tests/fail/memleak.stderr
+++ b/src/tools/miri/tests/fail/memleak.stderr
@@ -1,10 +1,23 @@
-The following memory was leaked: ALLOC (Rust heap, size: 4, align: 4) {
-$stripped$
-}
+error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here:
+  --> RUSTLIB/alloc/src/alloc.rs:LL:CC
+   |
+LL |     unsafe { __rust_alloc(layout.size(), layout.align()) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: inside `std::alloc::alloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+   = note: inside `std::alloc::Global::alloc_impl` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+   = note: inside `<std::alloc::Global as std::alloc::Allocator>::allocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+   = note: inside `alloc::alloc::exchange_malloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+   = note: inside `std::boxed::Box::<i32>::new` at RUSTLIB/alloc/src/boxed.rs:LL:CC
+note: inside `main`
+  --> $DIR/memleak.rs:LL:CC
+   |
+LL |     std::mem::forget(Box::new(42));
+   |                      ^^^^^^^^^^^^
 
-error: the evaluated program leaked memory
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
 
-note: pass `-Zmiri-ignore-leaks` to disable this check
+note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check
 
 error: aborting due to previous error
 
diff --git a/src/tools/miri/tests/fail/memleak_no_backtrace.rs b/src/tools/miri/tests/fail/memleak_no_backtrace.rs
new file mode 100644
index 00000000000..24d4a02df71
--- /dev/null
+++ b/src/tools/miri/tests/fail/memleak_no_backtrace.rs
@@ -0,0 +1,7 @@
+//@compile-flags: -Zmiri-disable-leak-backtraces
+//@error-pattern: the evaluated program leaked memory
+//@normalize-stderr-test: ".*│.*" -> "$$stripped$$"
+
+fn main() {
+    std::mem::forget(Box::new(42));
+}
diff --git a/src/tools/miri/tests/fail/memleak_no_backtrace.stderr b/src/tools/miri/tests/fail/memleak_no_backtrace.stderr
new file mode 100644
index 00000000000..f44e6ce0797
--- /dev/null
+++ b/src/tools/miri/tests/fail/memleak_no_backtrace.stderr
@@ -0,0 +1,4 @@
+error: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/fail/memleak_rc.32bit.stderr b/src/tools/miri/tests/fail/memleak_rc.32bit.stderr
index da222609091..0e1146cf4ad 100644
--- a/src/tools/miri/tests/fail/memleak_rc.32bit.stderr
+++ b/src/tools/miri/tests/fail/memleak_rc.32bit.stderr
@@ -1,10 +1,24 @@
-The following memory was leaked: ALLOC (Rust heap, size: 16, align: 4) {
-$stripped$
-}
+error: memory leaked: ALLOC (Rust heap, size: 16, align: 4), allocated here:
+  --> RUSTLIB/alloc/src/alloc.rs:LL:CC
+   |
+LL |     unsafe { __rust_alloc(layout.size(), layout.align()) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: inside `std::alloc::alloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+   = note: inside `std::alloc::Global::alloc_impl` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+   = note: inside `<std::alloc::Global as std::alloc::Allocator>::allocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+   = note: inside `alloc::alloc::exchange_malloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+   = note: inside `std::boxed::Box::<std::rc::RcBox<std::cell::RefCell<std::option::Option<Dummy>>>>::new` at RUSTLIB/alloc/src/boxed.rs:LL:CC
+   = note: inside `std::rc::Rc::<std::cell::RefCell<std::option::Option<Dummy>>>::new` at RUSTLIB/alloc/src/rc.rs:LL:CC
+note: inside `main`
+  --> $DIR/memleak_rc.rs:LL:CC
+   |
+LL |     let x = Dummy(Rc::new(RefCell::new(None)));
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: the evaluated program leaked memory
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
 
-note: pass `-Zmiri-ignore-leaks` to disable this check
+note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check
 
 error: aborting due to previous error
 
diff --git a/src/tools/miri/tests/fail/memleak_rc.64bit.stderr b/src/tools/miri/tests/fail/memleak_rc.64bit.stderr
index 8c24bbc779b..4979588f370 100644
--- a/src/tools/miri/tests/fail/memleak_rc.64bit.stderr
+++ b/src/tools/miri/tests/fail/memleak_rc.64bit.stderr
@@ -1,11 +1,24 @@
-The following memory was leaked: ALLOC (Rust heap, size: 32, align: 8) {
-$stripped$
-$stripped$
-}
+error: memory leaked: ALLOC (Rust heap, size: 32, align: 8), allocated here:
+  --> RUSTLIB/alloc/src/alloc.rs:LL:CC
+   |
+LL |     unsafe { __rust_alloc(layout.size(), layout.align()) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: inside `std::alloc::alloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+   = note: inside `std::alloc::Global::alloc_impl` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+   = note: inside `<std::alloc::Global as std::alloc::Allocator>::allocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+   = note: inside `alloc::alloc::exchange_malloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+   = note: inside `std::boxed::Box::<std::rc::RcBox<std::cell::RefCell<std::option::Option<Dummy>>>>::new` at RUSTLIB/alloc/src/boxed.rs:LL:CC
+   = note: inside `std::rc::Rc::<std::cell::RefCell<std::option::Option<Dummy>>>::new` at RUSTLIB/alloc/src/rc.rs:LL:CC
+note: inside `main`
+  --> $DIR/memleak_rc.rs:LL:CC
+   |
+LL |     let x = Dummy(Rc::new(RefCell::new(None)));
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: the evaluated program leaked memory
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
 
-note: pass `-Zmiri-ignore-leaks` to disable this check
+note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check
 
 error: aborting due to previous error
 
diff --git a/src/tools/miri/tests/fail/memleak_rc.rs b/src/tools/miri/tests/fail/memleak_rc.rs
index 76ecd71b011..cf4671912ad 100644
--- a/src/tools/miri/tests/fail/memleak_rc.rs
+++ b/src/tools/miri/tests/fail/memleak_rc.rs
@@ -1,4 +1,4 @@
-//@error-pattern: the evaluated program leaked memory
+//@error-pattern: memory leaked
 //@stderr-per-bitwidth
 //@normalize-stderr-test: ".*│.*" -> "$$stripped$$"
 
diff --git a/src/tools/rls/Cargo.toml b/src/tools/rls/Cargo.toml
index 92b50bf4cec..b84647eb332 100644
--- a/src/tools/rls/Cargo.toml
+++ b/src/tools/rls/Cargo.toml
@@ -7,7 +7,3 @@ license = "Apache-2.0/MIT"
 [dependencies]
 serde = { version = "1.0.143", features = ["derive"] }
 serde_json = "1.0.83"
-# A noop dependency that changes in the Rust repository, it's a bit of a hack.
-# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
-# for more information.
-rustc-workspace-hack = "1.0.0"
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
deleted file mode 100644
index e088ffbbe77..00000000000
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ /dev/null
@@ -1,102 +0,0 @@
-[package]
-name = "rustc-workspace-hack"
-version = "1.0.0"
-license = 'MIT OR Apache-2.0'
-description = """
-Hack for the compiler's own build system
-"""
-edition = "2021"
-
-[lib]
-path = "lib.rs"
-
-# For documentation about what this is and why in the world these dependencies
-# are appearing, see `README.md`.
-
-[target.'cfg(windows)'.dependencies.winapi]
-version = "0.3"
-features = [
-  "accctrl",
-  "aclapi",
-  "basetsd",
-  "cfg",
-  "consoleapi",
-  "errhandlingapi",
-  "evntrace",
-  "fibersapi",
-  "handleapi",
-  "in6addr",
-  "inaddr",
-  "ioapiset",
-  "jobapi",
-  "jobapi2",
-  "knownfolders",
-  "libloaderapi",
-  "lmcons",
-  "memoryapi",
-  "minschannel",
-  "minwinbase",
-  "mstcpip",
-  "mswsock",
-  "namedpipeapi",
-  "ntdef",
-  "ntsecapi",
-  "ntstatus",
-  "objbase",
-  "processenv",
-  "processthreadsapi",
-  "profileapi",
-  "psapi",
-  "schannel",
-  "securitybaseapi",
-  "shellapi",
-  "shlobj",
-  "sspi",
-  "synchapi",
-  "sysinfoapi",
-  "threadpoollegacyapiset",
-  "timezoneapi",
-  "userenv",
-  "winbase",
-  "wincon",
-  "wincrypt",
-  "windef",
-  "winioctl",
-  "winnt",
-  "winreg",
-  "winsock2",
-  "winuser",
-  "ws2def",
-  "ws2ipdef",
-  "ws2tcpip",
-]
-
-[dependencies]
-bstr = { version = "0.2.17", features = ["default"] }
-clap = { version = "3.1.1", features = ["derive", "clap_derive"]}
-curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true }
-# Ensure `extra_traits` of libc, which is used transitively by Cargo.
-libc = { version = "0.2", features = ["extra_traits"] }
-# Ensure `js` of getrandom, which is (unfortunately) used transitively by Cargo.
-getrandom = { version = "0.2", features = ["js"] }
-# Ensure default features of libz-sys, which are disabled in some scenarios.
-libz-sys = { version = "1.1.2" }
-# Ensure default features of regex, which are disabled in some scenarios.
-regex = { version = "1.5.6" }
-serde_json = { version = "1.0.31", features = ["raw_value", "unbounded_depth"] }
-syn = { version = "1", features = ['full', 'visit', 'visit-mut'] } # `visit-mut` required by Cargo via `gix`
-url = { version = "2.0", features = ['serde'] }
-# Ensure default features of rand, which are disabled in some scenarios.
-rand = { version = "0.8.5" }
-
-# Ensure features of `hashbrown`, `smallvec`, and `once_cell`,
-# which are used transitively by Cargo (via `gix`).
-hashbrown = { version = "0.12.3", default-features = false, features = ["inline-more"] }
-once_cell = { version = "1.16.0", default-features = false, features = ["unstable"] }
-smallvec = { version = "1.10.0", features = ["write"] }
-
-[target.'cfg(not(windows))'.dependencies]
-openssl = { version = "0.10.35", optional = true }
-
-[features]
-all-static = ['openssl/vendored', 'curl-sys/static-curl', 'curl-sys/force-system-lib-on-osx']
diff --git a/src/tools/rustc-workspace-hack/README.md b/src/tools/rustc-workspace-hack/README.md
deleted file mode 100644
index 3c61470358b..00000000000
--- a/src/tools/rustc-workspace-hack/README.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# `rustc-workspace-hack`
-
-This crate is a bit of a hack to make workspaces in rustc work a bit better.
-The rationale for this existence is a bit subtle, but the general idea is that
-we want commands like `./x.py build src/tools/{clippy,cargo}` to share as
-many dependencies as possible.
-
-Each invocation is a different invocation of Cargo, however. Each time Cargo
-runs a build it will re-resolve the dependency graph, notably selecting
-different features sometimes for each build.
-
-For example, let's say there's a very deep dependency like `winapi` in each of
-these builds. For Cargo, `winapi` has 33 features enabled. In Clippy, however,
-`winapi` has 22 features enabled. This means that building Cargo and then the
-Clippy will actually build winapi twice, which in turn will build duplicates
-of everything that depends on `winapi`. This is bad!
-
-The goal of this crate is to solve this problem and ensure that the resolved
-dependency graph for all of these tools is the same in the various subsets of
-each tool, notably enabling the same features of transitive dependencies.
-
-All tools vendored here depend on the `rustc-workspace-hack` crate on crates.io.
-When on crates.io this crate is an empty crate that is just a noop. We override
-it, however, in this workspace to this crate here, which means we can control
-crates in the dependency graph for each of these tools.
diff --git a/src/tools/rustc-workspace-hack/lib.rs b/src/tools/rustc-workspace-hack/lib.rs
deleted file mode 100644
index 44425d9c15f..00000000000
--- a/src/tools/rustc-workspace-hack/lib.rs
+++ /dev/null
@@ -1 +0,0 @@
-// intentionally left blank
diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js
index 72baad606f0..692d5e3fcef 100644
--- a/src/tools/rustdoc-gui/tester.js
+++ b/src/tools/rustdoc-gui/tester.js
@@ -42,7 +42,7 @@ function parseOptions(args) {
         "executable_path": null,
         "no_sandbox": false,
     };
-    const correspondances = {
+    const correspondences = {
         "--doc-folder": "doc_folder",
         "--tests-folder": "tests_folder",
         "--debug": "debug",
@@ -73,7 +73,7 @@ function parseOptions(args) {
                 }
                 opts["jobs"] = parseInt(arg_value);
             } else if (arg !== "--file") {
-                opts[correspondances[arg]] = arg_value;
+                opts[correspondences[arg]] = arg_value;
             } else {
                 opts["files"].push(arg_value);
             }
@@ -82,9 +82,9 @@ function parseOptions(args) {
             process.exit(0);
         } else if (arg === "--no-sandbox") {
             console.log("`--no-sandbox` is being used. Be very careful!");
-            opts[correspondances[arg]] = true;
-        } else if (correspondances[arg]) {
-            opts[correspondances[arg]] = true;
+            opts[correspondences[arg]] = true;
+        } else if (correspondences[arg]) {
+            opts[correspondences[arg]] = true;
         } else {
             console.log("Unknown option `" + arg + "`.");
             console.log("Use `--help` to see the list of options");
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index a9eb6c8d03f..0e0a517ae49 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -18,6 +18,7 @@ const LICENSES: &[&str] = &[
     "ISC",
     "Unlicense/MIT",
     "Unlicense OR MIT",
+    "0BSD",
     "0BSD OR MIT OR Apache-2.0",                // adler license
     "Zlib OR Apache-2.0 OR MIT",                // tinyvec
     "MIT OR Apache-2.0 OR Zlib",                // tinyvec_macros
@@ -33,30 +34,35 @@ const LICENSES: &[&str] = &[
 const EXCEPTIONS: &[(&str, &str)] = &[
     ("ar_archive_writer", "Apache-2.0 WITH LLVM-exception"), // rustc
     ("mdbook", "MPL-2.0"),                                   // mdbook
-    ("openssl", "Apache-2.0"),                               // cargo, mdbook
     ("colored", "MPL-2.0"),                                  // rustfmt
     ("ryu", "Apache-2.0 OR BSL-1.0"),                        // cargo/... (because of serde)
-    ("bytesize", "Apache-2.0"),                              // cargo
-    ("im-rc", "MPL-2.0+"),                                   // cargo
-    ("sized-chunks", "MPL-2.0+"),                            // cargo via im-rc
-    ("bitmaps", "MPL-2.0+"),                                 // cargo via im-rc
-    ("fiat-crypto", "MIT OR Apache-2.0 OR BSD-1-Clause"),    // cargo via pasetors
-    ("subtle", "BSD-3-Clause"),                              // cargo via pasetors
-    ("dunce", "CC0-1.0 OR MIT-0"),                           // cargo via gix (and dev dependency)
-    ("imara-diff", "Apache-2.0"),                            // cargo via gix
-    ("sha1_smol", "BSD-3-Clause"),                           // cargo via gix
-    ("unicode-bom", "Apache-2.0"),                           // cargo via gix
     ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot
     ("snap", "BSD-3-Clause"),    // rustc
     ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations)
     ("self_cell", "Apache-2.0"), // rustc (fluent translations)
     // FIXME: this dependency violates the documentation comment above:
     ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target
-    ("similar", "Apache-2.0"),       // cargo (dev dependency)
-    ("normalize-line-endings", "Apache-2.0"), // cargo (dev dependency)
     ("dissimilar", "Apache-2.0"),    // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps)
 ];
 
+const EXCEPTIONS_CARGO: &[(&str, &str)] = &[
+    ("bitmaps", "MPL-2.0+"),
+    ("bytesize", "Apache-2.0"),
+    ("dunce", "CC0-1.0 OR MIT-0"),
+    ("fiat-crypto", "MIT OR Apache-2.0 OR BSD-1-Clause"),
+    ("im-rc", "MPL-2.0+"),
+    ("imara-diff", "Apache-2.0"),
+    ("instant", "BSD-3-Clause"),
+    ("normalize-line-endings", "Apache-2.0"),
+    ("openssl", "Apache-2.0"),
+    ("ryu", "Apache-2.0 OR BSL-1.0"),
+    ("sha1_smol", "BSD-3-Clause"),
+    ("similar", "Apache-2.0"),
+    ("sized-chunks", "MPL-2.0+"),
+    ("subtle", "BSD-3-Clause"),
+    ("unicode-bom", "Apache-2.0"),
+];
+
 const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[
     ("cranelift-bforest", "Apache-2.0 WITH LLVM-exception"),
     ("cranelift-codegen", "Apache-2.0 WITH LLVM-exception"),
@@ -156,7 +162,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "lazy_static",
     "libc",
     "libloading",
-    "libz-sys",
     "litemap",
     "lock_api",
     "log",
@@ -177,7 +182,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "perf-event-open-sys",
     "petgraph",
     "pin-project-lite",
-    "pkg-config",
     "polonius-engine",
     "ppv-lite86",
     "proc-macro-hack",
@@ -217,7 +221,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "stable_deref_trait",
     "stacker",
     "static_assertions",
-    "subtle", // dependency of cargo (via pasetors)
     "syn",
     "synstructure",
     "tempfile",
@@ -256,7 +259,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "unicode-security",
     "unicode-width",
     "unicode-xid",
-    "vcpkg",
     "valuable",
     "version_check",
     "wasi",
@@ -333,13 +335,6 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
     "windows_x86_64_msvc",
 ];
 
-const FORBIDDEN_TO_HAVE_DUPLICATES: &[&str] = &[
-    // This crate takes quite a long time to build, so don't allow two versions of them
-    // to accidentally sneak into our dependency graph, in order to ensure we keep our CI times
-    // under control.
-    "cargo",
-];
-
 /// Dependency checks.
 ///
 /// `root` is path to the directory with the root `Cargo.toml` (for the workspace). `cargo` is path
@@ -359,8 +354,16 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
         &["rustc_driver", "rustc_codegen_llvm"],
         bad,
     );
-    check_crate_duplicate(&metadata, FORBIDDEN_TO_HAVE_DUPLICATES, bad);
-    check_rustfix(&metadata, bad);
+
+    // Check cargo independently as it has it's own workspace.
+    let mut cmd = cargo_metadata::MetadataCommand::new();
+    cmd.cargo_path(cargo)
+        .manifest_path(root.join("src/tools/cargo/Cargo.toml"))
+        .features(cargo_metadata::CargoOpt::AllFeatures);
+    let cargo_metadata = t!(cmd.exec());
+    let runtime_ids = HashSet::new();
+    check_license_exceptions(&cargo_metadata, EXCEPTIONS_CARGO, runtime_ids, bad);
+    check_rustfix(&metadata, &cargo_metadata, bad);
 
     // Check rustc_codegen_cranelift independently as it has it's own workspace.
     let mut cmd = cargo_metadata::MetadataCommand::new();
@@ -377,7 +380,6 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
         &["rustc_codegen_cranelift"],
         bad,
     );
-    check_crate_duplicate(&metadata, &[], bad);
 
     let mut cmd = cargo_metadata::MetadataCommand::new();
     cmd.cargo_path(cargo)
@@ -523,40 +525,6 @@ fn check_permitted_dependencies(
     }
 }
 
-/// Prevents multiple versions of some expensive crates.
-fn check_crate_duplicate(
-    metadata: &Metadata,
-    forbidden_to_have_duplicates: &[&str],
-    bad: &mut bool,
-) {
-    for &name in forbidden_to_have_duplicates {
-        let matches: Vec<_> = metadata.packages.iter().filter(|pkg| pkg.name == name).collect();
-        match matches.len() {
-            0 => {
-                tidy_error!(
-                    bad,
-                    "crate `{}` is missing, update `check_crate_duplicate` \
-                    if it is no longer used",
-                    name
-                );
-            }
-            1 => {}
-            _ => {
-                tidy_error!(
-                    bad,
-                    "crate `{}` is duplicated in `Cargo.lock`, \
-                    it is too expensive to build multiple times, \
-                    so make sure only one version appears across all dependencies",
-                    name
-                );
-                for pkg in matches {
-                    println!("  * {}", pkg.id);
-                }
-            }
-        }
-    }
-}
-
 /// Finds a package with the given name.
 fn pkg_from_name<'a>(metadata: &'a Metadata, name: &'static str) -> &'a Package {
     let mut i = metadata.packages.iter().filter(|p| p.name == name);
@@ -606,19 +574,24 @@ fn deps_of_filtered<'a>(
     }
 }
 
-fn direct_deps_of<'a>(metadata: &'a Metadata, pkg_id: &'a PackageId) -> Vec<&'a Package> {
+fn direct_deps_of<'a>(
+    metadata: &'a Metadata,
+    pkg_id: &'a PackageId,
+) -> impl Iterator<Item = &'a Package> {
     let resolve = metadata.resolve.as_ref().unwrap();
     let node = resolve.nodes.iter().find(|n| &n.id == pkg_id).unwrap();
-    node.deps.iter().map(|dep| pkg_from_id(metadata, &dep.pkg)).collect()
+    node.deps.iter().map(|dep| pkg_from_id(metadata, &dep.pkg))
 }
 
-fn check_rustfix(metadata: &Metadata, bad: &mut bool) {
-    let cargo = pkg_from_name(metadata, "cargo");
-    let compiletest = pkg_from_name(metadata, "compiletest");
-    let cargo_deps = direct_deps_of(metadata, &cargo.id);
-    let compiletest_deps = direct_deps_of(metadata, &compiletest.id);
-    let cargo_rustfix = cargo_deps.iter().find(|p| p.name == "rustfix").unwrap();
-    let compiletest_rustfix = compiletest_deps.iter().find(|p| p.name == "rustfix").unwrap();
+fn check_rustfix(rust_metadata: &Metadata, cargo_metadata: &Metadata, bad: &mut bool) {
+    let cargo = pkg_from_name(cargo_metadata, "cargo");
+    let cargo_rustfix =
+        direct_deps_of(cargo_metadata, &cargo.id).find(|p| p.name == "rustfix").unwrap();
+
+    let compiletest = pkg_from_name(rust_metadata, "compiletest");
+    let compiletest_rustfix =
+        direct_deps_of(rust_metadata, &compiletest.id).find(|p| p.name == "rustfix").unwrap();
+
     if cargo_rustfix.version != compiletest_rustfix.version {
         tidy_error!(
             bad,
diff --git a/tests/codegen-units/item-collection/cross-crate-trait-method.rs b/tests/codegen-units/item-collection/cross-crate-trait-method.rs
index dc0984c8a98..b7216a14318 100644
--- a/tests/codegen-units/item-collection/cross-crate-trait-method.rs
+++ b/tests/codegen-units/item-collection/cross-crate-trait-method.rs
@@ -1,4 +1,4 @@
-// compile-flags:-Zprint-mono-items=eager
+// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no
 
 #![deny(dead_code)]
 #![feature(start)]
diff --git a/tests/codegen-units/item-collection/function-as-argument.rs b/tests/codegen-units/item-collection/function-as-argument.rs
index ea500c3111a..d951cbfacec 100644
--- a/tests/codegen-units/item-collection/function-as-argument.rs
+++ b/tests/codegen-units/item-collection/function-as-argument.rs
@@ -1,5 +1,4 @@
-//
-// compile-flags:-Zprint-mono-items=eager
+// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no
 
 #![deny(dead_code)]
 #![feature(start)]
diff --git a/tests/codegen-units/item-collection/generic-functions.rs b/tests/codegen-units/item-collection/generic-functions.rs
index 04383bb8edb..f790cd0dadd 100644
--- a/tests/codegen-units/item-collection/generic-functions.rs
+++ b/tests/codegen-units/item-collection/generic-functions.rs
@@ -1,4 +1,4 @@
-// compile-flags:-Zprint-mono-items=eager
+// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no
 
 #![deny(dead_code)]
 #![feature(start)]
diff --git a/tests/codegen-units/item-collection/generic-impl.rs b/tests/codegen-units/item-collection/generic-impl.rs
index 4260230c2c6..e19eec36b31 100644
--- a/tests/codegen-units/item-collection/generic-impl.rs
+++ b/tests/codegen-units/item-collection/generic-impl.rs
@@ -1,4 +1,4 @@
-// compile-flags:-Zprint-mono-items=eager
+// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no
 
 #![deny(dead_code)]
 #![feature(start)]
diff --git a/tests/codegen-units/item-collection/trait-implementations.rs b/tests/codegen-units/item-collection/trait-implementations.rs
index a816cb03241..ad0ed7da28e 100644
--- a/tests/codegen-units/item-collection/trait-implementations.rs
+++ b/tests/codegen-units/item-collection/trait-implementations.rs
@@ -1,4 +1,4 @@
-// compile-flags:-Zprint-mono-items=eager
+// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no
 
 #![deny(dead_code)]
 #![feature(start)]
diff --git a/tests/codegen-units/item-collection/trait-method-as-argument.rs b/tests/codegen-units/item-collection/trait-method-as-argument.rs
index 235569728a2..164ef794ca7 100644
--- a/tests/codegen-units/item-collection/trait-method-as-argument.rs
+++ b/tests/codegen-units/item-collection/trait-method-as-argument.rs
@@ -1,5 +1,4 @@
-//
-// compile-flags:-Zprint-mono-items=eager
+// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no
 
 #![deny(dead_code)]
 #![feature(start)]
diff --git a/tests/codegen-units/item-collection/trait-method-default-impl.rs b/tests/codegen-units/item-collection/trait-method-default-impl.rs
index bfcdb6fa142..d953582cce9 100644
--- a/tests/codegen-units/item-collection/trait-method-default-impl.rs
+++ b/tests/codegen-units/item-collection/trait-method-default-impl.rs
@@ -1,4 +1,4 @@
-// compile-flags:-Zprint-mono-items=eager -Zpolymorphize=on
+// compile-flags:-Zprint-mono-items=eager -Zpolymorphize=on -Zinline-mir=no
 
 #![deny(dead_code)]
 #![feature(start)]
diff --git a/tests/codegen/align-fn.rs b/tests/codegen/align-fn.rs
index c5886cf2808..f3cf614e185 100644
--- a/tests/codegen/align-fn.rs
+++ b/tests/codegen/align-fn.rs
@@ -7,3 +7,43 @@
 #[no_mangle]
 #[repr(align(16))]
 pub fn fn_align() {}
+
+pub struct A;
+
+impl A {
+    // CHECK: align 16
+    #[no_mangle]
+    #[repr(align(16))]
+    pub fn method_align(self) {}
+
+    // CHECK: align 16
+    #[no_mangle]
+    #[repr(align(16))]
+    pub fn associated_fn() {}
+}
+
+trait T: Sized {
+    fn trait_fn() {}
+
+    // CHECK: align 32
+    #[repr(align(32))]
+    fn trait_method(self) {}
+}
+
+impl T for A {
+    // CHECK: align 16
+    #[no_mangle]
+    #[repr(align(16))]
+    fn trait_fn() {}
+
+    // CHECK: align 16
+    #[no_mangle]
+    #[repr(align(16))]
+    fn trait_method(self) {}
+}
+
+impl T for () {}
+
+pub fn foo() {
+    ().trait_method();
+}
diff --git a/tests/codegen/array-map.rs b/tests/codegen/array-map.rs
index 7b8ab2c79a7..3706ddf99fd 100644
--- a/tests/codegen/array-map.rs
+++ b/tests/codegen/array-map.rs
@@ -21,7 +21,7 @@ pub fn short_integer_map(x: [u32; 8]) -> [u32; 8] {
 pub fn short_integer_zip_map(x: [u32; 8], y: [u32; 8]) -> [u32; 8] {
     // CHECK: %[[A:.+]] = load <8 x i32>
     // CHECK: %[[B:.+]] = load <8 x i32>
-    // CHECK: sub <8 x i32> %[[A]], %[[B]]
+    // CHECK: sub <8 x i32> %[[B]], %[[A]]
     // CHECK: store <8 x i32>
     x.zip(y).map(|(x, y)| x - y)
 }
diff --git a/tests/codegen/inline-hint.rs b/tests/codegen/inline-hint.rs
index d3ea1915a8b..bb2a8e6a649 100644
--- a/tests/codegen/inline-hint.rs
+++ b/tests/codegen/inline-hint.rs
@@ -1,7 +1,7 @@
 // Checks that closures, constructors, and shims except
 // for a drop glue receive inline hint by default.
 //
-// compile-flags: -Cno-prepopulate-passes -Csymbol-mangling-version=v0
+// compile-flags: -Cno-prepopulate-passes -Csymbol-mangling-version=v0 -Zinline-mir=no
 #![crate_type = "lib"]
 
 pub fn f() {
diff --git a/tests/codegen/local-generics-in-exe-internalized.rs b/tests/codegen/local-generics-in-exe-internalized.rs
index e5430fbf17a..449c5ca75fc 100644
--- a/tests/codegen/local-generics-in-exe-internalized.rs
+++ b/tests/codegen/local-generics-in-exe-internalized.rs
@@ -1,4 +1,4 @@
-// compile-flags: -C no-prepopulate-passes -Zshare-generics=yes
+// compile-flags: -C no-prepopulate-passes -Zshare-generics=yes -Zinline-mir=no
 
 // Check that local generics are internalized if they are in the same CGU
 
diff --git a/tests/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs b/tests/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs
index 59092dbf637..15bd0f17421 100644
--- a/tests/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs
+++ b/tests/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs
@@ -3,4 +3,6 @@
 
 #![crate_type = "lib"]
 
-pub fn foo<T>() {}
+pub fn foo<T: Default>() -> T {
+    T::default()
+}
diff --git a/tests/codegen/remap_path_prefix/xcrate-generic.rs b/tests/codegen/remap_path_prefix/xcrate-generic.rs
index 7a9d2ca9b6b..399deec1fc9 100644
--- a/tests/codegen/remap_path_prefix/xcrate-generic.rs
+++ b/tests/codegen/remap_path_prefix/xcrate-generic.rs
@@ -7,7 +7,7 @@
 extern crate xcrate_generic;
 
 pub fn foo() {
-    xcrate_generic::foo::<u32>();
+    println!("{}", xcrate_generic::foo::<u32>());
 }
 
 // Here we check that local debuginfo is mapped correctly.
diff --git a/tests/codegen/thread-local.rs b/tests/codegen/thread-local.rs
index aa7fab7fb17..caf0366d2c1 100644
--- a/tests/codegen/thread-local.rs
+++ b/tests/codegen/thread-local.rs
@@ -20,8 +20,8 @@ thread_local!(static A: Cell<u32> = const { Cell::new(1) });
 // CHECK-LABEL: @get
 #[no_mangle]
 fn get() -> u32 {
-    // CHECK: %0 = load i32, {{.*}}[[TLS]]{{.*}}
-    // CHECK-NEXT: ret i32 %0
+    // CHECK: [[RET_0:%.+]] = load i32, {{.*}}[[TLS]]{{.*}}
+    // CHECK-NEXT: ret i32 [[RET_0]]
     A.with(|a| a.get())
 }
 
@@ -36,8 +36,8 @@ fn set(v: u32) {
 // CHECK-LABEL: @get_aux
 #[no_mangle]
 fn get_aux() -> u64 {
-    // CHECK: %0 = load i64, {{.*}}[[TLS_AUX]]
-    // CHECK-NEXT: ret i64 %0
+    // CHECK: [[RET_1:%.+]] = load i64, {{.*}}[[TLS_AUX]]
+    // CHECK-NEXT: ret i64 [[RET_1]]
     aux::A.with(|a| a.get())
 }
 
diff --git a/tests/run-make/issue-107094/Makefile b/tests/run-make/issue-107094/Makefile
new file mode 100644
index 00000000000..d614e3e1055
--- /dev/null
+++ b/tests/run-make/issue-107094/Makefile
@@ -0,0 +1,7 @@
+# needs-git-hash
+
+include ../tools.mk
+
+all:
+	$(BARE_RUSTC) --version --verbose | $(CGREP) -i -e "commit-hash: [0-9a-f]{40}" "commit-date: [0-9]{4}-[0-9]{2}-[0-9]{2}"
+	$(BARE_RUSTDOC) --version --verbose | $(CGREP) -i -e "commit-hash: [0-9a-f]{40}" "commit-date: [0-9]{4}-[0-9]{2}-[0-9]{2}"
diff --git a/tests/ui/attributes/invalid-repr.rs b/tests/ui/attributes/invalid-repr.rs
new file mode 100644
index 00000000000..10a487c127e
--- /dev/null
+++ b/tests/ui/attributes/invalid-repr.rs
@@ -0,0 +1,5 @@
+#[repr(align(16))]
+//~^ ERROR attribute should be applied to a struct, enum, function, associated function, or union
+pub type Foo = i32;
+
+fn main() {}
diff --git a/tests/ui/attributes/invalid-repr.stderr b/tests/ui/attributes/invalid-repr.stderr
new file mode 100644
index 00000000000..98a6a24b3c4
--- /dev/null
+++ b/tests/ui/attributes/invalid-repr.stderr
@@ -0,0 +1,12 @@
+error[E0517]: attribute should be applied to a struct, enum, function, associated function, or union
+  --> $DIR/invalid-repr.rs:1:8
+   |
+LL | #[repr(align(16))]
+   |        ^^^^^^^^^
+LL |
+LL | pub type Foo = i32;
+   | ------------------- not a struct, enum, function, associated function, or union
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0517`.
diff --git a/tests/ui/codegen/freeze-on-polymorphic-projection.rs b/tests/ui/codegen/freeze-on-polymorphic-projection.rs
new file mode 100644
index 00000000000..edc79f8fd94
--- /dev/null
+++ b/tests/ui/codegen/freeze-on-polymorphic-projection.rs
@@ -0,0 +1,19 @@
+// build-pass
+// compile-flags: -Copt-level=1 --crate-type=lib
+
+#![feature(specialization)]
+//~^ WARN the feature `specialization` is incomplete
+
+pub unsafe trait Storage {
+    type Handle;
+}
+
+pub unsafe trait MultipleStorage: Storage {}
+
+default unsafe impl<S> Storage for S where S: MultipleStorage {}
+
+// Make sure that we call is_freeze on `(S::Handle,)` in the param-env of `ice`,
+// instead of in an empty, reveal-all param-env.
+pub fn ice<S: Storage>(boxed: (S::Handle,)) -> (S::Handle,) {
+    boxed
+}
diff --git a/tests/ui/codegen/freeze-on-polymorphic-projection.stderr b/tests/ui/codegen/freeze-on-polymorphic-projection.stderr
new file mode 100644
index 00000000000..903cb2ff6aa
--- /dev/null
+++ b/tests/ui/codegen/freeze-on-polymorphic-projection.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/freeze-on-polymorphic-projection.rs:4:12
+   |
+LL | #![feature(specialization)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+   = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
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
new file mode 100644
index 00000000000..85b0c6c9df8
--- /dev/null
+++ b/tests/ui/consts/auxiliary/foreign-generic-mismatch-with-const-arg.rs
@@ -0,0 +1 @@
+pub fn test<const N: usize, T>() {}
diff --git a/tests/ui/consts/foreign-generic-mismatch-with-const-arg.rs b/tests/ui/consts/foreign-generic-mismatch-with-const-arg.rs
new file mode 100644
index 00000000000..7590abbd827
--- /dev/null
+++ b/tests/ui/consts/foreign-generic-mismatch-with-const-arg.rs
@@ -0,0 +1,8 @@
+// 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
new file mode 100644
index 00000000000..4cc03a20514
--- /dev/null
+++ b/tests/ui/consts/foreign-generic-mismatch-with-const-arg.stderr
@@ -0,0 +1,21 @@
+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/lint/unused/issue-54538-unused-parens-lint.fixed b/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed
index 71ebaea8ed2..9c52ca5577e 100644
--- a/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed
+++ b/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed
@@ -21,17 +21,32 @@ fn lint_on_top_level() {
     let _ = |a: u8| 0; //~ ERROR unnecessary parentheses around pattern
 }
 
-fn _no_lint_attr() {
+fn no_lint_attr() {
     let _x = #[allow(dead_code)] (1 + 2);
 }
 
-fn _no_lint_yeet() -> Result<(), ()> {
+fn no_lint_yeet() -> Result<(), ()> {
     #[allow(unreachable_code)]
     if (do yeet) {}
 
     Ok(())
 }
 
+fn no_lint_ops() {
+    #![allow(unreachable_code, irrefutable_let_patterns)]
+    if ((..{}) == ..{}) {}
+    if (!return) {}
+    loop { match (() = () = () = break {}) {} }
+    while let () = (*&mut false |= true && return) {}
+}
+
+fn lint_break_if_not_followed_by_block() {
+    #![allow(unreachable_code)]
+    loop { if break {} } //~ ERROR unnecessary parentheses
+    loop { if break ({ println!("hello") }) {} } //~ ERROR unnecessary parentheses
+    loop { if (break { println!("hello") }) {} }
+}
+
 // Don't lint in these cases (#64106).
 fn or_patterns_no_lint() {
     match Box::new(0) {
diff --git a/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs b/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs
index 28b662dd024..196ecf0c1bb 100644
--- a/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs
+++ b/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs
@@ -21,17 +21,32 @@ fn lint_on_top_level() {
     let _ = |(a): u8| 0; //~ ERROR unnecessary parentheses around pattern
 }
 
-fn _no_lint_attr() {
+fn no_lint_attr() {
     let _x = #[allow(dead_code)] (1 + 2);
 }
 
-fn _no_lint_yeet() -> Result<(), ()> {
+fn no_lint_yeet() -> Result<(), ()> {
     #[allow(unreachable_code)]
     if (do yeet) {}
 
     Ok(())
 }
 
+fn no_lint_ops() {
+    #![allow(unreachable_code, irrefutable_let_patterns)]
+    if ((..{}) == ..{}) {}
+    if (!return) {}
+    loop { match (() = () = () = break {}) {} }
+    while let () = (*&mut false |= true && return) {}
+}
+
+fn lint_break_if_not_followed_by_block() {
+    #![allow(unreachable_code)]
+    loop { if (break) {} } //~ ERROR unnecessary parentheses
+    loop { if (break ({ println!("hello") })) {} } //~ ERROR unnecessary parentheses
+    loop { if (break { println!("hello") }) {} }
+}
+
 // Don't lint in these cases (#64106).
 fn or_patterns_no_lint() {
     match Box::new(0) {
diff --git a/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr b/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr
index a5e69e6d938..f916bba8194 100644
--- a/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr
+++ b/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr
@@ -75,8 +75,32 @@ LL -     let _ = |(a): u8| 0;
 LL +     let _ = |a: u8| 0;
    |
 
+error: unnecessary parentheses around `if` condition
+  --> $DIR/issue-54538-unused-parens-lint.rs:45:15
+   |
+LL |     loop { if (break) {} }
+   |               ^     ^
+   |
+help: remove these parentheses
+   |
+LL -     loop { if (break) {} }
+LL +     loop { if break {} }
+   |
+
+error: unnecessary parentheses around `if` condition
+  --> $DIR/issue-54538-unused-parens-lint.rs:46:15
+   |
+LL |     loop { if (break ({ println!("hello") })) {} }
+   |               ^                             ^
+   |
+help: remove these parentheses
+   |
+LL -     loop { if (break ({ println!("hello") })) {} }
+LL +     loop { if break ({ println!("hello") }) {} }
+   |
+
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:56:12
+  --> $DIR/issue-54538-unused-parens-lint.rs:71:12
    |
 LL |     if let (0 | 1) = 0 {}
    |            ^     ^
@@ -88,7 +112,7 @@ LL +     if let 0 | 1 = 0 {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:57:13
+  --> $DIR/issue-54538-unused-parens-lint.rs:72:13
    |
 LL |     if let ((0 | 1),) = (0,) {}
    |             ^     ^
@@ -100,7 +124,7 @@ LL +     if let (0 | 1,) = (0,) {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:58:13
+  --> $DIR/issue-54538-unused-parens-lint.rs:73:13
    |
 LL |     if let [(0 | 1)] = [0] {}
    |             ^     ^
@@ -112,7 +136,7 @@ LL +     if let [0 | 1] = [0] {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:59:16
+  --> $DIR/issue-54538-unused-parens-lint.rs:74:16
    |
 LL |     if let 0 | (1 | 2) = 0 {}
    |                ^     ^
@@ -124,7 +148,7 @@ LL +     if let 0 | 1 | 2 = 0 {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:61:15
+  --> $DIR/issue-54538-unused-parens-lint.rs:76:15
    |
 LL |     if let TS((0 | 1)) = TS(0) {}
    |               ^     ^
@@ -136,7 +160,7 @@ LL +     if let TS(0 | 1) = TS(0) {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:63:20
+  --> $DIR/issue-54538-unused-parens-lint.rs:78:20
    |
 LL |     if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
    |                    ^     ^
@@ -148,7 +172,7 @@ LL +     if let NS { f: 0 | 1 } = (NS { f: 0 }) {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:73:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:88:9
    |
 LL |         (_) => {}
    |         ^ ^
@@ -160,7 +184,7 @@ LL +         _ => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:74:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:89:9
    |
 LL |         (y) => {}
    |         ^ ^
@@ -172,7 +196,7 @@ LL +         y => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:75:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:90:9
    |
 LL |         (ref r) => {}
    |         ^     ^
@@ -184,7 +208,7 @@ LL +         ref r => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:76:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:91:9
    |
 LL |         (e @ 1...2) => {}
    |         ^         ^
@@ -196,7 +220,7 @@ LL +         e @ 1...2 => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:82:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:97:9
    |
 LL |         (e @ &(1...2)) => {}
    |         ^            ^
@@ -208,7 +232,7 @@ LL +         e @ &(1...2) => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:83:10
+  --> $DIR/issue-54538-unused-parens-lint.rs:98:10
    |
 LL |         &(_) => {}
    |          ^ ^
@@ -220,7 +244,7 @@ LL +         &_ => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:94:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:109:9
    |
 LL |         (_) => {}
    |         ^ ^
@@ -232,7 +256,7 @@ LL +         _ => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:95:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:110:9
    |
 LL |         (y) => {}
    |         ^ ^
@@ -244,7 +268,7 @@ LL +         y => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:96:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:111:9
    |
 LL |         (ref r) => {}
    |         ^     ^
@@ -256,7 +280,7 @@ LL +         ref r => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:97:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:112:9
    |
 LL |         (e @ 1..=2) => {}
    |         ^         ^
@@ -268,7 +292,7 @@ LL +         e @ 1..=2 => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:103:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:118:9
    |
 LL |         (e @ &(1..=2)) => {}
    |         ^            ^
@@ -280,7 +304,7 @@ LL +         e @ &(1..=2) => {}
    |
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:104:10
+  --> $DIR/issue-54538-unused-parens-lint.rs:119:10
    |
 LL |         &(_) => {}
    |          ^ ^
@@ -291,5 +315,5 @@ LL -         &(_) => {}
 LL +         &_ => {}
    |
 
-error: aborting due to 24 previous errors
+error: aborting due to 26 previous errors
 
diff --git a/tests/ui/rfc-2632-const-trait-impl/trait-method-ptr-in-consts-ice.rs b/tests/ui/rfc-2632-const-trait-impl/trait-method-ptr-in-consts-ice.rs
new file mode 100644
index 00000000000..7d7cb967c66
--- /dev/null
+++ b/tests/ui/rfc-2632-const-trait-impl/trait-method-ptr-in-consts-ice.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+struct LazyLock<T> {
+    data: (Option<T>, fn() -> T),
+}
+
+impl<T> LazyLock<T> {
+    pub const fn new(f: fn() -> T) -> LazyLock<T> {
+        LazyLock { data: (None, f) }
+    }
+}
+
+struct A<T = i32>(Option<T>);
+
+impl<T> Default for A<T> {
+    fn default() -> Self {
+        A(None)
+    }
+}
+
+static EMPTY_SET: LazyLock<A<i32>> = LazyLock::new(A::default);
+
+fn main() {}
diff --git a/tests/ui/transmutability/references.current.stderr b/tests/ui/transmutability/references.current.stderr
index ecb095354a5..819c9b92bc8 100644
--- a/tests/ui/transmutability/references.current.stderr
+++ b/tests/ui/transmutability/references.current.stderr
@@ -1,8 +1,8 @@
-error[E0277]: `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`
+error[E0277]: `&Unit` cannot be safely transmuted into `&Unit` in the defining scope of `assert::Context`
   --> $DIR/references.rs:29:52
    |
 LL |     assert::is_maybe_transmutable::<&'static Unit, &'static Unit>();
-   |                                                    ^^^^^^^^^^^^^ `&'static Unit` does not have a well-specified layout
+   |                                                    ^^^^^^^^^^^^^ `&Unit` does not have a well-specified layout
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/references.rs:16:14
diff --git a/tests/ui/transmutability/references.next.stderr b/tests/ui/transmutability/references.next.stderr
index ecb095354a5..819c9b92bc8 100644
--- a/tests/ui/transmutability/references.next.stderr
+++ b/tests/ui/transmutability/references.next.stderr
@@ -1,8 +1,8 @@
-error[E0277]: `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`
+error[E0277]: `&Unit` cannot be safely transmuted into `&Unit` in the defining scope of `assert::Context`
   --> $DIR/references.rs:29:52
    |
 LL |     assert::is_maybe_transmutable::<&'static Unit, &'static Unit>();
-   |                                                    ^^^^^^^^^^^^^ `&'static Unit` does not have a well-specified layout
+   |                                                    ^^^^^^^^^^^^^ `&Unit` does not have a well-specified layout
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/references.rs:16:14
diff --git a/tests/ui/transmutability/region-infer.rs b/tests/ui/transmutability/region-infer.rs
new file mode 100644
index 00000000000..09f60277688
--- /dev/null
+++ b/tests/ui/transmutability/region-infer.rs
@@ -0,0 +1,22 @@
+#![feature(transmutability)]
+
+use std::mem::{Assume, BikeshedIntrinsicFrom};
+pub struct Context;
+
+#[repr(C)]
+struct W<'a>(&'a ());
+
+fn test<'a>()
+where
+    W<'a>: BikeshedIntrinsicFrom<
+            (),
+            Context,
+            { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
+        >,
+{
+}
+
+fn main() {
+    test();
+    //~^ ERROR `()` cannot be safely transmuted into `W<'_>`
+}
diff --git a/tests/ui/transmutability/region-infer.stderr b/tests/ui/transmutability/region-infer.stderr
new file mode 100644
index 00000000000..d6b65e9e4a0
--- /dev/null
+++ b/tests/ui/transmutability/region-infer.stderr
@@ -0,0 +1,23 @@
+error[E0277]: `()` cannot be safely transmuted into `W<'_>` in the defining scope of `Context`
+  --> $DIR/region-infer.rs:20:5
+   |
+LL |     test();
+   |     ^^^^ `W<'_>` does not have a well-specified layout
+   |
+note: required by a bound in `test`
+  --> $DIR/region-infer.rs:11:12
+   |
+LL |   fn test<'a>()
+   |      ---- required by a bound in this function
+LL |   where
+LL |       W<'a>: BikeshedIntrinsicFrom<
+   |  ____________^
+LL | |             (),
+LL | |             Context,
+LL | |             { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
+LL | |         >,
+   | |_________^ required by this bound in `test`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.