about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock179
-rw-r--r--Cargo.toml4
-rw-r--r--compiler/rustc_ast_lowering/src/delegation.rs84
-rw-r--r--compiler/rustc_ast_passes/messages.ftl6
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs30
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs15
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/archive.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/archive.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs109
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs4
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs25
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs37
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs4
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/mod.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/mod.rs)45
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/different_lifetimes.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs)11
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/find_anon_type.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs)0
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs)4
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/mod.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs)6
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs)8
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/placeholder_error.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs)4
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/placeholder_relation.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs)9
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/static_impl_trait.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs)4
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs)4
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/nice_region_error/util.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs)6
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/note.rs421
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/note_and_explain.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs)0
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/region.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/region.rs)2
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/sub_relations.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/sub_relations.rs)0
-rw-r--r--compiler/rustc_infer/src/error_reporting/infer/suggest.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/suggest.rs)2
-rw-r--r--compiler/rustc_infer/src/error_reporting/mod.rs1
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs7
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs5
-rw-r--r--compiler/rustc_infer/src/infer/need_type_info.rs (renamed from compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs)2
-rw-r--r--compiler/rustc_infer/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp136
-rw-r--r--compiler/rustc_parse/messages.ftl6
-rw-r--r--compiler/rustc_parse/src/errors.rs15
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs13
-rw-r--r--compiler/rustc_parse/src/parser/nonterminal.rs7
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs8
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs6
-rw-r--r--compiler/rustc_pattern_analysis/src/lib.rs4
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs6
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs1
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs3
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs4
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs2
-rw-r--r--library/alloc/src/testing/crash_test.rs3
-rw-r--r--library/core/src/char/mod.rs6
-rw-r--r--library/core/src/ffi/c_str.rs17
-rw-r--r--library/core/src/num/dec2flt/mod.rs6
-rw-r--r--library/core/src/prelude/common.rs8
-rw-r--r--library/core/src/prelude/mod.rs3
-rw-r--r--library/core/src/ptr/mod.rs5
-rw-r--r--library/core/src/unicode/mod.rs26
-rw-r--r--library/std/src/env.rs14
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/os/fortanix_sgx/mod.rs1
-rw-r--r--library/std/src/os/uefi/mod.rs1
-rw-r--r--library/std/src/os/xous/mod.rs1
-rw-r--r--library/std/src/prelude/common.rs3
-rw-r--r--library/std/src/prelude/mod.rs3
-rw-r--r--library/std/src/rt.rs1
-rw-r--r--library/std/src/sys/pal/hermit/futex.rs5
-rw-r--r--library/std/src/sys/pal/uefi/mod.rs1
-rw-r--r--library/std/src/sys/pal/unix/futex.rs5
-rw-r--r--library/std/src/sys/pal/wasi/mod.rs9
-rw-r--r--library/std/src/sys/pal/wasip2/mod.rs9
-rw-r--r--library/std/src/sys/pal/wasm/atomics/futex.rs5
-rw-r--r--library/std/src/sys/pal/windows/futex.rs5
-rw-r--r--library/std/src/sys/pal/xous/mod.rs2
-rw-r--r--library/std/src/sys/pal/zkvm/alloc.rs2
-rw-r--r--library/std/src/sys/pal/zkvm/mod.rs1
-rw-r--r--library/std/src/sys/personality/dwarf/mod.rs26
-rw-r--r--library/std/src/sys/sync/mutex/futex.rs21
-rw-r--r--library/std/src/sys/sync/thread_parking/futex.rs17
-rw-r--r--library/std/src/sys/sync/thread_parking/mod.rs7
-rw-r--r--library/std/src/sys/sync/thread_parking/windows7.rs (renamed from library/std/src/sys/sync/thread_parking/windows.rs)0
-rw-r--r--library/test/src/lib.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs15
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs1
-rw-r--r--src/ci/docker/host-x86_64/dist-various-2/Dockerfile1
-rw-r--r--src/tools/clippy/tests/ui/track-diagnostics.stderr2
-rw-r--r--src/tools/run-make-support/Cargo.toml2
-rw-r--r--src/tools/run-make-support/src/cc.rs11
-rw-r--r--src/tools/run-make-support/src/lib.rs37
-rw-r--r--src/tools/run-make-support/src/llvm.rs37
-rw-r--r--src/tools/run-make-support/src/rustc.rs13
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt5
-rw-r--r--src/tools/tidy/src/deps.rs5
-rw-r--r--src/tools/wasm-component-ld/Cargo.toml13
-rw-r--r--src/tools/wasm-component-ld/README.md62
-rw-r--r--src/tools/wasm-component-ld/src/main.rs9
-rw-r--r--tests/run-make/compiler-lookup-paths/Makefile44
-rw-r--r--tests/run-make/compiler-lookup-paths/rmake.rs84
-rw-r--r--tests/run-make/dump-mono-stats/Makefile5
-rw-r--r--tests/run-make/dump-mono-stats/rmake.rs17
-rw-r--r--tests/run-make/invalid-library/rmake.rs10
-rw-r--r--tests/run-make/link-arg/rmake.rs1
-rw-r--r--tests/run-make/prune-link-args/Makefile10
-rw-r--r--tests/run-make/prune-link-args/rmake.rs17
-rw-r--r--tests/run-make/raw-dylib-custom-dlltool/Makefile11
-rw-r--r--tests/run-make/raw-dylib-custom-dlltool/rmake.rs24
-rw-r--r--tests/run-make/raw-dylib-custom-dlltool/script.cmd2
-rw-r--r--tests/run-make/raw-dylib-inline-cross-dylib/Makefile30
-rw-r--r--tests/run-make/raw-dylib-inline-cross-dylib/rmake.rs61
-rw-r--r--tests/rustdoc-ui/track-diagnostics.stderr2
-rw-r--r--tests/ui/delegation/bad-resolve.rs3
-rw-r--r--tests/ui/delegation/bad-resolve.stderr24
-rw-r--r--tests/ui/delegation/explicit-paths-pass.rs4
-rw-r--r--tests/ui/delegation/explicit-paths.rs4
-rw-r--r--tests/ui/delegation/explicit-paths.stderr9
-rw-r--r--tests/ui/delegation/ice-issue-122550.stderr25
-rw-r--r--tests/ui/delegation/method-call-choice.rs25
-rw-r--r--tests/ui/delegation/method-call-choice.stderr21
-rw-r--r--tests/ui/delegation/method-call-priority.rs34
-rw-r--r--tests/ui/delegation/self-coercion.rs26
-rw-r--r--tests/ui/parser/cfg-keyword-lifetime.rs15
-rw-r--r--tests/ui/parser/cfg-keyword-lifetime.stderr14
-rw-r--r--tests/ui/parser/require-parens-for-chained-comparison.rs2
-rw-r--r--tests/ui/parser/require-parens-for-chained-comparison.stderr20
-rw-r--r--tests/ui/self/self_type_keyword.stderr12
137 files changed, 1762 insertions, 527 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 68478d55e23..2d3bc59dddb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -229,18 +229,12 @@ dependencies = [
 ]
 
 [[package]]
-name = "ar"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69"
-
-[[package]]
 name = "ar_archive_writer"
-version = "0.2.0"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a"
+checksum = "f8412a2d690663356cba5a2532f3ed55d1e8090743bc6695b88403b27df67733"
 dependencies = [
- "object 0.32.2",
+ "object 0.35.0",
 ]
 
 [[package]]
@@ -1682,6 +1676,7 @@ dependencies = [
  "compiler_builtins",
  "rustc-std-workspace-alloc",
  "rustc-std-workspace-core",
+ "serde",
 ]
 
 [[package]]
@@ -1892,6 +1887,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "id-arena"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
+
+[[package]]
 name = "ident_case"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2121,6 +2122,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760"
 
 [[package]]
+name = "lexopt"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401"
+
+[[package]]
 name = "libc"
 version = "0.2.155"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2634,7 +2641,7 @@ dependencies = [
  "indexmap",
  "memchr",
  "ruzstd 0.5.0",
- "wasmparser",
+ "wasmparser 0.118.2",
 ]
 
 [[package]]
@@ -2650,6 +2657,15 @@ dependencies = [
 
 [[package]]
 name = "object"
+version = "0.35.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "object"
 version = "0.36.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434"
@@ -3429,14 +3445,13 @@ dependencies = [
 name = "run_make_support"
 version = "0.2.0"
 dependencies = [
- "ar",
  "bstr",
  "build_helper",
  "gimli 0.31.0",
  "object 0.34.0",
  "regex",
  "similar",
- "wasmparser",
+ "wasmparser 0.118.2",
 ]
 
 [[package]]
@@ -3823,7 +3838,7 @@ dependencies = [
  "thin-vec",
  "thorin-dwp",
  "tracing",
- "wasm-encoder",
+ "wasm-encoder 0.200.0",
  "windows",
 ]
 
@@ -5268,6 +5283,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "spdx"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47317bbaf63785b53861e1ae2d11b80d6b624211d42cb20efcd210ee6f8a14bc"
+dependencies = [
+ "smallvec",
+]
+
+[[package]]
 name = "spdx-expression"
 version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6316,6 +6340,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
 
 [[package]]
+name = "wasm-component-ld"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "314d932d5e84c9678751b85498b1482b2f32f185744e449d3ce0b1d400376dad"
+dependencies = [
+ "anyhow",
+ "clap",
+ "lexopt",
+ "tempfile",
+ "wasmparser 0.210.0",
+ "wat",
+ "wit-component",
+]
+
+[[package]]
+name = "wasm-component-ld-wrapper"
+version = "0.1.0"
+dependencies = [
+ "wasm-component-ld",
+]
+
+[[package]]
 name = "wasm-encoder"
 version = "0.200.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6325,6 +6371,40 @@ dependencies = [
 ]
 
 [[package]]
+name = "wasm-encoder"
+version = "0.210.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7e3764d9d6edabd8c9e16195e177be0d20f6ab942ad18af52860f12f82bc59a"
+dependencies = [
+ "leb128",
+]
+
+[[package]]
+name = "wasm-encoder"
+version = "0.211.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e7d931a1120ef357f32b74547646b6fa68ea25e377772b72874b131a9ed70d4"
+dependencies = [
+ "leb128",
+]
+
+[[package]]
+name = "wasm-metadata"
+version = "0.210.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "012729d1294907fcb0866f08460ab95426a6d0b176a599619b84cac7653452b4"
+dependencies = [
+ "anyhow",
+ "indexmap",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "spdx",
+ "wasm-encoder 0.210.0",
+ "wasmparser 0.210.0",
+]
+
+[[package]]
 name = "wasmparser"
 version = "0.118.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6335,6 +6415,42 @@ dependencies = [
 ]
 
 [[package]]
+name = "wasmparser"
+version = "0.210.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7bbcd21e7581619d9f6ca00f8c4f08f1cacfe58bf63f83af57cd0476f1026f5"
+dependencies = [
+ "ahash",
+ "bitflags 2.5.0",
+ "hashbrown",
+ "indexmap",
+ "semver",
+ "serde",
+]
+
+[[package]]
+name = "wast"
+version = "211.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b25506dd82d00da6b14a87436b3d52b1d264083fa79cdb72a0d1b04a8595ccaa"
+dependencies = [
+ "bumpalo",
+ "leb128",
+ "memchr",
+ "unicode-width",
+ "wasm-encoder 0.211.1",
+]
+
+[[package]]
+name = "wat"
+version = "1.211.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb716ca6c86eecac2d82541ffc39860118fc0af9309c4f2670637bea2e1bdd7d"
+dependencies = [
+ "wast",
+]
+
+[[package]]
 name = "winapi"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6562,6 +6678,43 @@ dependencies = [
 ]
 
 [[package]]
+name = "wit-component"
+version = "0.210.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a450bdb5d032acf1fa0865451fa0c6f50e62f2d31eaa8dba967c2e2d068694a4"
+dependencies = [
+ "anyhow",
+ "bitflags 2.5.0",
+ "indexmap",
+ "log",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "wasm-encoder 0.210.0",
+ "wasm-metadata",
+ "wasmparser 0.210.0",
+ "wit-parser",
+]
+
+[[package]]
+name = "wit-parser"
+version = "0.210.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60a965cbd439af19a4b44a54a97ab8957d86f02d01320efc9e31c1d3605c6710"
+dependencies = [
+ "anyhow",
+ "id-arena",
+ "indexmap",
+ "log",
+ "semver",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "unicode-xid",
+ "wasmparser 0.210.0",
+]
+
+[[package]]
 name = "writeable"
 version = "0.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 93c520b0d68..ce87a8c20b7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -45,6 +45,7 @@ members = [
   "src/tools/opt-dist",
   "src/tools/coverage-dump",
   "src/tools/rustc-perf-wrapper",
+  "src/tools/wasm-component-ld",
 ]
 
 exclude = [
@@ -104,6 +105,9 @@ rustc-demangle.debug = 0
 [profile.release.package.lld-wrapper]
 debug = 0
 strip = true
+[profile.release.package.wasm-component-ld-wrapper]
+debug = 0
+strip = true
 
 [patch.crates-io]
 # See comments in `library/rustc-std-workspace-core/README.md` for what's going on
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs
index 678cac210f4..6df2c15ce60 100644
--- a/compiler/rustc_ast_lowering/src/delegation.rs
+++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -38,7 +38,7 @@
 
 use crate::{ImplTraitPosition, ResolverAstLoweringExt};
 
-use super::{ImplTraitContext, LoweringContext, ParamMode};
+use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
 
 use ast::visit::Visitor;
 use hir::def::{DefKind, PartialRes, Res};
@@ -259,8 +259,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         self_param_id: pat_node_id,
                     };
                     self_resolver.visit_block(block);
-                    let block = this.lower_block(block, false);
-                    this.mk_expr(hir::ExprKind::Block(block, None), block.span)
+                    this.lower_target_expr(&block)
                 } else {
                     let pat_hir_id = this.lower_node_id(pat_node_id);
                     this.generate_arg(pat_hir_id, span)
@@ -273,26 +272,81 @@ impl<'hir> LoweringContext<'_, 'hir> {
         })
     }
 
-    // Generates fully qualified call for the resulting body.
+    // FIXME(fn_delegation): Alternatives for target expression lowering:
+    // https://github.com/rust-lang/rfcs/pull/3530#issuecomment-2197170600.
+    fn lower_target_expr(&mut self, block: &Block) -> hir::Expr<'hir> {
+        if block.stmts.len() == 1
+            && let StmtKind::Expr(expr) = &block.stmts[0].kind
+        {
+            return self.lower_expr_mut(expr);
+        }
+
+        let block = self.lower_block(block, false);
+        self.mk_expr(hir::ExprKind::Block(block, None), block.span)
+    }
+
+    // Generates expression for the resulting body. If possible, `MethodCall` is used
+    // to allow autoref/autoderef for target expression. For example in:
+    //
+    // trait Trait : Sized {
+    //     fn by_value(self) -> i32 { 1 }
+    //     fn by_mut_ref(&mut self) -> i32 { 2 }
+    //     fn by_ref(&self) -> i32 { 3 }
+    // }
+    //
+    // struct NewType(SomeType);
+    // impl Trait for NewType {
+    //     reuse Trait::* { self.0 }
+    // }
+    //
+    // `self.0` will automatically coerce.
     fn finalize_body_lowering(
         &mut self,
         delegation: &Delegation,
         args: Vec<hir::Expr<'hir>>,
         span: Span,
     ) -> hir::Expr<'hir> {
-        let path = self.lower_qpath(
-            delegation.id,
-            &delegation.qself,
-            &delegation.path,
-            ParamMode::Optional,
-            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
-            None,
-        );
-
         let args = self.arena.alloc_from_iter(args);
-        let path_expr = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(path), span));
-        let call = self.arena.alloc(self.mk_expr(hir::ExprKind::Call(path_expr, args), span));
 
+        let has_generic_args =
+            delegation.path.segments.iter().rev().skip(1).any(|segment| segment.args.is_some());
+
+        let call = if self
+            .get_resolution_id(delegation.id, span)
+            .and_then(|def_id| Ok(self.has_self(def_id, span)))
+            .unwrap_or_default()
+            && delegation.qself.is_none()
+            && !has_generic_args
+        {
+            let ast_segment = delegation.path.segments.last().unwrap();
+            let segment = self.lower_path_segment(
+                delegation.path.span,
+                ast_segment,
+                ParamMode::Optional,
+                ParenthesizedGenericArgs::Err,
+                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                None,
+            );
+            let segment = self.arena.alloc(segment);
+
+            self.arena.alloc(hir::Expr {
+                hir_id: self.next_id(),
+                kind: hir::ExprKind::MethodCall(segment, &args[0], &args[1..], span),
+                span,
+            })
+        } else {
+            let path = self.lower_qpath(
+                delegation.id,
+                &delegation.qself,
+                &delegation.path,
+                ParamMode::Optional,
+                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                None,
+            );
+
+            let callee_path = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(path), span));
+            self.arena.alloc(self.mk_expr(hir::ExprKind::Call(callee_path, args), span))
+        };
         let block = self.arena.alloc(hir::Block {
             stmts: &[],
             expr: Some(call),
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index 7da726ef408..02bdff96aa6 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -159,9 +159,6 @@ ast_passes_inherent_cannot_be = inherent impls cannot be {$annotation}
     .type = inherent impl for this type
     .only_trait = only trait implementations may be annotated with {$annotation}
 
-ast_passes_invalid_label =
-    invalid label name `{$name}`
-
 ast_passes_invalid_unnamed_field =
     unnamed fields are not allowed outside of structs or unions
     .label = unnamed field declared here
@@ -176,9 +173,6 @@ ast_passes_item_invalid_safety = items outside of `unsafe extern {"{ }"}` cannot
 ast_passes_item_underscore = `{$kind}` items in this context need a name
     .label = `_` is not a valid name for this `{$kind}` item
 
-ast_passes_keyword_lifetime =
-    lifetimes cannot use keyword names
-
 ast_passes_match_arm_with_no_body =
     `match` arm with no body
     .suggestion = add a body after the pattern
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index e6cc2e4069b..83249dea82a 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -269,19 +269,6 @@ impl<'a> AstValidator<'a> {
         self.session.dcx()
     }
 
-    fn check_lifetime(&self, ident: Ident) {
-        let valid_names = [kw::UnderscoreLifetime, kw::StaticLifetime, kw::Empty];
-        if !valid_names.contains(&ident.name) && ident.without_first_quote().is_reserved() {
-            self.dcx().emit_err(errors::KeywordLifetime { span: ident.span });
-        }
-    }
-
-    fn check_label(&self, ident: Ident) {
-        if ident.without_first_quote().is_reserved() {
-            self.dcx().emit_err(errors::InvalidLabel { span: ident.span, name: ident.name });
-        }
-    }
-
     fn visibility_not_permitted(&self, vis: &Visibility, note: errors::VisibilityNotPermittedNote) {
         if let VisibilityKind::Inherited = vis.kind {
             return;
@@ -908,16 +895,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         self.walk_ty(ty)
     }
 
-    fn visit_label(&mut self, label: &'a Label) {
-        self.check_label(label.ident);
-        visit::walk_label(self, label);
-    }
-
-    fn visit_lifetime(&mut self, lifetime: &'a Lifetime, _: visit::LifetimeCtxt) {
-        self.check_lifetime(lifetime.ident);
-        visit::walk_lifetime(self, lifetime);
-    }
-
     fn visit_field_def(&mut self, field: &'a FieldDef) {
         self.deny_unnamed_field(field);
         visit::walk_field_def(self, field)
@@ -1356,13 +1333,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         }
     }
 
-    fn visit_generic_param(&mut self, param: &'a GenericParam) {
-        if let GenericParamKind::Lifetime { .. } = param.kind {
-            self.check_lifetime(param.ident);
-        }
-        visit::walk_generic_param(self, param);
-    }
-
     fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
         match bound {
             GenericBound::Trait(trait_ref, modifiers) => {
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 2c18b47f0f7..460da254653 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -10,21 +10,6 @@ use rustc_span::{symbol::Ident, Span, Symbol};
 use crate::fluent_generated as fluent;
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_keyword_lifetime)]
-pub struct KeywordLifetime {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(ast_passes_invalid_label)]
-pub struct InvalidLabel {
-    #[primary_span]
-    pub span: Span,
-    pub name: Symbol,
-}
-
-#[derive(Diagnostic)]
 #[diag(ast_passes_visibility_not_permitted, code = E0449)]
 pub struct VisibilityNotPermitted {
     #[primary_span]
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index 8bf3e670ff2..4cd0d9cb294 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -1,7 +1,7 @@
 use rustc_errors::Diag;
 use rustc_hir::def_id::LocalDefId;
+use rustc_infer::error_reporting::infer::nice_region_error::NiceRegionError;
 use rustc_infer::infer::canonical::Canonical;
-use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
 use rustc_infer::infer::region_constraints::Constraint;
 use rustc_infer::infer::region_constraints::RegionConstraintData;
 use rustc_infer::infer::RegionVariableOrigin;
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 55147ee337f..6cf797b4761 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -10,11 +10,11 @@ use rustc_hir::GenericBound::Trait;
 use rustc_hir::QPath::Resolved;
 use rustc_hir::WherePredicate::BoundPredicate;
 use rustc_hir::{PolyTraitRef, TyKind, WhereBoundPredicate};
-use rustc_infer::infer::error_reporting::nice_region_error::{
+use rustc_infer::error_reporting::infer::nice_region_error::{
     self, find_anon_type, find_param_with_region, suggest_adding_lifetime_params,
     HirTraitObjectVisitor, NiceRegionError, TraitObjectVisitor,
 };
-use rustc_infer::infer::error_reporting::region::unexpected_hidden_region_diagnostic;
+use rustc_infer::error_reporting::infer::region::unexpected_hidden_region_diagnostic;
 use rustc_infer::infer::{NllRegionVariableOrigin, RelateParamBound};
 use rustc_middle::bug;
 use rustc_middle::hir::place::PlaceBase;
diff --git a/compiler/rustc_codegen_cranelift/src/archive.rs b/compiler/rustc_codegen_cranelift/src/archive.rs
index 3f23e0d9e04..1935005a08c 100644
--- a/compiler/rustc_codegen_cranelift/src/archive.rs
+++ b/compiler/rustc_codegen_cranelift/src/archive.rs
@@ -1,7 +1,7 @@
 use std::path::{Path, PathBuf};
 
 use rustc_codegen_ssa::back::archive::{
-    get_native_object_symbols, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
+    ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
 };
 use rustc_session::Session;
 
@@ -9,7 +9,7 @@ pub(crate) struct ArArchiveBuilderBuilder;
 
 impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
-        Box::new(ArArchiveBuilder::new(sess, get_native_object_symbols))
+        Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
     }
 
     fn create_dll_import_lib(
diff --git a/compiler/rustc_codegen_gcc/src/archive.rs b/compiler/rustc_codegen_gcc/src/archive.rs
index 73ff0c37b66..21676f5dbb6 100644
--- a/compiler/rustc_codegen_gcc/src/archive.rs
+++ b/compiler/rustc_codegen_gcc/src/archive.rs
@@ -1,7 +1,7 @@
 use std::path::{Path, PathBuf};
 
 use rustc_codegen_ssa::back::archive::{
-    get_native_object_symbols, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
+    ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
 };
 use rustc_session::Session;
 
@@ -11,7 +11,7 @@ pub(crate) struct ArArchiveBuilderBuilder;
 
 impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
-        Box::new(ArArchiveBuilder::new(sess, get_native_object_symbols))
+        Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
     }
 
     fn create_dll_import_lib(
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index a354f3d3536..f46c6b1c498 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -15,8 +15,8 @@ use crate::errors::{
 use crate::llvm::archive_ro::{ArchiveRO, Child};
 use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
 use rustc_codegen_ssa::back::archive::{
-    get_native_object_symbols, try_extract_macho_fat_archive, ArArchiveBuilder,
-    ArchiveBuildFailure, ArchiveBuilder, ArchiveBuilderBuilder, UnknownArchiveKind,
+    try_extract_macho_fat_archive, ArArchiveBuilder, ArchiveBuildFailure, ArchiveBuilder,
+    ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind, DEFAULT_OBJECT_READER,
 };
 use tracing::trace;
 
@@ -115,7 +115,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
         if true {
             Box::new(LlvmArchiveBuilder { sess, additions: Vec::new() })
         } else {
-            Box::new(ArArchiveBuilder::new(sess, get_llvm_object_symbols))
+            Box::new(ArArchiveBuilder::new(sess, &LLVM_OBJECT_READER))
         }
     }
 
@@ -291,59 +291,84 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
 
 // The object crate doesn't know how to get symbols for LLVM bitcode and COFF bigobj files.
 // As such we need to use LLVM for them.
+
+static LLVM_OBJECT_READER: ObjectReader = ObjectReader {
+    get_symbols: get_llvm_object_symbols,
+    is_64_bit_object_file: llvm_is_64_bit_object_file,
+    is_ec_object_file: llvm_is_ec_object_file,
+    get_xcoff_member_alignment: DEFAULT_OBJECT_READER.get_xcoff_member_alignment,
+};
+
+fn should_use_llvm_reader(buf: &[u8]) -> bool {
+    let is_bitcode = unsafe { llvm::LLVMRustIsBitcode(buf.as_ptr(), buf.len()) };
+
+    // COFF bigobj file, msvc LTO file or import library. See
+    // https://github.com/llvm/llvm-project/blob/453f27bc9/llvm/lib/BinaryFormat/Magic.cpp#L38-L51
+    let is_unsupported_windows_obj_file = buf.get(0..4) == Some(b"\0\0\xFF\xFF");
+
+    is_bitcode || is_unsupported_windows_obj_file
+}
+
 #[deny(unsafe_op_in_unsafe_fn)]
 fn get_llvm_object_symbols(
     buf: &[u8],
     f: &mut dyn FnMut(&[u8]) -> io::Result<()>,
 ) -> io::Result<bool> {
-    let is_bitcode = unsafe { llvm::LLVMRustIsBitcode(buf.as_ptr(), buf.len()) };
+    if !should_use_llvm_reader(buf) {
+        return (DEFAULT_OBJECT_READER.get_symbols)(buf, f);
+    }
 
-    // COFF bigobj file, msvc LTO file or import library. See
-    // https://github.com/llvm/llvm-project/blob/453f27bc9/llvm/lib/BinaryFormat/Magic.cpp#L38-L51
-    let is_unsupported_windows_obj_file = buf.get(0..4) == Some(b"\0\0\xFF\xFF");
+    let mut state = Box::new(f);
 
-    if is_bitcode || is_unsupported_windows_obj_file {
-        let mut state = Box::new(f);
-
-        let err = unsafe {
-            llvm::LLVMRustGetSymbols(
-                buf.as_ptr(),
-                buf.len(),
-                std::ptr::addr_of_mut!(*state) as *mut c_void,
-                callback,
-                error_callback,
-            )
-        };
+    let err = unsafe {
+        llvm::LLVMRustGetSymbols(
+            buf.as_ptr(),
+            buf.len(),
+            std::ptr::addr_of_mut!(*state) as *mut c_void,
+            callback,
+            error_callback,
+        )
+    };
 
-        if err.is_null() {
-            return Ok(true);
-        } else {
-            return Err(unsafe { *Box::from_raw(err as *mut io::Error) });
-        }
+    if err.is_null() {
+        return Ok(true);
+    } else {
+        return Err(unsafe { *Box::from_raw(err as *mut io::Error) });
+    }
 
-        unsafe extern "C" fn callback(
-            state: *mut c_void,
-            symbol_name: *const c_char,
-        ) -> *mut c_void {
-            let f = unsafe { &mut *(state as *mut &mut dyn FnMut(&[u8]) -> io::Result<()>) };
-            match f(unsafe { CStr::from_ptr(symbol_name) }.to_bytes()) {
-                Ok(()) => std::ptr::null_mut(),
-                Err(err) => Box::into_raw(Box::new(err)) as *mut c_void,
-            }
+    unsafe extern "C" fn callback(state: *mut c_void, symbol_name: *const c_char) -> *mut c_void {
+        let f = unsafe { &mut *(state as *mut &mut dyn FnMut(&[u8]) -> io::Result<()>) };
+        match f(unsafe { CStr::from_ptr(symbol_name) }.to_bytes()) {
+            Ok(()) => std::ptr::null_mut(),
+            Err(err) => Box::into_raw(Box::new(err)) as *mut c_void,
         }
+    }
 
-        unsafe extern "C" fn error_callback(error: *const c_char) -> *mut c_void {
-            let error = unsafe { CStr::from_ptr(error) };
-            Box::into_raw(Box::new(io::Error::new(
-                io::ErrorKind::Other,
-                format!("LLVM error: {}", error.to_string_lossy()),
-            ))) as *mut c_void
-        }
-    } else {
-        get_native_object_symbols(buf, f)
+    unsafe extern "C" fn error_callback(error: *const c_char) -> *mut c_void {
+        let error = unsafe { CStr::from_ptr(error) };
+        Box::into_raw(Box::new(io::Error::new(
+            io::ErrorKind::Other,
+            format!("LLVM error: {}", error.to_string_lossy()),
+        ))) as *mut c_void
     }
 }
 
+fn llvm_is_64_bit_object_file(buf: &[u8]) -> bool {
+    if !should_use_llvm_reader(buf) {
+        return (DEFAULT_OBJECT_READER.is_64_bit_object_file)(buf);
+    }
+
+    unsafe { llvm::LLVMRustIs64BitSymbolicFile(buf.as_ptr(), buf.len()) }
+}
+
+fn llvm_is_ec_object_file(buf: &[u8]) -> bool {
+    if !should_use_llvm_reader(buf) {
+        return (DEFAULT_OBJECT_READER.is_ec_object_file)(buf);
+    }
+
+    unsafe { llvm::LLVMRustIsECObject(buf.as_ptr(), buf.len()) }
+}
+
 impl<'a> LlvmArchiveBuilder<'a> {
     fn build_with_llvm(&mut self, output: &Path) -> io::Result<bool> {
         let kind = &*self.sess.target.archive_format;
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index e0bf6110cdf..ae46200d3f5 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2440,4 +2440,8 @@ extern "C" {
         callback: GetSymbolsCallback,
         error_callback: GetSymbolsErrorCallback,
     ) -> *mut c_void;
+
+    pub fn LLVMRustIs64BitSymbolicFile(buf_ptr: *const u8, buf_len: usize) -> bool;
+
+    pub fn LLVMRustIsECObject(buf_ptr: *const u8, buf_len: usize) -> bool;
 }
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 3771fc6b0a2..f7b5b0f310b 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
 
 [dependencies]
 # tidy-alphabetical-start
-ar_archive_writer = "0.2.0"
+ar_archive_writer = "0.3.0"
 arrayvec = { version = "0.7", default-features = false }
 bitflags = "2.4.1"
 cc = "1.0.90"
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index c99118f5156..ae649cd77c4 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -6,8 +6,8 @@ use rustc_span::symbol::Symbol;
 
 use super::metadata::search_for_section;
 
-pub use ar_archive_writer::get_native_object_symbols;
 use ar_archive_writer::{write_archive_to_stream, ArchiveKind, NewArchiveMember};
+pub use ar_archive_writer::{ObjectReader, DEFAULT_OBJECT_READER};
 use object::read::archive::ArchiveFile;
 use object::read::macho::FatArch;
 use tempfile::Builder as TempFileBuilder;
@@ -89,8 +89,7 @@ pub trait ArchiveBuilder {
 #[must_use = "must call build() to finish building the archive"]
 pub struct ArArchiveBuilder<'a> {
     sess: &'a Session,
-    get_object_symbols:
-        fn(buf: &[u8], f: &mut dyn FnMut(&[u8]) -> io::Result<()>) -> io::Result<bool>,
+    object_reader: &'static ObjectReader,
 
     src_archives: Vec<(PathBuf, Mmap)>,
     // Don't use an `HashMap` here, as the order is important. `lib.rmeta` needs
@@ -105,14 +104,8 @@ enum ArchiveEntry {
 }
 
 impl<'a> ArArchiveBuilder<'a> {
-    pub fn new(
-        sess: &'a Session,
-        get_object_symbols: fn(
-            buf: &[u8],
-            f: &mut dyn FnMut(&[u8]) -> io::Result<()>,
-        ) -> io::Result<bool>,
-    ) -> ArArchiveBuilder<'a> {
-        ArArchiveBuilder { sess, get_object_symbols, src_archives: vec![], entries: vec![] }
+    pub fn new(sess: &'a Session, object_reader: &'static ObjectReader) -> ArArchiveBuilder<'a> {
+        ArArchiveBuilder { sess, object_reader, src_archives: vec![], entries: vec![] }
     }
 }
 
@@ -267,7 +260,7 @@ impl<'a> ArArchiveBuilder<'a> {
 
             entries.push(NewArchiveMember {
                 buf: data,
-                get_symbols: self.get_object_symbols,
+                object_reader: self.object_reader,
                 member_name: String::from_utf8(entry_name).unwrap(),
                 mtime: 0,
                 uid: 0,
@@ -294,7 +287,13 @@ impl<'a> ArArchiveBuilder<'a> {
         let mut archive_tmpfile = File::create_new(&archive_tmpfile_path)
             .map_err(|err| io_error_context("couldn't create the temp file", err))?;
 
-        write_archive_to_stream(&mut archive_tmpfile, &entries, archive_kind, false)?;
+        write_archive_to_stream(
+            &mut archive_tmpfile,
+            &entries,
+            archive_kind,
+            false,
+            /* is_ec = */ self.sess.target.arch == "arm64ec",
+        )?;
 
         let any_entries = !entries.is_empty();
         drop(entries);
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 1f627353d54..8e07d128dbd 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -750,7 +750,7 @@ fn link_natively(
 
     for print in &sess.opts.prints {
         if print.kind == PrintKind::LinkArgs {
-            let content = format!("{cmd:?}");
+            let content = format!("{cmd:?}\n");
             print.out.overwrite(&content, sess);
         }
     }
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 7fea0617666..4da7e233889 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -34,7 +34,6 @@ use super::{
     Pointer, Projectable, Scalar, ValueVisitor,
 };
 
-// for the validation errors
 use super::InterpError::UndefinedBehavior as Ub;
 use super::InterpError::Unsupported as Unsup;
 use super::UndefinedBehaviorInfo::*;
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 6a36938dd1d..9fef31acef8 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -82,7 +82,7 @@ use rustc_errors::{pluralize, struct_span_code_err, Diag};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::Visitor;
 use rustc_index::bit_set::BitSet;
-use rustc_infer::infer::error_reporting::ObligationCauseExt as _;
+use rustc_infer::error_reporting::infer::ObligationCauseExt as _;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{self, TyCtxtInferExt as _};
 use rustc_infer::traits::ObligationCause;
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index ea9567f4e3d..6da3f1dd114 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -19,7 +19,7 @@ use rustc_hir_analysis::hir_ty_lowering::{
     GenericPathSegment, HirTyLowerer, IsMethodCall, RegionInferReason,
 };
 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
-use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
+use rustc_infer::infer::need_type_info::TypeAnnotationNeeded;
 use rustc_infer::infer::{DefineOpaqueTypes, InferResult};
 use rustc_lint::builtin::SELF_CONSTRUCTOR_FROM_OUTER_ITEM;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
@@ -1519,7 +1519,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         } else {
             let e = self.tainted_by_errors().unwrap_or_else(|| {
                 self.err_ctxt()
-                    .emit_inference_failure_err(self.body_id, sp, ty.into(), E0282, true)
+                    .emit_inference_failure_err(
+                        self.body_id,
+                        sp,
+                        ty.into(),
+                        TypeAnnotationNeeded::E0282,
+                        true,
+                    )
                     .emit()
             });
             let err = Ty::new_error(self.tcx, e);
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 9fbb01216bb..b6b1bf34653 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -29,7 +29,7 @@ use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
 use rustc_hir_analysis::check::potentially_plural_count;
 use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
 use rustc_index::IndexVec;
-use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
+use rustc_infer::error_reporting::infer::{FailureCode, ObligationCauseExt};
 use rustc_infer::infer::TypeTrace;
 use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
 use rustc_middle::ty::adjustment::AllowTwoPhase;
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index b5796fbd48a..3fe87c03e74 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -15,9 +15,9 @@ use hir::def_id::CRATE_DEF_ID;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
+use rustc_infer::error_reporting::infer::sub_relations::SubRelations;
+use rustc_infer::error_reporting::infer::TypeErrCtxt;
 use rustc_infer::infer;
-use rustc_infer::infer::error_reporting::sub_relations::SubRelations;
-use rustc_infer::infer::error_reporting::TypeErrCtxt;
 use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
 use rustc_session::Session;
 use rustc_span::symbol::Ident;
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index dc1b888374c..daf4ef5cdb3 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -182,8 +182,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self_expr: &'tcx hir::Expr<'tcx>,
         args: &'tcx [hir::Expr<'tcx>],
     ) -> Result<MethodCallee<'tcx>, MethodError<'tcx>> {
-        let pick =
-            self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?;
+        let scope = if let Some(only_method) = segment.res.opt_def_id() {
+            ProbeScope::Single(only_method)
+        } else {
+            ProbeScope::TraitsInScope
+        };
+
+        let pick = self.lookup_probe(segment.ident, self_ty, call_expr, scope)?;
 
         self.lint_edition_dependent_dot_call(
             self_ty, segment, span, call_expr, self_expr, &pick, args,
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 6a7af5510e0..e817685e41c 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -12,7 +12,7 @@ use rustc_hir::HirId;
 use rustc_hir_analysis::autoderef::{self, Autoderef};
 use rustc_infer::infer::canonical::OriginalQueryValues;
 use rustc_infer::infer::canonical::{Canonical, QueryResponse};
-use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
+use rustc_infer::infer::need_type_info::TypeAnnotationNeeded;
 use rustc_infer::infer::DefineOpaqueTypes;
 use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
 use rustc_infer::traits::ObligationCauseCode;
@@ -20,6 +20,7 @@ use rustc_middle::middle::stability;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
 use rustc_middle::ty::AssocItem;
+use rustc_middle::ty::AssocItemContainer;
 use rustc_middle::ty::GenericParamDefKind;
 use rustc_middle::ty::Upcast;
 use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
@@ -216,6 +217,9 @@ pub enum Mode {
 
 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
 pub enum ProbeScope {
+    // Single candidate coming from pre-resolved delegation method.
+    Single(DefId),
+
     // Assemble candidates coming only from traits in scope.
     TraitsInScope,
 
@@ -441,7 +445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             self.body_id,
                             span,
                             ty.into(),
-                            E0282,
+                            TypeAnnotationNeeded::E0282,
                             !raw_ptr_call,
                         );
                         if raw_ptr_call {
@@ -480,12 +484,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 is_suggestion,
             );
 
-            probe_cx.assemble_inherent_candidates();
             match scope {
                 ProbeScope::TraitsInScope => {
-                    probe_cx.assemble_extension_candidates_for_traits_in_scope()
+                    probe_cx.assemble_inherent_candidates();
+                    probe_cx.assemble_extension_candidates_for_traits_in_scope();
+                }
+                ProbeScope::AllTraits => {
+                    probe_cx.assemble_inherent_candidates();
+                    probe_cx.assemble_extension_candidates_for_all_traits();
+                }
+                ProbeScope::Single(def_id) => {
+                    let item = self.tcx.associated_item(def_id);
+                    // FIXME(fn_delegation): Delegation to inherent methods is not yet supported.
+                    assert_eq!(item.container, AssocItemContainer::TraitContainer);
+
+                    let trait_def_id = self.tcx.parent(def_id);
+                    let trait_span = self.tcx.def_span(trait_def_id);
+
+                    let trait_args = self.fresh_args_for_item(trait_span, trait_def_id);
+                    let trait_ref = ty::TraitRef::new_from_args(self.tcx, trait_def_id, trait_args);
+
+                    probe_cx.push_candidate(
+                        Candidate {
+                            item,
+                            kind: CandidateKind::TraitCandidate(ty::Binder::dummy(trait_ref)),
+                            import_ids: smallvec![],
+                        },
+                        false,
+                    );
                 }
-                ProbeScope::AllTraits => probe_cx.assemble_extension_candidates_for_all_traits(),
             };
             op(probe_cx)
         })
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index e800c1a97d9..611854ce2af 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -8,7 +8,7 @@ use rustc_errors::{ErrorGuaranteed, StashKey};
 use rustc_hir as hir;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::HirId;
-use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
+use rustc_infer::infer::need_type_info::TypeAnnotationNeeded;
 use rustc_middle::span_bug;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
@@ -783,7 +783,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
                     self.fcx.tcx.hir().body_owner_def_id(self.body.id()),
                     self.span.to_span(self.fcx.tcx),
                     p.into(),
-                    E0282,
+                    TypeAnnotationNeeded::E0282,
                     false,
                 )
                 .emit()
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/error_reporting/infer/mod.rs
index bb1285ee813..ddd5818203c 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/mod.rs
@@ -45,17 +45,11 @@
 //! ported to this system, and which relies on string concatenation at the
 //! time of error detection.
 
-use super::{InferCtxt, TypeTrace, ValuePairs};
-
-use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags};
-use crate::infer;
-use crate::infer::ExpectedFound;
-use crate::traits::{
-    IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
-    PredicateObligation,
-};
+use std::borrow::Cow;
+use std::ops::{ControlFlow, Deref};
+use std::path::PathBuf;
+use std::{cmp, fmt, iter};
 
-use crate::infer::relate::{self, RelateResult, TypeRelation};
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_errors::{
     pluralize, Applicability, Diag, DiagCtxtHandle, DiagStyledString, IntoDiagArg, StringPart,
@@ -68,6 +62,7 @@ use rustc_hir::{self as hir};
 use rustc_macros::extension;
 use rustc_middle::bug;
 use rustc_middle::dep_graph::DepContext;
+use rustc_middle::ty::error::ExpectedFound;
 use rustc_middle::ty::error::TypeErrorToStringExt;
 use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError, PrintTraitRefExt as _};
 use rustc_middle::ty::{
@@ -76,18 +71,21 @@ use rustc_middle::ty::{
 };
 use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span};
 use rustc_target::spec::abi;
-use std::borrow::Cow;
-use std::ops::{ControlFlow, Deref};
-use std::path::PathBuf;
-use std::{cmp, fmt, iter};
+
+use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags};
+use crate::infer;
+use crate::infer::relate::{self, RelateResult, TypeRelation};
+use crate::infer::{InferCtxt, TypeTrace, ValuePairs};
+use crate::traits::{
+    IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
+    PredicateObligation,
+};
 
 mod note_and_explain;
 mod suggest;
 
-pub(crate) mod need_type_info;
-pub mod sub_relations;
-pub use need_type_info::TypeAnnotationNeeded;
 pub mod region;
+pub mod sub_relations;
 
 pub mod nice_region_error;
 
@@ -1242,7 +1240,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             Some(values) => {
                 let values = self.resolve_vars_if_possible(values);
                 let (is_simple_error, exp_found) = match values {
-                    ValuePairs::Terms(infer::ExpectedFound { expected, found }) => {
+                    ValuePairs::Terms(ExpectedFound { expected, found }) => {
                         match (expected.unpack(), found.unpack()) {
                             (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
                                 let is_simple_err = expected.is_simple_text(self.tcx)
@@ -1254,7 +1252,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
                                 (
                                     is_simple_err,
-                                    Mismatch::Variable(infer::ExpectedFound { expected, found }),
+                                    Mismatch::Variable(ExpectedFound { expected, found }),
                                 )
                             }
                             (ty::TermKind::Const(_), ty::TermKind::Const(_)) => {
@@ -1263,13 +1261,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             _ => (false, Mismatch::Fixed("type")),
                         }
                     }
-                    ValuePairs::PolySigs(infer::ExpectedFound { expected, found }) => {
+                    ValuePairs::PolySigs(ExpectedFound { expected, found }) => {
                         OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
                             .report(diag);
                         (false, Mismatch::Fixed("signature"))
                     }
                     ValuePairs::TraitRefs(_) => (false, Mismatch::Fixed("trait")),
-                    ValuePairs::Aliases(infer::ExpectedFound { expected, .. }) => {
+                    ValuePairs::Aliases(ExpectedFound { expected, .. }) => {
                         (false, Mismatch::Fixed(self.tcx.def_descr(expected.def_id)))
                     }
                     ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")),
@@ -1303,9 +1301,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         };
         if let Some((sp, msg)) = secondary_span {
             if swap_secondary_and_primary {
-                let terr = if let Some(infer::ValuePairs::Terms(infer::ExpectedFound {
-                    expected,
-                    ..
+                let terr = if let Some(infer::ValuePairs::Terms(ExpectedFound {
+                    expected, ..
                 })) = values
                 {
                     Cow::from(format!("expected this to be `{expected}`"))
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/different_lifetimes.rs
index cbeec591960..74dcde03639 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/different_lifetimes.rs
@@ -1,21 +1,20 @@
 //! Error Reporting for Anonymous Region Lifetime Errors
 //! where both the regions are anonymous.
 
+use crate::error_reporting::infer::nice_region_error::find_anon_type::find_anon_type;
+use crate::error_reporting::infer::nice_region_error::util::AnonymousParamInfo;
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
 use crate::errors::AddLifetimeParamsSuggestion;
 use crate::errors::LifetimeMismatch;
 use crate::errors::LifetimeMismatchLabels;
-use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
-use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::RegionResolutionError;
 use crate::infer::SubregionOrigin;
-use crate::infer::TyCtxt;
 
 use rustc_errors::Subdiagnostic;
 use rustc_errors::{Diag, ErrorGuaranteed};
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::Ty;
-use rustc_middle::ty::Region;
+use rustc_middle::ty::{Region, TyCtxt};
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// Print the error message for lifetime errors when both the concerned regions are anonymous.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/find_anon_type.rs
index b91b755d683..b91b755d683 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/find_anon_type.rs
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs
index 7996b4bf65b..550cc455e01 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs
@@ -1,12 +1,12 @@
 //! Error Reporting for when the lifetime for a type doesn't match the `impl` selected for a predicate
 //! to hold.
 
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
 use crate::errors::{note_and_explain, IntroducesStaticBecauseUnmetLifetimeReq};
 use crate::errors::{
     DoesNotOutliveStaticFromImpl, ImplicitStaticLifetimeSubdiag, MismatchedStaticLifetime,
 };
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::RegionResolutionError;
 use crate::infer::{SubregionOrigin, TypeTrace};
 use crate::traits::ObligationCauseCode;
 use rustc_data_structures::fx::FxIndexSet;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/mod.rs
index cffdfa88752..ced4c384f02 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/mod.rs
@@ -1,6 +1,6 @@
-use crate::infer::error_reporting::TypeErrCtxt;
-use crate::infer::lexical_region_resolve::RegionResolutionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError::*;
+use crate::error_reporting::infer::TypeErrCtxt;
+use crate::infer::RegionResolutionError;
+use crate::infer::RegionResolutionError::*;
 use rustc_errors::{Diag, ErrorGuaranteed};
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::ty::{self, TyCtxt};
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs
index 85624c9ca73..d1802d2f5ee 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs
@@ -1,11 +1,9 @@
 //! Error Reporting for Anonymous Region Lifetime Errors
 //! where one region is named and the other is anonymous.
 
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::{
-    errors::ExplicitLifetimeRequired,
-    infer::error_reporting::nice_region_error::find_anon_type::find_anon_type,
-};
+use crate::error_reporting::infer::nice_region_error::find_anon_type::find_anon_type;
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
+use crate::errors::ExplicitLifetimeRequired;
 use rustc_errors::Diag;
 use rustc_middle::ty;
 use rustc_span::symbol::kw;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/placeholder_error.rs
index 80b7e3b4fa5..476ac3f1720 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/placeholder_error.rs
@@ -1,9 +1,9 @@
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
 use crate::errors::{
     ActualImplExpectedKind, ActualImplExpectedLifetimeKind, ActualImplExplNotes,
     TraitPlaceholderMismatch, TyOrSig,
 };
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::RegionResolutionError;
 use crate::infer::ValuePairs;
 use crate::infer::{SubregionOrigin, TypeTrace};
 use crate::traits::{ObligationCause, ObligationCauseCode};
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/placeholder_relation.rs
index a3f306802de..e9f17a3e3e2 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/placeholder_relation.rs
@@ -1,9 +1,6 @@
-use crate::{
-    errors::PlaceholderRelationLfNotSatisfied,
-    infer::{
-        error_reporting::nice_region_error::NiceRegionError, RegionResolutionError, SubregionOrigin,
-    },
-};
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
+use crate::errors::PlaceholderRelationLfNotSatisfied;
+use crate::infer::{RegionResolutionError, SubregionOrigin};
 use rustc_data_structures::intern::Interned;
 use rustc_errors::Diag;
 use rustc_middle::ty::{self, RePlaceholder, Region};
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
index 9973646aecd..ce157ff3dc8 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/static_impl_trait.rs
@@ -1,11 +1,11 @@
 //! Error Reporting for static impl Traits.
 
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
 use crate::errors::{
     ButCallingIntroduces, ButNeedsToSatisfy, DynTraitConstraintSuggestion, MoreTargeted,
     ReqIntroducedLocations,
 };
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::RegionResolutionError;
 use crate::infer::{SubregionOrigin, TypeTrace};
 use crate::traits::{ObligationCauseCode, UnifyReceiverContext};
 use rustc_data_structures::fx::FxIndexSet;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs
index 7f3e23716f9..c58c7e13551 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs
@@ -1,8 +1,8 @@
 //! Error Reporting for `impl` items that do not match the obligations from their `trait`.
 
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
 use crate::errors::{ConsiderBorrowingParamHelp, RelationshipHelp, TraitImplDiff};
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::RegionResolutionError;
 use crate::infer::{Subtype, ValuePairs};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/util.rs
index 83145e4f7b2..30fa98c5526 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/nice_region_error/util.rs
@@ -1,13 +1,13 @@
 //! Helper functions corresponding to lifetime errors due to
 //! anonymous regions.
 
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::TyCtxt;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
-use rustc_middle::ty::{self, Binder, Region, Ty, TypeFoldable};
+use rustc_middle::ty::{self, Binder, Region, Ty, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 
+use crate::error_reporting::infer::nice_region_error::NiceRegionError;
+
 /// Information about the anonymous region we are searching for.
 #[derive(Debug)]
 pub struct AnonymousParamInfo<'tcx> {
diff --git a/compiler/rustc_infer/src/error_reporting/infer/note.rs b/compiler/rustc_infer/src/error_reporting/infer/note.rs
new file mode 100644
index 00000000000..aeb3049c2ae
--- /dev/null
+++ b/compiler/rustc_infer/src/error_reporting/infer/note.rs
@@ -0,0 +1,421 @@
+use crate::error_reporting::infer::{note_and_explain_region, TypeErrCtxt};
+use crate::errors::{
+    note_and_explain, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent,
+    RefLongerThanData, RegionOriginNote, WhereClauseSuggestions,
+};
+use crate::fluent_generated as fluent;
+use crate::infer::{self, SubregionOrigin};
+use rustc_errors::{Diag, Subdiagnostic};
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_middle::traits::ObligationCauseCode;
+use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::{self, IsSuggestable, Region, Ty};
+use rustc_span::symbol::kw;
+
+use super::ObligationCauseAsDiagArg;
+
+impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
+    pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) {
+        match *origin {
+            infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
+                span: trace.cause.span,
+                requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
+                expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)),
+            }
+            .add_to_diag(err),
+            infer::Reborrow(span) => {
+                RegionOriginNote::Plain { span, msg: fluent::infer_reborrow }.add_to_diag(err)
+            }
+            infer::RelateObjectBound(span) => {
+                RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound }
+                    .add_to_diag(err);
+            }
+            infer::ReferenceOutlivesReferent(ty, span) => {
+                RegionOriginNote::WithName {
+                    span,
+                    msg: fluent::infer_reference_outlives_referent,
+                    name: &self.ty_to_string(ty),
+                    continues: false,
+                }
+                .add_to_diag(err);
+            }
+            infer::RelateParamBound(span, ty, opt_span) => {
+                RegionOriginNote::WithName {
+                    span,
+                    msg: fluent::infer_relate_param_bound,
+                    name: &self.ty_to_string(ty),
+                    continues: opt_span.is_some(),
+                }
+                .add_to_diag(err);
+                if let Some(span) = opt_span {
+                    RegionOriginNote::Plain { span, msg: fluent::infer_relate_param_bound_2 }
+                        .add_to_diag(err);
+                }
+            }
+            infer::RelateRegionParamBound(span) => {
+                RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound }
+                    .add_to_diag(err);
+            }
+            infer::CompareImplItemObligation { span, .. } => {
+                RegionOriginNote::Plain { span, msg: fluent::infer_compare_impl_item_obligation }
+                    .add_to_diag(err);
+            }
+            infer::CheckAssociatedTypeBounds { ref parent, .. } => {
+                self.note_region_origin(err, parent);
+            }
+            infer::AscribeUserTypeProvePredicate(span) => {
+                RegionOriginNote::Plain {
+                    span,
+                    msg: fluent::infer_ascribe_user_type_prove_predicate,
+                }
+                .add_to_diag(err);
+            }
+        }
+    }
+
+    pub(super) fn report_concrete_failure(
+        &self,
+        generic_param_scope: LocalDefId,
+        origin: SubregionOrigin<'tcx>,
+        sub: Region<'tcx>,
+        sup: Region<'tcx>,
+    ) -> Diag<'a> {
+        let mut err = match origin {
+            infer::Subtype(box trace) => {
+                let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
+                let mut err = self.report_and_explain_type_error(trace, terr);
+                match (*sub, *sup) {
+                    (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
+                    (ty::RePlaceholder(_), _) => {
+                        note_and_explain_region(
+                            self.tcx,
+                            &mut err,
+                            generic_param_scope,
+                            "",
+                            sup,
+                            " doesn't meet the lifetime requirements",
+                            None,
+                        );
+                    }
+                    (_, ty::RePlaceholder(_)) => {
+                        note_and_explain_region(
+                            self.tcx,
+                            &mut err,
+                            generic_param_scope,
+                            "the required lifetime does not necessarily outlive ",
+                            sub,
+                            "",
+                            None,
+                        );
+                    }
+                    _ => {
+                        note_and_explain_region(
+                            self.tcx,
+                            &mut err,
+                            generic_param_scope,
+                            "",
+                            sup,
+                            "...",
+                            None,
+                        );
+                        note_and_explain_region(
+                            self.tcx,
+                            &mut err,
+                            generic_param_scope,
+                            "...does not necessarily outlive ",
+                            sub,
+                            "",
+                            None,
+                        );
+                    }
+                }
+                err
+            }
+            infer::Reborrow(span) => {
+                let reference_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sub,
+                    None,
+                    note_and_explain::PrefixKind::RefValidFor,
+                    note_and_explain::SuffixKind::Continues,
+                );
+                let content_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sup,
+                    None,
+                    note_and_explain::PrefixKind::ContentValidFor,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                self.dcx().create_err(OutlivesContent {
+                    span,
+                    notes: reference_valid.into_iter().chain(content_valid).collect(),
+                })
+            }
+            infer::RelateObjectBound(span) => {
+                let object_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sub,
+                    None,
+                    note_and_explain::PrefixKind::TypeObjValidFor,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                let pointer_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sup,
+                    None,
+                    note_and_explain::PrefixKind::SourcePointerValidFor,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                self.dcx().create_err(OutlivesBound {
+                    span,
+                    notes: object_valid.into_iter().chain(pointer_valid).collect(),
+                })
+            }
+            infer::RelateParamBound(span, ty, opt_span) => {
+                let prefix = match *sub {
+                    ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy,
+                    _ => note_and_explain::PrefixKind::TypeOutlive,
+                };
+                let suffix = if opt_span.is_some() {
+                    note_and_explain::SuffixKind::ReqByBinding
+                } else {
+                    note_and_explain::SuffixKind::Empty
+                };
+                let note = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sub,
+                    opt_span,
+                    prefix,
+                    suffix,
+                );
+                self.dcx().create_err(FulfillReqLifetime {
+                    span,
+                    ty: self.resolve_vars_if_possible(ty),
+                    note,
+                })
+            }
+            infer::RelateRegionParamBound(span) => {
+                let param_instantiated = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sup,
+                    None,
+                    note_and_explain::PrefixKind::LfParamInstantiatedWith,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                let param_must_outlive = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sub,
+                    None,
+                    note_and_explain::PrefixKind::LfParamMustOutlive,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                self.dcx().create_err(LfBoundNotSatisfied {
+                    span,
+                    notes: param_instantiated.into_iter().chain(param_must_outlive).collect(),
+                })
+            }
+            infer::ReferenceOutlivesReferent(ty, span) => {
+                let pointer_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sub,
+                    None,
+                    note_and_explain::PrefixKind::PointerValidFor,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                let data_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sup,
+                    None,
+                    note_and_explain::PrefixKind::DataValidFor,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                self.dcx().create_err(RefLongerThanData {
+                    span,
+                    ty: self.resolve_vars_if_possible(ty),
+                    notes: pointer_valid.into_iter().chain(data_valid).collect(),
+                })
+            }
+            infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => {
+                let mut err = self.infcx.report_extra_impl_obligation(
+                    span,
+                    impl_item_def_id,
+                    trait_item_def_id,
+                    &format!("`{sup}: {sub}`"),
+                );
+                // We should only suggest rewriting the `where` clause if the predicate is within that `where` clause
+                if let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id)
+                    && generics.where_clause_span.contains(span)
+                {
+                    self.suggest_copy_trait_method_bounds(
+                        trait_item_def_id,
+                        impl_item_def_id,
+                        &mut err,
+                    );
+                }
+                err
+            }
+            infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => {
+                let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup);
+
+                // Don't mention the item name if it's an RPITIT, since that'll just confuse
+                // folks.
+                if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) {
+                    let trait_item_span = self.tcx.def_span(trait_item_def_id);
+                    let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
+                    err.span_label(
+                        trait_item_span,
+                        format!("definition of `{item_name}` from trait"),
+                    );
+                }
+
+                self.suggest_copy_trait_method_bounds(
+                    trait_item_def_id,
+                    impl_item_def_id,
+                    &mut err,
+                );
+                err
+            }
+            infer::AscribeUserTypeProvePredicate(span) => {
+                let instantiated = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sup,
+                    None,
+                    note_and_explain::PrefixKind::LfInstantiatedWith,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                let must_outlive = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    generic_param_scope,
+                    sub,
+                    None,
+                    note_and_explain::PrefixKind::LfMustOutlive,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                self.dcx().create_err(LfBoundNotSatisfied {
+                    span,
+                    notes: instantiated.into_iter().chain(must_outlive).collect(),
+                })
+            }
+        };
+        if sub.is_error() || sup.is_error() {
+            err.downgrade_to_delayed_bug();
+        }
+        err
+    }
+
+    pub fn suggest_copy_trait_method_bounds(
+        &self,
+        trait_item_def_id: DefId,
+        impl_item_def_id: LocalDefId,
+        err: &mut Diag<'_>,
+    ) {
+        // FIXME(compiler-errors): Right now this is only being used for region
+        // predicate mismatches. Ideally, we'd use it for *all* predicate mismatches,
+        // but right now it's not really very smart when it comes to implicit `Sized`
+        // predicates and bounds on the trait itself.
+
+        let Some(impl_def_id) = self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx)
+        else {
+            return;
+        };
+        let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) else {
+            return;
+        };
+        let trait_args = trait_ref
+            .instantiate_identity()
+            // Replace the explicit self type with `Self` for better suggestion rendering
+            .with_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper))
+            .args;
+        let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id)
+            .rebase_onto(self.tcx, impl_def_id, trait_args);
+
+        let Ok(trait_predicates) =
+            self.tcx
+                .explicit_predicates_of(trait_item_def_id)
+                .instantiate_own(self.tcx, trait_item_args)
+                .map(|(pred, _)| {
+                    if pred.is_suggestable(self.tcx, false) {
+                        Ok(pred.to_string())
+                    } else {
+                        Err(())
+                    }
+                })
+                .collect::<Result<Vec<_>, ()>>()
+        else {
+            return;
+        };
+
+        let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) else {
+            return;
+        };
+
+        let suggestion = if trait_predicates.is_empty() {
+            WhereClauseSuggestions::Remove { span: generics.where_clause_span }
+        } else {
+            let space = if generics.where_clause_span.is_empty() { " " } else { "" };
+            WhereClauseSuggestions::CopyPredicates {
+                span: generics.where_clause_span,
+                space,
+                trait_predicates: trait_predicates.join(", "),
+            }
+        };
+        err.subdiagnostic(suggestion);
+    }
+
+    pub(super) fn report_placeholder_failure(
+        &self,
+        generic_param_scope: LocalDefId,
+        placeholder_origin: SubregionOrigin<'tcx>,
+        sub: Region<'tcx>,
+        sup: Region<'tcx>,
+    ) -> Diag<'a> {
+        // I can't think how to do better than this right now. -nikomatsakis
+        debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure");
+        match placeholder_origin {
+            infer::Subtype(box ref trace)
+                if matches!(
+                    &trace.cause.code().peel_derives(),
+                    ObligationCauseCode::WhereClause(..)
+                        | ObligationCauseCode::WhereClauseInExpr(..)
+                ) =>
+            {
+                // Hack to get around the borrow checker because trace.cause has an `Rc`.
+                if let ObligationCauseCode::WhereClause(_, span)
+                | ObligationCauseCode::WhereClauseInExpr(_, span, ..) =
+                    &trace.cause.code().peel_derives()
+                    && !span.is_dummy()
+                {
+                    let span = *span;
+                    self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup)
+                        .with_span_note(span, "the lifetime requirement is introduced here")
+                } else {
+                    unreachable!(
+                        "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..."
+                    )
+                }
+            }
+            infer::Subtype(box trace) => {
+                let terr = TypeError::RegionsPlaceholderMismatch;
+                return self.report_and_explain_type_error(trace, terr);
+            }
+            _ => {
+                return self.report_concrete_failure(
+                    generic_param_scope,
+                    placeholder_origin,
+                    sub,
+                    sup,
+                );
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/error_reporting/infer/note_and_explain.rs
index d5e7de897d0..d5e7de897d0 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/note_and_explain.rs
diff --git a/compiler/rustc_infer/src/infer/error_reporting/region.rs b/compiler/rustc_infer/src/error_reporting/infer/region.rs
index 191cb23184d..093d2d3d743 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/region.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/region.rs
@@ -18,12 +18,12 @@ use rustc_type_ir::Upcast as _;
 
 use super::nice_region_error::find_anon_type;
 use super::{nice_region_error, ObligationCauseAsDiagArg};
+use crate::error_reporting::infer::{ObligationCauseExt as _, TypeErrCtxt};
 use crate::errors::{
     self, note_and_explain, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound,
     OutlivesContent, RefLongerThanData, RegionOriginNote, WhereClauseSuggestions,
 };
 use crate::fluent_generated as fluent;
-use crate::infer::error_reporting::{ObligationCauseExt as _, TypeErrCtxt};
 use crate::infer::region_constraints::GenericKind;
 use crate::infer::{self, InferCtxt, RegionResolutionError, RegionVariableOrigin, SubregionOrigin};
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/sub_relations.rs b/compiler/rustc_infer/src/error_reporting/infer/sub_relations.rs
index ef26a8ff7b8..ef26a8ff7b8 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/sub_relations.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/sub_relations.rs
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/error_reporting/infer/suggest.rs
index 13b145296a7..4d11ab9fac6 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/error_reporting/infer/suggest.rs
@@ -1,4 +1,4 @@
-use crate::infer::error_reporting::hir::Path;
+use crate::error_reporting::infer::hir::Path;
 use core::ops::ControlFlow;
 use hir::def::CtorKind;
 use hir::intravisit::{walk_expr, walk_stmt, Visitor};
diff --git a/compiler/rustc_infer/src/error_reporting/mod.rs b/compiler/rustc_infer/src/error_reporting/mod.rs
new file mode 100644
index 00000000000..132485ec661
--- /dev/null
+++ b/compiler/rustc_infer/src/error_reporting/mod.rs
@@ -0,0 +1 @@
+pub mod infer;
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index ce1b0f86d03..f849a1a7322 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -15,11 +15,10 @@ use rustc_span::symbol::kw;
 use rustc_span::Symbol;
 use rustc_span::{symbol::Ident, BytePos, Span};
 
+use crate::error_reporting::infer::nice_region_error::placeholder_error::Highlighted;
+use crate::error_reporting::infer::ObligationCauseAsDiagArg;
 use crate::fluent_generated as fluent;
-use crate::infer::error_reporting::{
-    need_type_info::UnderspecifiedArgKind, nice_region_error::placeholder_error::Highlighted,
-    ObligationCauseAsDiagArg,
-};
+use crate::infer::need_type_info::UnderspecifiedArgKind;
 
 use std::path::PathBuf;
 
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index 4fbeb0ec102..d71b7f3c264 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -1,5 +1,5 @@
+use crate::error_reporting::infer::nice_region_error::find_anon_type;
 use crate::fluent_generated as fluent;
-use crate::infer::error_reporting::nice_region_error::find_anon_type;
 use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, SubdiagMessageOp, Subdiagnostic};
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::bug;
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index a0be545d46f..cfef1f13015 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -11,9 +11,9 @@ pub use BoundRegionConversionTime::*;
 pub use RegionVariableOrigin::*;
 pub use SubregionOrigin::*;
 
+use crate::error_reporting::infer::TypeErrCtxt;
 use crate::infer::relate::RelateResult;
 use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine};
-use error_reporting::TypeErrCtxt;
 use free_regions::RegionRelations;
 use lexical_region_resolve::LexicalRegionResolutions;
 use opaque_types::OpaqueTypeStorage;
@@ -54,7 +54,6 @@ use type_variable::TypeVariableOrigin;
 pub mod at;
 pub mod canonical;
 mod context;
-pub mod error_reporting;
 pub mod free_regions;
 mod freshen;
 mod lexical_region_resolve;
@@ -66,6 +65,8 @@ pub mod relate;
 pub mod resolve;
 pub(crate) mod snapshot;
 pub mod type_variable;
+// FIXME(error_reporting): Where should we put this?
+pub mod need_type_info;
 
 #[must_use]
 #[derive(Debug)]
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/need_type_info.rs
index 084aebc296f..4f3dcd9043f 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/need_type_info.rs
@@ -1,8 +1,8 @@
+use crate::error_reporting::infer::TypeErrCtxt;
 use crate::errors::{
     AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError,
     SourceKindMultiSuggestion, SourceKindSubdiag,
 };
-use crate::infer::error_reporting::TypeErrCtxt;
 use crate::infer::InferCtxt;
 use rustc_errors::{codes::*, Diag, IntoDiagArg};
 use rustc_hir as hir;
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index b65ac859667..02ebf933f53 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -34,6 +34,7 @@
 #[macro_use]
 extern crate tracing;
 
+pub mod error_reporting;
 mod errors;
 pub mod infer;
 pub mod traits;
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 8be8996e4c8..4e83ef0c629 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -120,7 +120,6 @@ use types::*;
 use unit_bindings::*;
 use unused::*;
 
-/// Useful for other parts of the compiler / Clippy.
 pub use builtin::{MissingDoc, SoftLints};
 pub use context::{CheckLintNameResult, FindLintError, LintStore};
 pub use context::{EarlyContext, LateContext, LintContext};
diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
index a9d1362a338..ccf1a5429e2 100644
--- a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
@@ -4,12 +4,16 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
 // Derived from:
-// * https://github.com/llvm/llvm-project/blob/8ef3e895ad8ab1724e2b87cabad1dacdc7a397a3/llvm/include/llvm/Object/ArchiveWriter.h
-// * https://github.com/llvm/llvm-project/blob/8ef3e895ad8ab1724e2b87cabad1dacdc7a397a3/llvm/lib/Object/ArchiveWriter.cpp
+// * https://github.com/llvm/llvm-project/blob/ef6d1ec07c693352c4a60dd58db08d2d8558f6ea/llvm/include/llvm/Object/ArchiveWriter.h
+// * https://github.com/llvm/llvm-project/blob/ef6d1ec07c693352c4a60dd58db08d2d8558f6ea/llvm/lib/Object/ArchiveWriter.cpp
 
+#include "LLVMWrapper.h"
 #include "SuppressLLVMWarnings.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/COFFImportFile.h"
+#include "llvm/Object/IRObjectFile.h"
 #include "llvm/Object/ObjectFile.h"
 #include <llvm/Support/raw_ostream.h>
 
@@ -34,6 +38,27 @@ static bool isArchiveSymbol(const object::BasicSymbolRef &S) {
 typedef void *(*LLVMRustGetSymbolsCallback)(void *, const char *);
 typedef void *(*LLVMRustGetSymbolsErrorCallback)(const char *);
 
+// This function is copied from ArchiveWriter.cpp.
+static Expected<std::unique_ptr<SymbolicFile>>
+getSymbolicFile(MemoryBufferRef Buf, LLVMContext &Context) {
+  const file_magic Type = identify_magic(Buf.getBuffer());
+  // Don't attempt to read non-symbolic file types.
+  if (!object::SymbolicFile::isSymbolicFile(Type, &Context))
+    return nullptr;
+  if (Type == file_magic::bitcode) {
+    auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
+        Buf, file_magic::bitcode, &Context);
+    if (!ObjOrErr)
+      return ObjOrErr.takeError();
+    return std::move(*ObjOrErr);
+  } else {
+    auto ObjOrErr = object::SymbolicFile::createSymbolicFile(Buf);
+    if (!ObjOrErr)
+      return ObjOrErr.takeError();
+    return std::move(*ObjOrErr);
+  }
+}
+
 // Note: This is implemented in C++ instead of using the C api from Rust as
 // IRObjectFile doesn't implement getSymbolName, only printSymbolName, which is
 // inaccessible from the C api.
@@ -49,36 +74,16 @@ LLVMRustGetSymbols(char *BufPtr, size_t BufLen, void *State,
   // In the scenario when LLVMContext is populated SymbolicFile will contain a
   // reference to it, thus SymbolicFile should be destroyed first.
   LLVMContext Context;
-  std::unique_ptr<object::SymbolicFile> Obj;
-
-  const file_magic Type = identify_magic(Buf->getBuffer());
-  if (!object::SymbolicFile::isSymbolicFile(Type, &Context)) {
-    return 0;
-  }
-
-  if (Type == file_magic::bitcode) {
-    auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
-        Buf->getMemBufferRef(), file_magic::bitcode, &Context);
-    if (!ObjOrErr) {
-      Error E = ObjOrErr.takeError();
-      SmallString<0> ErrorBuf;
-      auto Error = raw_svector_ostream(ErrorBuf);
-      Error << E << '\0';
-      return ErrorCallback(Error.str().data());
-    }
-    Obj = std::move(*ObjOrErr);
-  } else {
-    auto ObjOrErr =
-        object::SymbolicFile::createSymbolicFile(Buf->getMemBufferRef());
-    if (!ObjOrErr) {
-      Error E = ObjOrErr.takeError();
-      SmallString<0> ErrorBuf;
-      auto Error = raw_svector_ostream(ErrorBuf);
-      Error << E << '\0';
-      return ErrorCallback(Error.str().data());
-    }
-    Obj = std::move(*ObjOrErr);
+  Expected<std::unique_ptr<object::SymbolicFile>> ObjOrErr =
+      getSymbolicFile(Buf->getMemBufferRef(), Context);
+  if (!ObjOrErr) {
+    Error E = ObjOrErr.takeError();
+    SmallString<0> ErrorBuf;
+    auto Error = raw_svector_ostream(ErrorBuf);
+    Error << E << '\0';
+    return ErrorCallback(Error.str().data());
   }
+  std::unique_ptr<object::SymbolicFile> Obj = std::move(*ObjOrErr);
 
   for (const object::BasicSymbolRef &S : Obj->symbols()) {
     if (!isArchiveSymbol(S))
@@ -97,3 +102,72 @@ LLVMRustGetSymbols(char *BufPtr, size_t BufLen, void *State,
   }
   return 0;
 }
+
+// Encoding true and false as invalid pointer values
+#define TRUE_PTR (void *)1
+#define FALSE_PTR (void *)0
+
+extern "C" bool LLVMRustIs64BitSymbolicFile(char *BufPtr, size_t BufLen) {
+  std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(
+      StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), false);
+  SmallString<0> SymNameBuf;
+  auto SymName = raw_svector_ostream(SymNameBuf);
+
+  // Code starting from this line is copied from s64BitSymbolicFile in
+  // ArchiveWriter.cpp.
+  // In the scenario when LLVMContext is populated SymbolicFile will contain a
+  // reference to it, thus SymbolicFile should be destroyed first.
+  LLVMContext Context;
+  Expected<std::unique_ptr<object::SymbolicFile>> ObjOrErr =
+      getSymbolicFile(Buf->getMemBufferRef(), Context);
+  if (!ObjOrErr) {
+    return false;
+  }
+  std::unique_ptr<object::SymbolicFile> Obj = std::move(*ObjOrErr);
+
+  return Obj != nullptr ? Obj->is64Bit() : false;
+}
+
+extern "C" bool LLVMRustIsECObject(char *BufPtr, size_t BufLen) {
+  std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(
+      StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), false);
+  SmallString<0> SymNameBuf;
+  auto SymName = raw_svector_ostream(SymNameBuf);
+
+  // In the scenario when LLVMContext is populated SymbolicFile will contain a
+  // reference to it, thus SymbolicFile should be destroyed first.
+  LLVMContext Context;
+  Expected<std::unique_ptr<object::SymbolicFile>> ObjOrErr =
+      getSymbolicFile(Buf->getMemBufferRef(), Context);
+  if (!ObjOrErr) {
+    return false;
+  }
+  std::unique_ptr<object::SymbolicFile> Obj = std::move(*ObjOrErr);
+
+  if (Obj == nullptr) {
+    return false;
+  }
+
+  // Code starting from this line is copied from isECObject in
+  // ArchiveWriter.cpp with an extra #if to work with LLVM 17.
+  if (Obj->isCOFF())
+    return cast<llvm::object::COFFObjectFile>(&*Obj)->getMachine() !=
+           COFF::IMAGE_FILE_MACHINE_ARM64;
+
+#if LLVM_VERSION_GE(18, 0)
+  if (Obj->isCOFFImportFile())
+    return cast<llvm::object::COFFImportFile>(&*Obj)->getMachine() !=
+           COFF::IMAGE_FILE_MACHINE_ARM64;
+#endif
+
+  if (Obj->isIR()) {
+    Expected<std::string> TripleStr =
+        getBitcodeTargetTriple(Obj->getMemoryBufferRef());
+    if (!TripleStr)
+      return false;
+    Triple T(*TripleStr);
+    return T.isWindowsArm64EC() || T.getArch() == Triple::x86_64;
+  }
+
+  return false;
+}
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index c2201b1c41e..4ce9e0f025c 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -388,6 +388,9 @@ parse_invalid_dyn_keyword = invalid `dyn` keyword
 parse_invalid_expression_in_let_else = a `{$operator}` expression cannot be directly assigned in `let...else`
 parse_invalid_identifier_with_leading_number = identifiers cannot start with a number
 
+parse_invalid_label =
+    invalid label name `{$name}`
+
 parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are invalid
     .label = invalid suffix `{$suffix}`
     .tuple_exception_line_1 = `{$suffix}` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases
@@ -414,6 +417,9 @@ parse_invalid_unicode_escape = invalid unicode character escape
 parse_invalid_variable_declaration =
     invalid variable declaration
 
+parse_keyword_lifetime =
+    lifetimes cannot use keyword names
+
 parse_kw_bad_case = keyword `{$kw}` is written in the wrong case
     .suggestion = write it in the correct case
 
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 092a2a10ab7..4222486034b 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -2010,6 +2010,21 @@ pub struct CannotBeRawIdent {
 }
 
 #[derive(Diagnostic)]
+#[diag(parse_keyword_lifetime)]
+pub struct KeywordLifetime {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_invalid_label)]
+pub struct InvalidLabel {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+}
+
+#[derive(Diagnostic)]
 #[diag(parse_cr_doc_comment)]
 pub struct CrDocComment {
     #[primary_span]
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 4bd20be4171..0ba8c66f48f 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2932,10 +2932,17 @@ impl<'a> Parser<'a> {
     }
 
     pub(crate) fn eat_label(&mut self) -> Option<Label> {
-        self.token.lifetime().map(|ident| {
+        if let Some(ident) = self.token.lifetime() {
+            // Disallow `'fn`, but with a better error message than `expect_lifetime`.
+            if ident.without_first_quote().is_reserved() {
+                self.dcx().emit_err(errors::InvalidLabel { span: ident.span, name: ident.name });
+            }
+
             self.bump();
-            Label { ident }
-        })
+            Some(Label { ident })
+        } else {
+            None
+        }
     }
 
     /// Parses a `match ... { ... }` expression (`match` token already eaten).
diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index 4a78b427832..41e31d76d62 100644
--- a/compiler/rustc_parse/src/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -177,8 +177,11 @@ impl<'a> Parser<'a> {
                     .collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?))
             }
             NonterminalKind::Lifetime => {
-                return if self.check_lifetime() {
-                    Ok(ParseNtResult::Lifetime(self.expect_lifetime().ident))
+                // We want to keep `'keyword` parsing, just like `keyword` is still
+                // an ident for nonterminal purposes.
+                return if let Some(ident) = self.token.lifetime() {
+                    self.bump();
+                    Ok(ParseNtResult::Lifetime(ident))
                 } else {
                     Err(self.dcx().create_err(UnexpectedNonterminal::Lifetime {
                         span: self.token.span,
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index e4e89615d71..8e8df9f0a84 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -542,12 +542,12 @@ impl<'a> Parser<'a> {
                     None => PatKind::Path(qself, path),
                 }
             }
-        } else if let token::Lifetime(lt) = self.token.kind
+        } else if let Some(lt) = self.token.lifetime()
             // In pattern position, we're totally fine with using "next token isn't colon"
             // as a heuristic. We could probably just always try to recover if it's a lifetime,
             // because we never have `'a: label {}` in a pattern position anyways, but it does
             // keep us from suggesting something like `let 'a: Ty = ..` => `let 'a': Ty = ..`
-            && could_be_unclosed_char_literal(Ident::with_dummy_span(lt))
+            && could_be_unclosed_char_literal(lt)
             && !self.look_ahead(1, |token| matches!(token.kind, token::Colon))
         {
             // Recover a `'a` as a `'a'` literal
@@ -683,12 +683,12 @@ impl<'a> Parser<'a> {
     /// Parse `&pat` / `&mut pat`.
     fn parse_pat_deref(&mut self, expected: Option<Expected>) -> PResult<'a, PatKind> {
         self.expect_and()?;
-        if let token::Lifetime(name) = self.token.kind {
+        if let Some(lifetime) = self.token.lifetime() {
             self.bump(); // `'a`
 
             self.dcx().emit_err(UnexpectedLifetimeInPattern {
                 span: self.prev_token.span,
-                symbol: name,
+                symbol: lifetime.name,
                 suggestion: self.prev_token.span.until(self.token.span),
             });
         }
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 94321b1dddd..68b8af7d20e 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -1230,6 +1230,12 @@ impl<'a> Parser<'a> {
     /// Parses a single lifetime `'a` or panics.
     pub(super) fn expect_lifetime(&mut self) -> Lifetime {
         if let Some(ident) = self.token.lifetime() {
+            if ident.without_first_quote().is_reserved()
+                && ![kw::UnderscoreLifetime, kw::StaticLifetime].contains(&ident.name)
+            {
+                self.dcx().emit_err(errors::KeywordLifetime { span: ident.span });
+            }
+
             self.bump();
             Lifetime { ident, id: ast::DUMMY_NODE_ID }
         } else {
diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs
index c9590ad06b0..1b4bcb789d2 100644
--- a/compiler/rustc_pattern_analysis/src/lib.rs
+++ b/compiler/rustc_pattern_analysis/src/lib.rs
@@ -21,9 +21,7 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
 use std::fmt;
 
-// Re-exports to avoid rustc_index version issues.
-pub use rustc_index::Idx;
-pub use rustc_index::IndexVec;
+pub use rustc_index::{Idx, IndexVec}; // re-exported to avoid rustc_index version issues
 
 #[cfg(feature = "rustc")]
 use rustc_middle::ty::Ty;
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 92cf73870ff..ced5ac17dac 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -316,7 +316,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         }
     }
 
-    fn insert_field_def_ids(&mut self, def_id: LocalDefId, fields: &[ast::FieldDef]) {
+    fn insert_field_idents(&mut self, def_id: LocalDefId, fields: &[ast::FieldDef]) {
         if fields.iter().any(|field| field.is_placeholder) {
             // The fields are not expanded yet.
             return;
@@ -652,7 +652,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         let def_id = feed.key();
 
         // Record field names for error reporting.
-        self.insert_field_def_ids(def_id, fields);
+        self.insert_field_idents(def_id, fields);
         self.insert_field_visibilities_local(def_id.to_def_id(), fields);
 
         for field in fields {
@@ -1520,7 +1520,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         }
 
         // Record field names for error reporting.
-        self.insert_field_def_ids(def_id, variant.data.fields());
+        self.insert_field_idents(def_id, variant.data.fields());
         self.insert_field_visibilities_local(def_id.to_def_id(), variant.data.fields());
 
         visit::walk_variant(self, variant);
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index 7c3553b60fd..854295dc048 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -4,6 +4,7 @@
 //! due to incomplete stable coverage.
 
 // Prefer importing stable_mir over internal rustc constructs to make this file more readable.
+
 use crate::rustc_smir::Tables;
 use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy, TyCtxt};
 use rustc_span::Symbol;
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
index c301deac616..deab0451ccb 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
@@ -8,7 +8,8 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor as _;
 use rustc_hir::LangItem;
-use rustc_infer::infer::error_reporting::{TypeAnnotationNeeded, TypeErrCtxt};
+use rustc_infer::error_reporting::infer::TypeErrCtxt;
+use rustc_infer::infer::need_type_info::TypeAnnotationNeeded;
 use rustc_infer::infer::{BoundRegionConversionTime, InferCtxt};
 use rustc_infer::traits::util::elaborate;
 use rustc_infer::traits::{
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 2e6247b4640..0d040ddbacb 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -4,7 +4,6 @@ use crate::error_reporting::traits::infer_ctxt_ext::InferCtxtExt;
 use crate::errors::{
     AsyncClosureNotFn, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch,
 };
-use crate::infer::error_reporting::TyCategory;
 use crate::infer::InferCtxtExt as _;
 use crate::infer::{self, InferCtxt};
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
@@ -25,7 +24,8 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::Node;
 use rustc_hir::{self as hir, LangItem};
-use rustc_infer::infer::error_reporting::TypeErrCtxt;
+use rustc_infer::error_reporting::infer::TyCategory;
+use rustc_infer::error_reporting::infer::TypeErrCtxt;
 use rustc_infer::infer::{InferOk, TypeTrace};
 use rustc_macros::extension;
 use rustc_middle::traits::select::OverflowError;
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
index 2131e236401..16dfa27b75a 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -11,7 +11,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{self as hir, LangItem};
-use rustc_infer::infer::error_reporting::TypeErrCtxt;
+use rustc_infer::error_reporting::infer::TypeErrCtxt;
 use rustc_infer::traits::{
     Obligation, ObligationCause, ObligationCauseCode, PredicateObligation, SelectionError,
 };
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
index e90fe8fb94d..a448e1924c8 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
@@ -3,7 +3,6 @@ use crate::error_reporting::traits::fulfillment_errors::InferCtxtPrivExt;
 use crate::errors::{
     EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented,
 };
-use crate::infer::error_reporting::TypeErrCtxt;
 use crate::infer::InferCtxtExt;
 use rustc_ast::AttrArgs;
 use rustc_ast::AttrArgsEq;
@@ -14,6 +13,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_infer::error_reporting::infer::TypeErrCtxt;
 use rustc_macros::{extension, LintDiagnostic};
 use rustc_middle::bug;
 use rustc_middle::ty::print::PrintTraitRefExt as _;
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
index 061a5a4be20..fe1771f9096 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
@@ -5,7 +5,7 @@ use rustc_errors::{
 };
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::LOCAL_CRATE;
-use rustc_infer::infer::error_reporting::TypeErrCtxt;
+use rustc_infer::error_reporting::infer::TypeErrCtxt;
 use rustc_infer::traits::{Obligation, PredicateObligation};
 use rustc_macros::extension;
 use rustc_middle::ty::print::{FmtPrinter, Print};
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 2bf582dcfb1..fa2acdd4a54 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -23,7 +23,7 @@ use rustc_hir::intravisit::Visitor;
 use rustc_hir::is_range_literal;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node};
-use rustc_infer::infer::error_reporting::TypeErrCtxt;
+use rustc_infer::error_reporting::infer::TypeErrCtxt;
 use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk};
 use rustc_macros::extension;
 use rustc_middle::hir::map;
diff --git a/library/alloc/src/testing/crash_test.rs b/library/alloc/src/testing/crash_test.rs
index bcf5f5f7251..ff72f99b2cb 100644
--- a/library/alloc/src/testing/crash_test.rs
+++ b/library/alloc/src/testing/crash_test.rs
@@ -1,5 +1,4 @@
-// We avoid relying on anything else in the crate, apart from the `Debug` trait.
-use crate::fmt::Debug;
+use crate::fmt::Debug; // the `Debug` trait is the only thing we use from `crate::fmt`
 use std::cmp::Ordering;
 use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
 
diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs
index 26b463e25ea..3c641a2e01c 100644
--- a/library/core/src/char/mod.rs
+++ b/library/core/src/char/mod.rs
@@ -24,7 +24,6 @@ mod convert;
 mod decode;
 mod methods;
 
-// stable re-exports
 #[stable(feature = "try_from", since = "1.34.0")]
 pub use self::convert::CharTryFromError;
 #[stable(feature = "char_from_str", since = "1.20.0")]
@@ -32,11 +31,10 @@ pub use self::convert::ParseCharError;
 #[stable(feature = "decode_utf16", since = "1.9.0")]
 pub use self::decode::{DecodeUtf16, DecodeUtf16Error};
 
-// perma-unstable re-exports
 #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
-pub use self::methods::encode_utf16_raw;
+pub use self::methods::encode_utf16_raw; // perma-unstable
 #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
-pub use self::methods::encode_utf8_raw;
+pub use self::methods::encode_utf8_raw; // perma-unstable
 
 use crate::ascii;
 use crate::error::Error;
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index 76752f22ed8..563f0a324e3 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -781,8 +781,15 @@ const unsafe fn strlen(ptr: *const c_char) -> usize {
 pub struct Bytes<'a> {
     // since we know the string is nul-terminated, we only need one pointer
     ptr: NonNull<u8>,
-    phantom: PhantomData<&'a u8>,
+    phantom: PhantomData<&'a [c_char]>,
 }
+
+#[unstable(feature = "cstr_bytes", issue = "112115")]
+unsafe impl Send for Bytes<'_> {}
+
+#[unstable(feature = "cstr_bytes", issue = "112115")]
+unsafe impl Sync for Bytes<'_> {}
+
 impl<'a> Bytes<'a> {
     #[inline]
     fn new(s: &'a CStr) -> Self {
@@ -815,7 +822,7 @@ impl Iterator for Bytes<'_> {
             if ret == 0 {
                 None
             } else {
-                self.ptr = self.ptr.offset(1);
+                self.ptr = self.ptr.add(1);
                 Some(ret)
             }
         }
@@ -825,6 +832,12 @@ impl Iterator for Bytes<'_> {
     fn size_hint(&self) -> (usize, Option<usize>) {
         if self.is_empty() { (0, Some(0)) } else { (1, None) }
     }
+
+    #[inline]
+    fn count(self) -> usize {
+        // SAFETY: We always hold a valid pointer to a C string
+        unsafe { strlen(self.ptr.as_ptr().cast()) }
+    }
 }
 
 #[unstable(feature = "cstr_bytes", issue = "112115")]
diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs
index a4bc8b1c9b0..9aac2332dce 100644
--- a/library/core/src/num/dec2flt/mod.rs
+++ b/library/core/src/num/dec2flt/mod.rs
@@ -250,8 +250,10 @@ pub fn dec2flt<F: RawFloat>(s: &str) -> Result<F, ParseFloatError> {
         None => return Err(pfe_invalid()),
     };
     num.negative = negative;
-    if let Some(value) = num.try_fast_path::<F>() {
-        return Ok(value);
+    if !cfg!(feature = "optimize_for_size") {
+        if let Some(value) = num.try_fast_path::<F>() {
+            return Ok(value);
+        }
     }
 
     // If significant digits were truncated, then we can have rounding error
diff --git a/library/core/src/prelude/common.rs b/library/core/src/prelude/common.rs
index a6a1a055e29..e38ef1e147c 100644
--- a/library/core/src/prelude/common.rs
+++ b/library/core/src/prelude/common.rs
@@ -2,6 +2,9 @@
 //!
 //! See the [module-level documentation](super) for more.
 
+// No formatting: this file is nothing but re-exports, and their order is worth preserving.
+#![cfg_attr(rustfmt, rustfmt::skip)]
+
 // Re-exported core operators
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
@@ -33,10 +36,7 @@ pub use crate::convert::{AsMut, AsRef, From, Into};
 pub use crate::default::Default;
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
-pub use crate::iter::{DoubleEndedIterator, ExactSizeIterator};
-#[stable(feature = "core_prelude", since = "1.4.0")]
-#[doc(no_inline)]
-pub use crate::iter::{Extend, IntoIterator, Iterator};
+pub use crate::iter::{DoubleEndedIterator, ExactSizeIterator, Extend, IntoIterator, Iterator};
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
 pub use crate::option::Option::{self, None, Some};
diff --git a/library/core/src/prelude/mod.rs b/library/core/src/prelude/mod.rs
index ca33ef160e8..496b78439ea 100644
--- a/library/core/src/prelude/mod.rs
+++ b/library/core/src/prelude/mod.rs
@@ -4,6 +4,9 @@
 //! This module is imported by default when `#![no_std]` is used in the same
 //! manner as the standard library's prelude.
 
+// No formatting: this file is nothing but re-exports, and their order is worth preserving.
+#![cfg_attr(rustfmt, rustfmt::skip)]
+
 #![stable(feature = "core_prelude", since = "1.4.0")]
 
 mod common;
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index a8a47b69632..f2247e83ec5 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -1809,10 +1809,9 @@ pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usiz
     // FIXME(#75598): Direct use of these intrinsics improves codegen significantly at opt-level <=
     // 1, where the method versions of these operations are not inlined.
     use intrinsics::{
-        assume, cttz_nonzero, exact_div, mul_with_overflow, unchecked_rem, unchecked_sub,
-        wrapping_add, wrapping_mul, wrapping_sub,
+        assume, cttz_nonzero, exact_div, mul_with_overflow, unchecked_rem, unchecked_shl,
+        unchecked_shr, unchecked_sub, wrapping_add, wrapping_mul, wrapping_sub,
     };
-    use intrinsics::{unchecked_shl, unchecked_shr};
 
     /// Calculate multiplicative modular inverse of `x` modulo `m`.
     ///
diff --git a/library/core/src/unicode/mod.rs b/library/core/src/unicode/mod.rs
index e1faa407d54..5ddd9f7476d 100644
--- a/library/core/src/unicode/mod.rs
+++ b/library/core/src/unicode/mod.rs
@@ -1,6 +1,19 @@
 #![unstable(feature = "unicode_internals", issue = "none")]
 #![allow(missing_docs)]
 
+// The `pub use` ones are for use in alloc, and are not re-exported in std.
+
+pub(crate) use unicode_data::alphabetic::lookup as Alphabetic;
+pub use unicode_data::case_ignorable::lookup as Case_Ignorable;
+pub use unicode_data::cased::lookup as Cased;
+pub(crate) use unicode_data::cc::lookup as Cc;
+pub use unicode_data::conversions;
+pub(crate) use unicode_data::grapheme_extend::lookup as Grapheme_Extend;
+pub(crate) use unicode_data::lowercase::lookup as Lowercase;
+pub(crate) use unicode_data::n::lookup as N;
+pub(crate) use unicode_data::uppercase::lookup as Uppercase;
+pub(crate) use unicode_data::white_space::lookup as White_Space;
+
 pub(crate) mod printable;
 mod unicode_data;
 
@@ -16,16 +29,3 @@ mod unicode_data;
 /// [Unicode 11.0 or later, Section 3.1 Versions of the Unicode Standard](https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf#page=4).
 #[stable(feature = "unicode_version", since = "1.45.0")]
 pub const UNICODE_VERSION: (u8, u8, u8) = unicode_data::UNICODE_VERSION;
-
-// For use in alloc, not re-exported in std.
-pub use unicode_data::{
-    case_ignorable::lookup as Case_Ignorable, cased::lookup as Cased, conversions,
-};
-
-pub(crate) use unicode_data::alphabetic::lookup as Alphabetic;
-pub(crate) use unicode_data::cc::lookup as Cc;
-pub(crate) use unicode_data::grapheme_extend::lookup as Grapheme_Extend;
-pub(crate) use unicode_data::lowercase::lookup as Lowercase;
-pub(crate) use unicode_data::n::lookup as N;
-pub(crate) use unicode_data::uppercase::lookup as Uppercase;
-pub(crate) use unicode_data::white_space::lookup as White_Space;
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 36add02d68c..fc9b8cfd46d 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -120,11 +120,8 @@ pub struct VarsOs {
 /// # Examples
 ///
 /// ```
-/// use std::env;
-///
-/// // We will iterate through the references to the element returned by
-/// // env::vars();
-/// for (key, value) in env::vars() {
+/// // Print all environment variables.
+/// for (key, value) in std::env::vars() {
 ///     println!("{key}: {value}");
 /// }
 /// ```
@@ -150,11 +147,8 @@ pub fn vars() -> Vars {
 /// # Examples
 ///
 /// ```
-/// use std::env;
-///
-/// // We will iterate through the references to the element returned by
-/// // env::vars_os();
-/// for (key, value) in env::vars_os() {
+/// // Print all environment variables.
+/// for (key, value) in std::env::vars_os() {
 ///     println!("{key:?}: {value:?}");
 /// }
 /// ```
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index d4d68c2068d..f0a73a308a4 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -470,7 +470,6 @@ pub mod rt;
 // The Rust prelude
 pub mod prelude;
 
-// Public module declarations and re-exports
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use alloc_crate::borrow;
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/os/fortanix_sgx/mod.rs b/library/std/src/os/fortanix_sgx/mod.rs
index 39a42f4e17f..b31dc06f8df 100644
--- a/library/std/src/os/fortanix_sgx/mod.rs
+++ b/library/std/src/os/fortanix_sgx/mod.rs
@@ -28,7 +28,6 @@ pub mod usercalls {
         pub use crate::sys::abi::usercalls::raw::{do_usercall, Usercalls as UsercallNrs};
         pub use crate::sys::abi::usercalls::raw::{Register, RegisterArgument, ReturnValue};
 
-        // fortanix-sgx-abi re-exports
         pub use crate::sys::abi::usercalls::raw::Error;
         pub use crate::sys::abi::usercalls::raw::{
             ByteBuffer, Cancel, FifoDescriptor, Return, Usercall,
diff --git a/library/std/src/os/uefi/mod.rs b/library/std/src/os/uefi/mod.rs
index 8ef05eee1f4..b42d796b28f 100644
--- a/library/std/src/os/uefi/mod.rs
+++ b/library/std/src/os/uefi/mod.rs
@@ -2,6 +2,7 @@
 
 #![unstable(feature = "uefi_std", issue = "100499")]
 #![doc(cfg(target_os = "uefi"))]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 pub mod env;
 #[path = "../windows/ffi.rs"]
diff --git a/library/std/src/os/xous/mod.rs b/library/std/src/os/xous/mod.rs
index 153694a89a7..4b21695c4ac 100644
--- a/library/std/src/os/xous/mod.rs
+++ b/library/std/src/os/xous/mod.rs
@@ -1,5 +1,6 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![doc(cfg(target_os = "xous"))]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 pub mod ffi;
 
diff --git a/library/std/src/prelude/common.rs b/library/std/src/prelude/common.rs
index 055ab7eb6d9..b231bd871b3 100644
--- a/library/std/src/prelude/common.rs
+++ b/library/std/src/prelude/common.rs
@@ -2,6 +2,9 @@
 //!
 //! See the [module-level documentation](super) for more.
 
+// No formatting: this file is nothing but re-exports, and their order is worth preserving.
+#![cfg_attr(rustfmt, rustfmt::skip)]
+
 // Re-exported core operators
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs
index 2d4639342bf..0c610ba67e6 100644
--- a/library/std/src/prelude/mod.rs
+++ b/library/std/src/prelude/mod.rs
@@ -95,6 +95,9 @@
 //! [book-enums]: ../../book/ch06-01-defining-an-enum.html
 //! [book-iter]: ../../book/ch13-02-iterators.html
 
+// No formatting: this file is nothing but re-exports, and their order is worth preserving.
+#![cfg_attr(rustfmt, rustfmt::skip)]
+
 #![stable(feature = "rust1", since = "1.0.0")]
 
 mod common;
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index d030017cfb4..deb4a8fa7ee 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -16,7 +16,6 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 #![allow(unused_macros)]
 
-// Re-export some of our utilities which are expected by other crates.
 pub use crate::panicking::{begin_panic, panic_count};
 pub use core::panicking::{panic_display, panic_fmt};
 
diff --git a/library/std/src/sys/pal/hermit/futex.rs b/library/std/src/sys/pal/hermit/futex.rs
index b2d74d1311b..21c5facd52f 100644
--- a/library/std/src/sys/pal/hermit/futex.rs
+++ b/library/std/src/sys/pal/hermit/futex.rs
@@ -3,6 +3,11 @@ use crate::ptr::null;
 use crate::sync::atomic::AtomicU32;
 use crate::time::Duration;
 
+/// An atomic for use as a futex that is at least 8-bits but may be larger.
+pub type SmallAtomic = AtomicU32;
+/// Must be the underlying type of SmallAtomic
+pub type SmallPrimitive = u32;
+
 pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
     // Calculate the timeout as a relative timespec.
     //
diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs
index 408031a4616..4d50d9e8c3d 100644
--- a/library/std/src/sys/pal/uefi/mod.rs
+++ b/library/std/src/sys/pal/uefi/mod.rs
@@ -11,6 +11,7 @@
 //!
 //! [`OsStr`]: crate::ffi::OsStr
 //! [`OsString`]: crate::ffi::OsString
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 pub mod alloc;
 pub mod args;
diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs
index 26161a9af79..b8900da4cdd 100644
--- a/library/std/src/sys/pal/unix/futex.rs
+++ b/library/std/src/sys/pal/unix/futex.rs
@@ -11,6 +11,11 @@
 use crate::sync::atomic::AtomicU32;
 use crate::time::Duration;
 
+/// An atomic for use as a futex that is at least 8-bits but may be larger.
+pub type SmallAtomic = AtomicU32;
+/// Must be the underlying type of SmallAtomic
+pub type SmallPrimitive = u32;
+
 /// Wait for a futex_wake operation to wake us.
 ///
 /// Returns directly if the futex doesn't hold the expected value.
diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs
index 8dfb733043e..d8fe06d1973 100644
--- a/library/std/src/sys/pal/wasi/mod.rs
+++ b/library/std/src/sys/pal/wasi/mod.rs
@@ -39,12 +39,15 @@ pub mod time;
 #[deny(unsafe_op_in_unsafe_fn)]
 #[allow(unused)]
 mod common;
+
 pub use common::*;
 
 mod helpers;
-// These exports are listed individually to work around Rust's glob import
-// conflict rules. If we glob export `helpers` and `common` together, then
-// the compiler complains about conflicts.
+
+// The following exports are listed individually to work around Rust's glob
+// import conflict rules. If we glob export `helpers` and `common` together,
+// then the compiler complains about conflicts.
+
 pub use helpers::abort_internal;
 pub use helpers::decode_error_kind;
 use helpers::err2io;
diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs
index 7af0917b8ed..0930d2e22fa 100644
--- a/library/std/src/sys/pal/wasip2/mod.rs
+++ b/library/std/src/sys/pal/wasip2/mod.rs
@@ -41,13 +41,16 @@ pub mod time;
 #[deny(unsafe_op_in_unsafe_fn)]
 #[allow(unused)]
 mod common;
+
 pub use common::*;
 
 #[path = "../wasi/helpers.rs"]
 mod helpers;
-// These exports are listed individually to work around Rust's glob import
-// conflict rules. If we glob export `helpers` and `common` together, then
-// the compiler complains about conflicts.
+
+// The following exports are listed individually to work around Rust's glob
+// import conflict rules. If we glob export `helpers` and `common` together,
+// then the compiler complains about conflicts.
+
 pub use helpers::abort_internal;
 pub use helpers::decode_error_kind;
 use helpers::err2io;
diff --git a/library/std/src/sys/pal/wasm/atomics/futex.rs b/library/std/src/sys/pal/wasm/atomics/futex.rs
index a21b71efbbc..3584138ca04 100644
--- a/library/std/src/sys/pal/wasm/atomics/futex.rs
+++ b/library/std/src/sys/pal/wasm/atomics/futex.rs
@@ -6,6 +6,11 @@ use core::arch::wasm64 as wasm;
 use crate::sync::atomic::AtomicU32;
 use crate::time::Duration;
 
+/// An atomic for use as a futex that is at least 8-bits but may be larger.
+pub type SmallAtomic = AtomicU32;
+/// Must be the underlying type of SmallAtomic
+pub type SmallPrimitive = u32;
+
 /// Wait for a futex_wake operation to wake us.
 ///
 /// Returns directly if the futex doesn't hold the expected value.
diff --git a/library/std/src/sys/pal/windows/futex.rs b/library/std/src/sys/pal/windows/futex.rs
index 08b7fe300dc..cb802fdd9c9 100644
--- a/library/std/src/sys/pal/windows/futex.rs
+++ b/library/std/src/sys/pal/windows/futex.rs
@@ -10,6 +10,11 @@ use core::sync::atomic::{
 };
 use core::time::Duration;
 
+/// An atomic for use as a futex that is at least 8-bits but may be larger.
+pub type SmallAtomic = AtomicU8;
+/// Must be the underlying type of SmallAtomic
+pub type SmallPrimitive = u8;
+
 pub unsafe trait Waitable {
     type Atomic;
 }
diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs
index a28a52e305e..961d45c5e83 100644
--- a/library/std/src/sys/pal/xous/mod.rs
+++ b/library/std/src/sys/pal/xous/mod.rs
@@ -1,4 +1,4 @@
-#![deny(unsafe_op_in_unsafe_fn)]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 pub mod alloc;
 #[path = "../unsupported/args.rs"]
diff --git a/library/std/src/sys/pal/zkvm/alloc.rs b/library/std/src/sys/pal/zkvm/alloc.rs
index fd333f12151..2fdca223524 100644
--- a/library/std/src/sys/pal/zkvm/alloc.rs
+++ b/library/std/src/sys/pal/zkvm/alloc.rs
@@ -5,7 +5,7 @@ use crate::alloc::{GlobalAlloc, Layout, System};
 unsafe impl GlobalAlloc for System {
     #[inline]
     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
-        abi::sys_alloc_aligned(layout.size(), layout.align())
+        unsafe { abi::sys_alloc_aligned(layout.size(), layout.align()) }
     }
 
     #[inline]
diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs
index bacde9d880c..651f25d6623 100644
--- a/library/std/src/sys/pal/zkvm/mod.rs
+++ b/library/std/src/sys/pal/zkvm/mod.rs
@@ -6,6 +6,7 @@
 //! This is all super highly experimental and not actually intended for
 //! wide/production use yet, it's still all in the experimental category. This
 //! will likely change over time.
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 const WORD_SIZE: usize = core::mem::size_of::<u32>();
 
diff --git a/library/std/src/sys/personality/dwarf/mod.rs b/library/std/src/sys/personality/dwarf/mod.rs
index 652fbe95a14..89f7f133e21 100644
--- a/library/std/src/sys/personality/dwarf/mod.rs
+++ b/library/std/src/sys/personality/dwarf/mod.rs
@@ -17,32 +17,30 @@ pub struct DwarfReader {
     pub ptr: *const u8,
 }
 
-#[repr(C, packed)]
-struct Unaligned<T>(T);
-
+#[forbid(unsafe_op_in_unsafe_fn)]
 impl DwarfReader {
     pub fn new(ptr: *const u8) -> DwarfReader {
         DwarfReader { ptr }
     }
 
-    // DWARF streams are packed, so e.g., a u32 would not necessarily be aligned
-    // on a 4-byte boundary. This may cause problems on platforms with strict
-    // alignment requirements. By wrapping data in a "packed" struct, we are
-    // telling the backend to generate "misalignment-safe" code.
+    /// Read a type T and then bump the pointer by that amount.
+    ///
+    /// DWARF streams are "packed", so all types must be read at align 1.
     pub unsafe fn read<T: Copy>(&mut self) -> T {
-        let Unaligned(result) = *(self.ptr as *const Unaligned<T>);
-        self.ptr = self.ptr.add(mem::size_of::<T>());
-        result
+        unsafe {
+            let result = self.ptr.cast::<T>().read_unaligned();
+            self.ptr = self.ptr.byte_add(mem::size_of::<T>());
+            result
+        }
     }
 
-    // ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable
-    // Length Data".
+    /// ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable Length Data".
     pub unsafe fn read_uleb128(&mut self) -> u64 {
         let mut shift: usize = 0;
         let mut result: u64 = 0;
         let mut byte: u8;
         loop {
-            byte = self.read::<u8>();
+            byte = unsafe { self.read::<u8>() };
             result |= ((byte & 0x7F) as u64) << shift;
             shift += 7;
             if byte & 0x80 == 0 {
@@ -57,7 +55,7 @@ impl DwarfReader {
         let mut result: u64 = 0;
         let mut byte: u8;
         loop {
-            byte = self.read::<u8>();
+            byte = unsafe { self.read::<u8>() };
             result |= ((byte & 0x7F) as u64) << shift;
             shift += 7;
             if byte & 0x80 == 0 {
diff --git a/library/std/src/sys/sync/mutex/futex.rs b/library/std/src/sys/sync/mutex/futex.rs
index 7427cae94d6..81afa94b147 100644
--- a/library/std/src/sys/sync/mutex/futex.rs
+++ b/library/std/src/sys/sync/mutex/futex.rs
@@ -1,19 +1,8 @@
-use crate::sync::atomic::{
-    self,
-    Ordering::{Acquire, Relaxed, Release},
-};
-use crate::sys::futex::{futex_wait, futex_wake};
-
-cfg_if::cfg_if! {
-if #[cfg(windows)] {
-    // On Windows we can have a smol futex
-    type Atomic = atomic::AtomicU8;
-    type State = u8;
-} else {
-    type Atomic = atomic::AtomicU32;
-    type State = u32;
-}
-}
+use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
+use crate::sys::futex::{self, futex_wait, futex_wake};
+
+type Atomic = futex::SmallAtomic;
+type State = futex::SmallPrimitive;
 
 pub struct Mutex {
     futex: Atomic,
diff --git a/library/std/src/sys/sync/thread_parking/futex.rs b/library/std/src/sys/sync/thread_parking/futex.rs
index 588e7b27826..034eececb2a 100644
--- a/library/std/src/sys/sync/thread_parking/futex.rs
+++ b/library/std/src/sys/sync/thread_parking/futex.rs
@@ -1,15 +1,18 @@
+#![forbid(unsafe_op_in_unsafe_fn)]
 use crate::pin::Pin;
-use crate::sync::atomic::AtomicU32;
 use crate::sync::atomic::Ordering::{Acquire, Release};
-use crate::sys::futex::{futex_wait, futex_wake};
+use crate::sys::futex::{self, futex_wait, futex_wake};
 use crate::time::Duration;
 
-const PARKED: u32 = u32::MAX;
-const EMPTY: u32 = 0;
-const NOTIFIED: u32 = 1;
+type Atomic = futex::SmallAtomic;
+type State = futex::SmallPrimitive;
+
+const PARKED: State = State::MAX;
+const EMPTY: State = 0;
+const NOTIFIED: State = 1;
 
 pub struct Parker {
-    state: AtomicU32,
+    state: Atomic,
 }
 
 // Notes about memory ordering:
@@ -36,7 +39,7 @@ impl Parker {
     /// Construct the futex parker. The UNIX parker implementation
     /// requires this to happen in-place.
     pub unsafe fn new_in_place(parker: *mut Parker) {
-        parker.write(Self { state: AtomicU32::new(EMPTY) });
+        unsafe { parker.write(Self { state: Atomic::new(EMPTY) }) };
     }
 
     // Assumes this is only called by the thread that owns the Parker,
diff --git a/library/std/src/sys/sync/thread_parking/mod.rs b/library/std/src/sys/sync/thread_parking/mod.rs
index ed1a6437faa..0ebc5e093ee 100644
--- a/library/std/src/sys/sync/thread_parking/mod.rs
+++ b/library/std/src/sys/sync/thread_parking/mod.rs
@@ -1,5 +1,6 @@
 cfg_if::cfg_if! {
     if #[cfg(any(
+        all(target_os = "windows", not(target_vendor = "win7")),
         target_os = "linux",
         target_os = "android",
         all(target_arch = "wasm32", target_feature = "atomics"),
@@ -18,9 +19,9 @@ cfg_if::cfg_if! {
     ))] {
         mod id;
         pub use id::Parker;
-    } else if #[cfg(target_os = "windows")] {
-        mod windows;
-        pub use windows::Parker;
+    } else if #[cfg(target_vendor = "win7")] {
+        mod windows7;
+        pub use windows7::Parker;
     } else if #[cfg(all(target_vendor = "apple", not(miri)))] {
         mod darwin;
         pub use darwin::Parker;
diff --git a/library/std/src/sys/sync/thread_parking/windows.rs b/library/std/src/sys/sync/thread_parking/windows7.rs
index 3a8d40dc5cf..3a8d40dc5cf 100644
--- a/library/std/src/sys/sync/thread_parking/windows.rs
+++ b/library/std/src/sys/sync/thread_parking/windows7.rs
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index 7aff7fe1fdd..71cb796b937 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -25,7 +25,6 @@
 #![feature(test)]
 #![allow(internal_features)]
 
-// Public reexports
 pub use self::bench::{black_box, Bencher};
 pub use self::console::run_tests_console;
 pub use self::options::{ColorConfig, Options, OutputFormat, RunIgnored, ShouldPanic};
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index ba2ad53a94e..d4dd3e546ec 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1820,6 +1820,21 @@ impl Step for Assemble {
                     &self_contained_lld_dir.join(exe(name, target_compiler.host)),
                 );
             }
+
+            // In addition to `rust-lld` also install `wasm-component-ld` when
+            // LLD is enabled. This is a relatively small binary that primarily
+            // delegates to the `rust-lld` binary for linking and then runs
+            // logic to create the final binary. This is used by the
+            // `wasm32-wasip2` target of Rust.
+            let wasm_component_ld_exe =
+                builder.ensure(crate::core::build_steps::tool::WasmComponentLd {
+                    compiler: build_compiler,
+                    target: target_compiler.host,
+                });
+            builder.copy_link(
+                &wasm_component_ld_exe,
+                &libdir_bin.join(wasm_component_ld_exe.file_name().unwrap()),
+            );
         }
 
         if builder.config.llvm_enabled(target_compiler.host) {
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index ad92a01bce7..7bc410b9e88 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -337,6 +337,7 @@ bootstrap_tool!(
     RustdocGUITest, "src/tools/rustdoc-gui-test", "rustdoc-gui-test", is_unstable_tool = true, allow_features = "test";
     CoverageDump, "src/tools/coverage-dump", "coverage-dump";
     RustcPerfWrapper, "src/tools/rustc-perf-wrapper", "rustc-perf-wrapper";
+    WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization";
 );
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
index e3cb396b782..962484593b4 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -112,6 +112,7 @@ ENV TARGETS=$TARGETS,wasm32-unknown-unknown
 ENV TARGETS=$TARGETS,wasm32-wasi
 ENV TARGETS=$TARGETS,wasm32-wasip1
 ENV TARGETS=$TARGETS,wasm32-wasip1-threads
+ENV TARGETS=$TARGETS,wasm32-wasip2
 ENV TARGETS=$TARGETS,sparcv9-sun-solaris
 ENV TARGETS=$TARGETS,x86_64-pc-solaris
 ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32
diff --git a/src/tools/clippy/tests/ui/track-diagnostics.stderr b/src/tools/clippy/tests/ui/track-diagnostics.stderr
index 410e80f2528..3c7577dd003 100644
--- a/src/tools/clippy/tests/ui/track-diagnostics.stderr
+++ b/src/tools/clippy/tests/ui/track-diagnostics.stderr
@@ -3,7 +3,7 @@ error[E0308]: mismatched types
    |
 LL | const S: A = B;
    |              ^ expected `A`, found `B`
--Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC
+-Ztrack-diagnostics: created at compiler/rustc_infer/src/error_reporting/infer/mod.rs:LL:CC
 
 error: aborting due to 1 previous error
 
diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml
index 681284b1a48..b3913732839 100644
--- a/src/tools/run-make-support/Cargo.toml
+++ b/src/tools/run-make-support/Cargo.toml
@@ -10,6 +10,4 @@ similar = "2.5.0"
 wasmparser = "0.118.2"
 regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace
 gimli = "0.31.0"
-ar = "0.9.0"
-
 build_helper = { path = "../build_helper" }
diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs
index 31b9e8a23b8..75a20a21a31 100644
--- a/src/tools/run-make-support/src/cc.rs
+++ b/src/tools/run-make-support/src/cc.rs
@@ -1,7 +1,7 @@
 use std::path::Path;
 
 use crate::command::Command;
-use crate::{bin_name, cygpath_windows, env_var, is_msvc, is_windows, uname};
+use crate::{cygpath_windows, env_var, is_msvc, is_windows, uname};
 
 /// Construct a new platform-specific C compiler invocation.
 ///
@@ -68,9 +68,14 @@ impl Cc {
         // endif
         // ```
 
+        let mut path = std::path::PathBuf::from(name);
+
         if is_msvc() {
-            let fe_path = cygpath_windows(bin_name(name));
-            let fo_path = cygpath_windows(format!("{name}.obj"));
+            path.set_extension("exe");
+            let fe_path = cygpath_windows(&path);
+            path.set_extension("");
+            path.set_extension("obj");
+            let fo_path = cygpath_windows(path);
             self.cmd.arg(format!("-Fe:{fe_path}"));
             self.cmd.arg(format!("-Fo:{fo_path}"));
         } else {
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index e5f1ce1bf34..cec2cedd15c 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -30,8 +30,8 @@ pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc};
 pub use clang::{clang, Clang};
 pub use diff::{diff, Diff};
 pub use llvm::{
-    llvm_filecheck, llvm_objdump, llvm_profdata, llvm_readobj, LlvmFilecheck, LlvmObjdump,
-    LlvmProfdata, LlvmReadobj,
+    llvm_ar, llvm_filecheck, llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr, LlvmFilecheck,
+    LlvmObjdump, LlvmProfdata, LlvmReadobj,
 };
 pub use run::{cmd, run, run_fail, run_with_args};
 pub use rustc::{aux_build, bare_rustc, rustc, Rustc};
@@ -61,19 +61,6 @@ pub fn target() -> String {
     env_var("TARGET")
 }
 
-/// `AR`
-#[track_caller]
-pub fn ar(inputs: &[impl AsRef<Path>], output_path: impl AsRef<Path>) {
-    let output = fs::File::create(&output_path).expect(&format!(
-        "the file in path \"{}\" could not be created",
-        output_path.as_ref().display()
-    ));
-    let mut builder = ar::Builder::new(output);
-    for input in inputs {
-        builder.append_path(input).unwrap();
-    }
-}
-
 /// Check if target is windows-like.
 #[must_use]
 pub fn is_windows() -> bool {
@@ -294,6 +281,26 @@ pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
     !path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
 }
 
+/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
+#[track_caller]
+pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
+    let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
+    let src = format!("{lib_name}.c");
+    let lib_path = static_lib_name(lib_name);
+    if is_msvc() {
+        cc().arg("-c").out_exe(&obj_file).input(src).run();
+    } else {
+        cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run();
+    };
+    let obj_file = if is_msvc() {
+        PathBuf::from(format!("{lib_name}.obj"))
+    } else {
+        PathBuf::from(format!("{lib_name}.o"))
+    };
+    llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run();
+    path(lib_path)
+}
+
 /// Returns true if the filename at `path` is not in `expected`.
 pub fn filename_not_in_denylist<P: AsRef<Path>, V: AsRef<[String]>>(path: P, expected: V) -> bool {
     let expected = expected.as_ref();
diff --git a/src/tools/run-make-support/src/llvm.rs b/src/tools/run-make-support/src/llvm.rs
index 4c9e9a53230..064dc62a4af 100644
--- a/src/tools/run-make-support/src/llvm.rs
+++ b/src/tools/run-make-support/src/llvm.rs
@@ -29,6 +29,12 @@ pub fn llvm_objdump() -> LlvmObjdump {
     LlvmObjdump::new()
 }
 
+/// Construct a new `llvm-ar` invocation. This assumes that `llvm-ar` is available
+/// at `$LLVM_BIN_DIR/llvm-ar`.
+pub fn llvm_ar() -> LlvmAr {
+    LlvmAr::new()
+}
+
 /// A `llvm-readobj` invocation builder.
 #[derive(Debug)]
 #[must_use]
@@ -57,10 +63,18 @@ pub struct LlvmObjdump {
     cmd: Command,
 }
 
+/// A `llvm-ar` invocation builder.
+#[derive(Debug)]
+#[must_use]
+pub struct LlvmAr {
+    cmd: Command,
+}
+
 crate::impl_common_helpers!(LlvmReadobj);
 crate::impl_common_helpers!(LlvmProfdata);
 crate::impl_common_helpers!(LlvmFilecheck);
 crate::impl_common_helpers!(LlvmObjdump);
+crate::impl_common_helpers!(LlvmAr);
 
 /// Generate the path to the bin directory of LLVM.
 #[must_use]
@@ -204,3 +218,26 @@ impl LlvmObjdump {
         self
     }
 }
+
+impl LlvmAr {
+    /// Construct a new `llvm-ar` invocation. This assumes that `llvm-ar` is available
+    /// at `$LLVM_BIN_DIR/llvm-ar`.
+    pub fn new() -> Self {
+        let llvm_ar = llvm_bin_dir().join("llvm-ar");
+        let cmd = Command::new(llvm_ar);
+        Self { cmd }
+    }
+
+    pub fn obj_to_ar(&mut self) -> &mut Self {
+        self.cmd.arg("rcus");
+        self
+    }
+
+    /// Provide an output, then an input file. Bundled in one function, as llvm-ar has
+    /// no "--output"-style flag.
+    pub fn output_input(&mut self, out: impl AsRef<Path>, input: impl AsRef<Path>) -> &mut Self {
+        self.cmd.arg(out.as_ref());
+        self.cmd.arg(input.as_ref());
+        self
+    }
+}
diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs
index ae200d51431..6b08608cc62 100644
--- a/src/tools/run-make-support/src/rustc.rs
+++ b/src/tools/run-make-support/src/rustc.rs
@@ -242,6 +242,19 @@ impl Rustc {
         self
     }
 
+    /// Add a directory to the library search path with a restriction, where `kind` is a dependency
+    /// type. Equivalent to `-L KIND=PATH` in rustc.
+    pub fn specific_library_search_path<P: AsRef<Path>>(
+        &mut self,
+        kind: &str,
+        path: P,
+    ) -> &mut Self {
+        assert!(["dependency", "native", "all", "framework", "crate"].contains(&kind));
+        let path = path.as_ref().to_string_lossy();
+        self.cmd.arg(format!("-L{kind}={path}"));
+        self
+    }
+
     /// Override the system root. Equivalent to `--sysroot` in rustc.
     pub fn sysroot<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
         self.cmd.arg("--sysroot");
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 08d28e58166..2e26f9344b8 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -10,7 +10,6 @@ run-make/c-unwind-abi-catch-panic/Makefile
 run-make/cat-and-grep-sanity-check/Makefile
 run-make/cdylib-dylib-linkage/Makefile
 run-make/compiler-lookup-paths-2/Makefile
-run-make/compiler-lookup-paths/Makefile
 run-make/compiler-rt-works-on-mingw/Makefile
 run-make/crate-hash-rustc-version/Makefile
 run-make/cross-lang-lto-clang/Makefile
@@ -21,7 +20,6 @@ run-make/dep-info-doesnt-run-much/Makefile
 run-make/dep-info-spaces/Makefile
 run-make/dep-info/Makefile
 run-make/dump-ice-to-disk/Makefile
-run-make/dump-mono-stats/Makefile
 run-make/emit-to-stdout/Makefile
 run-make/export-executable-symbols/Makefile
 run-make/extern-diff-internal-name/Makefile
@@ -93,12 +91,9 @@ run-make/pgo-indirect-call-promotion/Makefile
 run-make/pointer-auth-link-with-c/Makefile
 run-make/print-calling-conventions/Makefile
 run-make/print-target-list/Makefile
-run-make/prune-link-args/Makefile
 run-make/raw-dylib-alt-calling-convention/Makefile
 run-make/raw-dylib-c/Makefile
-run-make/raw-dylib-custom-dlltool/Makefile
 run-make/raw-dylib-import-name-type/Makefile
-run-make/raw-dylib-inline-cross-dylib/Makefile
 run-make/raw-dylib-link-ordinal/Makefile
 run-make/raw-dylib-stdcall-ordinal/Makefile
 run-make/redundant-libs/Makefile
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 3c72fae0881..f9bf04626f7 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -95,7 +95,12 @@ const EXCEPTIONS: ExceptionList = &[
     ("self_cell", "Apache-2.0"),                             // rustc (fluent translations)
     ("snap", "BSD-3-Clause"),                                // rustc
     ("wasm-encoder", "Apache-2.0 WITH LLVM-exception"),      // rustc
+    ("wasm-metadata", "Apache-2.0 WITH LLVM-exception"),     // rustc
     ("wasmparser", "Apache-2.0 WITH LLVM-exception"),        // rustc
+    ("wast", "Apache-2.0 WITH LLVM-exception"),              // rustc
+    ("wat", "Apache-2.0 WITH LLVM-exception"),               // rustc
+    ("wit-component", "Apache-2.0 WITH LLVM-exception"),     // rustc
+    ("wit-parser", "Apache-2.0 WITH LLVM-exception"),        // rustc
     // tidy-alphabetical-end
 ];
 
diff --git a/src/tools/wasm-component-ld/Cargo.toml b/src/tools/wasm-component-ld/Cargo.toml
new file mode 100644
index 00000000000..91ff19ad9fc
--- /dev/null
+++ b/src/tools/wasm-component-ld/Cargo.toml
@@ -0,0 +1,13 @@
+# See the `README.md` in this directory for what this tool is.
+
+[package]
+name = "wasm-component-ld-wrapper"
+version = "0.1.0"
+edition = "2021"
+
+[[bin]]
+name = "wasm-component-ld"
+path = "src/main.rs"
+
+[dependencies]
+wasm-component-ld = "0.5.4"
diff --git a/src/tools/wasm-component-ld/README.md b/src/tools/wasm-component-ld/README.md
new file mode 100644
index 00000000000..54608a2dea1
--- /dev/null
+++ b/src/tools/wasm-component-ld/README.md
@@ -0,0 +1,62 @@
+# `wasm-component-ld`
+
+This wrapper is a wrapper around the [`wasm-component-ld`] crates.io crate. That
+crate. That crate is itself a thin wrapper around two pieces:
+
+* `wasm-ld` - the LLVM-based linker distributed as part of LLD and packaged in
+  Rust as `rust-lld`.
+* [`wit-component`] - a Rust crate for creating a [WebAssembly Component] from a
+  core wasm module.
+
+This linker is used for Rust's `wasm32-wasip2` target to natively output a
+component instead of a core WebAssembly module, unlike other WebAssembly
+targets. If you're confused about any of this here's an FAQ-style explanation of
+what's going on here:
+
+* **What's a component?** - It's a proposal to the WebAssembly standard
+  primarily developed at this time by out-of-browser use cases of WebAssembly.
+  You can find high-level documentation [here][component docs].
+
+* **What's WASIp2?** - Not to be confused with WASIp1, WASIp0,
+  `wasi_snapshot_preview1`, or `wasi_unstable`, it's a version of WASI. Released
+  in January 2024 it's the first version of WASI defined in terms of the
+  component model.
+
+* **Why does this need its own linker?** - like any target that Rust has the
+  `wasm32-wasip2` target needs a linker. What makes this different from other
+  WebAssembly targets is that WASIp2 is defined at the component level, not core
+  WebAssembly level. This means that filesystem functions take a `string`
+  instead of `i32 i32`, for example. This means that the raw output of LLVM and
+  `wasm-ld`, a core WebAssembly module, is not suitable.
+
+* **Isn't writing a linker really hard?** - Generally, yes, but this linker
+  works by first asking `wasm-ld` to do all the hard work. It invokes `wasm-ld`
+  and then uses the output core WebAssembly module to create a component.
+
+* **How do you create a component from a core module?** - this is the purpose of
+  the [`wit-component`] crate, notably the `ComponentEncoder` type. This uses
+  component type information embedded in the core module and a general set of
+  conventions/guidelines with what the core module imports/exports. A component
+  is then hooked up to codify all of these conventions in a component itself.
+
+* **Why not require users to run `wit-component` themselves?** - while possible
+  it adds friction to the usage `wasm32-wasip2` target. More importantly though
+  the "module only" output of the `wasm32-wasip2` target is not ready right now.
+  The standard library still imports from `wasi_snapshot_preview1` and it will
+  take time to migrate all usage to WASIp2.
+
+* **What exactly does this linker do?** - the `wasm-component-ld` has the same
+  CLI interface and flags as `wasm-ld`, plus some more that are
+  component-specific. These flags are used to forward most flags to `wasm-ld` to
+  produce a core wasm module. After the core wasm module is produced the
+  `wit-component` crate will read custom sections in the final binary which
+  contain component type information. After merging all this type information
+  together a component is produced which wraps the core module.
+
+If you've got any other questions about this linker or its operation don't
+hesitate to reach out to the maintainers of the `wasm32-wasip2` target.
+
+[`wasm-component-ld`]: https://crates.io/crates/wasm-component-ld
+[`wit-component`]: https://crates.io/crates/wit-component
+[WebAssembly Component]: https://github.com/webassembly/component-model
+[component docs]: https://component-model.bytecodealliance.org/
diff --git a/src/tools/wasm-component-ld/src/main.rs b/src/tools/wasm-component-ld/src/main.rs
new file mode 100644
index 00000000000..caaac651c4c
--- /dev/null
+++ b/src/tools/wasm-component-ld/src/main.rs
@@ -0,0 +1,9 @@
+// See the `README.md` in this directory for what this tool is.
+
+// The source for this crate lives at
+// https://github.com/bytecodealliance/wasm-component-ld and the binary is
+// independently used in other projects such as `wasi-sdk` so the `main`
+// function is just reexported here to delegate. A Cargo dependency is used to
+// facilitate version management in the Rust repository and work well with
+// vendored/offline builds.
+use wasm_component_ld::main;
diff --git a/tests/run-make/compiler-lookup-paths/Makefile b/tests/run-make/compiler-lookup-paths/Makefile
deleted file mode 100644
index fc0cbde4c35..00000000000
--- a/tests/run-make/compiler-lookup-paths/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-# rustc supports different types of lookup paths, such as dependency, native or crate. This test checks that these lookup paths are functional and result in functional compilation.
-# See https://github.com/rust-lang/rust/pull/19941
-
-include ../tools.mk
-
-# ignore-wasm32 (need a C compiler)
-# ignore-wasm64 (need a C compiler)
-
-all: $(TMPDIR)/libnative.a
-	mkdir -p $(TMPDIR)/crate
-	mkdir -p $(TMPDIR)/native
-	mv $(TMPDIR)/libnative.a $(TMPDIR)/native
-	$(RUSTC) a.rs
-	mv $(TMPDIR)/liba.rlib $(TMPDIR)/crate
-	$(RUSTC) b.rs -L native=$(TMPDIR)/crate && exit 1 || exit 0
-	$(RUSTC) b.rs -L dependency=$(TMPDIR)/crate && exit 1 || exit 0
-	$(RUSTC) b.rs -L crate=$(TMPDIR)/crate
-	$(RUSTC) b.rs -L all=$(TMPDIR)/crate
-	$(RUSTC) c.rs -L native=$(TMPDIR)/crate && exit 1 || exit 0
-	$(RUSTC) c.rs -L crate=$(TMPDIR)/crate && exit 1 || exit 0
-	$(RUSTC) c.rs -L dependency=$(TMPDIR)/crate
-	$(RUSTC) c.rs -L all=$(TMPDIR)/crate
-	$(RUSTC) d.rs -L dependency=$(TMPDIR)/native && exit 1 || exit 0
-	$(RUSTC) d.rs -L crate=$(TMPDIR)/native && exit 1 || exit 0
-	$(RUSTC) d.rs -L native=$(TMPDIR)/native
-	$(RUSTC) d.rs -L all=$(TMPDIR)/native
-	# Deduplication tests:
-	#   Same hash, no errors.
-	mkdir -p $(TMPDIR)/e1
-	mkdir -p $(TMPDIR)/e2
-	$(RUSTC) e.rs -o $(TMPDIR)/e1/libe.rlib
-	$(RUSTC) e.rs -o $(TMPDIR)/e2/libe.rlib
-	$(RUSTC) f.rs -L $(TMPDIR)/e1 -L $(TMPDIR)/e2
-	$(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L $(TMPDIR)/e2
-	$(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L crate=$(TMPDIR)/e2
-	#   Different hash, errors.
-	$(RUSTC) e2.rs -o $(TMPDIR)/e2/libe.rlib
-	$(RUSTC) f.rs -L $(TMPDIR)/e1 -L $(TMPDIR)/e2 && exit 1 || exit 0
-	$(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L $(TMPDIR)/e2 && exit 1 || exit 0
-	$(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L crate=$(TMPDIR)/e2 && exit 1 || exit 0
-	#   Native/dependency paths don't cause errors.
-	$(RUSTC) f.rs -L native=$(TMPDIR)/e1 -L $(TMPDIR)/e2
-	$(RUSTC) f.rs -L dependency=$(TMPDIR)/e1 -L $(TMPDIR)/e2
-	$(RUSTC) f.rs -L dependency=$(TMPDIR)/e1 -L crate=$(TMPDIR)/e2
diff --git a/tests/run-make/compiler-lookup-paths/rmake.rs b/tests/run-make/compiler-lookup-paths/rmake.rs
new file mode 100644
index 00000000000..0f791852821
--- /dev/null
+++ b/tests/run-make/compiler-lookup-paths/rmake.rs
@@ -0,0 +1,84 @@
+// Since #19941, rustc can accept specifications on its library search paths.
+// This test runs Rust programs with varied library dependencies, expecting them
+// to succeed or fail depending on the situation.
+// The second part of the tests also checks that libraries with an incorrect hash
+// fail to be used by the compiler.
+// See https://github.com/rust-lang/rust/pull/19941
+
+//@ ignore-wasm32
+//@ ignore-wasm64
+// Reason: a C compiler is required for build_native_static_lib
+
+use run_make_support::{build_native_static_lib, fs_wrapper, rustc, static_lib_name};
+
+fn main() {
+    build_native_static_lib("native");
+    let lib_native = static_lib_name("native");
+    fs_wrapper::create_dir_all("crate");
+    fs_wrapper::create_dir_all("native");
+    fs_wrapper::rename(&lib_native, format!("native/{}", &lib_native));
+    rustc().input("a.rs").run();
+    fs_wrapper::rename("liba.rlib", "crate/liba.rlib");
+    rustc().input("b.rs").specific_library_search_path("native", "crate").run_fail();
+    rustc().input("b.rs").specific_library_search_path("dependency", "crate").run_fail();
+    rustc().input("b.rs").specific_library_search_path("crate", "crate").run();
+    rustc().input("b.rs").specific_library_search_path("all", "crate").run();
+
+    rustc().input("c.rs").specific_library_search_path("native", "crate").run_fail();
+    rustc().input("c.rs").specific_library_search_path("crate", "crate").run_fail();
+    rustc().input("c.rs").specific_library_search_path("dependency", "crate").run();
+    rustc().input("c.rs").specific_library_search_path("all", "crate").run();
+
+    rustc().input("d.rs").specific_library_search_path("dependency", "native").run_fail();
+    rustc().input("d.rs").specific_library_search_path("crate", "native").run_fail();
+    rustc().input("d.rs").specific_library_search_path("native", "native").run();
+    rustc().input("d.rs").specific_library_search_path("all", "native").run();
+
+    // Deduplication tests.
+    fs_wrapper::create_dir_all("e1");
+    fs_wrapper::create_dir_all("e2");
+
+    rustc().input("e.rs").output("e1/libe.rlib").run();
+    rustc().input("e.rs").output("e2/libe.rlib").run();
+    // If the library hash is correct, compilation should succeed.
+    rustc().input("f.rs").library_search_path("e1").library_search_path("e2").run();
+    rustc()
+        .input("f.rs")
+        .specific_library_search_path("crate", "e1")
+        .library_search_path("e2")
+        .run();
+    rustc()
+        .input("f.rs")
+        .specific_library_search_path("crate", "e1")
+        .specific_library_search_path("crate", "e2")
+        .run();
+    // If the library has a different hash, errors should occur.
+    rustc().input("e2.rs").output("e2/libe.rlib").run();
+    rustc().input("f.rs").library_search_path("e1").library_search_path("e2").run_fail();
+    rustc()
+        .input("f.rs")
+        .specific_library_search_path("crate", "e1")
+        .library_search_path("e2")
+        .run_fail();
+    rustc()
+        .input("f.rs")
+        .specific_library_search_path("crate", "e1")
+        .specific_library_search_path("crate", "e2")
+        .run_fail();
+    // Native and dependency paths do not cause errors.
+    rustc()
+        .input("f.rs")
+        .specific_library_search_path("native", "e1")
+        .library_search_path("e2")
+        .run();
+    rustc()
+        .input("f.rs")
+        .specific_library_search_path("dependency", "e1")
+        .library_search_path("e2")
+        .run();
+    rustc()
+        .input("f.rs")
+        .specific_library_search_path("dependency", "e1")
+        .specific_library_search_path("crate", "e2")
+        .run();
+}
diff --git a/tests/run-make/dump-mono-stats/Makefile b/tests/run-make/dump-mono-stats/Makefile
deleted file mode 100644
index 196f84be6ec..00000000000
--- a/tests/run-make/dump-mono-stats/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-include ../tools.mk
-
-all:
-	$(RUSTC) --crate-type lib foo.rs -Z dump-mono-stats=$(TMPDIR) -Zdump-mono-stats-format=json
-	cat $(TMPDIR)/foo.mono_items.json | $(CGREP) '"name":"bar"'
diff --git a/tests/run-make/dump-mono-stats/rmake.rs b/tests/run-make/dump-mono-stats/rmake.rs
new file mode 100644
index 00000000000..05ba2e6b8ff
--- /dev/null
+++ b/tests/run-make/dump-mono-stats/rmake.rs
@@ -0,0 +1,17 @@
+// A flag named dump-mono-stats was added to the compiler in 2022, which
+// collects stats on instantiation of items and their associated costs.
+// This test checks that the output stat file exists, and that it contains
+// a specific expected string.
+// See https://github.com/rust-lang/rust/pull/105481
+
+use run_make_support::{cwd, fs_wrapper, rustc};
+
+fn main() {
+    rustc()
+        .crate_type("lib")
+        .input("foo.rs")
+        .arg(format!("-Zdump-mono-stats={}", cwd().display()))
+        .arg("-Zdump-mono-stats-format=json")
+        .run();
+    assert!(fs_wrapper::read_to_string("foo.mono_items.json").contains(r#""name":"bar""#));
+}
diff --git a/tests/run-make/invalid-library/rmake.rs b/tests/run-make/invalid-library/rmake.rs
index 750fcd05c8a..9ebab1c8b0f 100644
--- a/tests/run-make/invalid-library/rmake.rs
+++ b/tests/run-make/invalid-library/rmake.rs
@@ -1,8 +1,14 @@
+// When the metadata format changes, old libraries used to cause librustc to abort
+// when reading their metadata. The error message for this scenario was unhelpful at best.
+// A better error message was implemented in #12645, and this test checks that it is the
+// one appearing in stderr in this scenario.
+// See https://github.com/rust-lang/rust/pull/12645
+
 use run_make_support::fs_wrapper::create_file;
-use run_make_support::{ar, rustc};
+use run_make_support::{llvm_ar, rustc};
 
 fn main() {
     create_file("lib.rmeta");
-    ar(&["lib.rmeta"], "libfoo-ffffffff-1.0.rlib");
+    llvm_ar().obj_to_ar().output_input("libfoo-ffffffff-1.0.rlib", "lib.rmeta").run();
     rustc().input("foo.rs").run_fail().assert_stderr_contains("found invalid metadata");
 }
diff --git a/tests/run-make/link-arg/rmake.rs b/tests/run-make/link-arg/rmake.rs
index a6d68800792..c0bf8d972af 100644
--- a/tests/run-make/link-arg/rmake.rs
+++ b/tests/run-make/link-arg/rmake.rs
@@ -17,4 +17,5 @@ fn main() {
         .run_unchecked();
     out.assert_stdout_contains("lfoo");
     out.assert_stdout_contains("lbar");
+    assert!(out.stdout_utf8().ends_with('\n'));
 }
diff --git a/tests/run-make/prune-link-args/Makefile b/tests/run-make/prune-link-args/Makefile
deleted file mode 100644
index c21ba6ace38..00000000000
--- a/tests/run-make/prune-link-args/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-# ignore-windows
-
-# Notice the space in the end, this emulates the output of pkg-config
-RUSTC_FLAGS = -C link-args="-lc "
-
-all:
-	$(RUSTC) $(RUSTC_FLAGS) empty.rs
diff --git a/tests/run-make/prune-link-args/rmake.rs b/tests/run-make/prune-link-args/rmake.rs
new file mode 100644
index 00000000000..ea4ffa732bf
--- /dev/null
+++ b/tests/run-make/prune-link-args/rmake.rs
@@ -0,0 +1,17 @@
+// Passing link-args with an unexpected space
+// could result in the flag being parsed and receiving
+// an unexpected, empty linker argument. This test
+// ensures successful compilation even when a space is
+// present.
+// See https://github.com/rust-lang/rust/pull/10749
+
+//@ ignore-cross-compile
+//@ ignore-windows-gnu
+// Reason: The space is parsed as an empty linker argument on windows-gnu.
+
+use run_make_support::rustc;
+
+fn main() {
+    // Notice the space at the end of -lc, which emulates the output of pkg-config.
+    rustc().arg("-Clink-args=-lc ").input("empty.rs").run();
+}
diff --git a/tests/run-make/raw-dylib-custom-dlltool/Makefile b/tests/run-make/raw-dylib-custom-dlltool/Makefile
deleted file mode 100644
index f5d5360a3fb..00000000000
--- a/tests/run-make/raw-dylib-custom-dlltool/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# Test using -Cdlltool to change where raw-dylib looks for the dlltool binary.
-
-# only-windows
-# only-gnu
-# needs-dlltool
-
-include ../tools.mk
-
-all:
-	$(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs -Cdlltool=$(CURDIR)/script.cmd
-	$(DIFF) output.txt "$(TMPDIR)"/output.txt
diff --git a/tests/run-make/raw-dylib-custom-dlltool/rmake.rs b/tests/run-make/raw-dylib-custom-dlltool/rmake.rs
new file mode 100644
index 00000000000..86b952f0b45
--- /dev/null
+++ b/tests/run-make/raw-dylib-custom-dlltool/rmake.rs
@@ -0,0 +1,24 @@
+// Instead of using the default dlltool, the rust compiler can also accept a custom
+// command file with the -C dlltool flag. This test uses it to compile some rust code
+// with the raw_dylib Windows-exclusive feature, and checks that the output contains
+// the string passed from the custom dlltool, confirming that the default dlltool was
+// successfully overridden.
+// See https://github.com/rust-lang/rust/pull/109677
+
+//@ only-windows
+//@ only-gnu
+//@ needs-dlltool
+// Reason: this test specifically checks the custom dlltool feature, only
+// available on Windows-gnu.
+
+use run_make_support::{diff, rustc};
+
+fn main() {
+    let out = rustc()
+        .crate_type("lib")
+        .crate_name("raw_dylib_test")
+        .input("lib.rs")
+        .arg("-Cdlltool=script.cmd")
+        .run();
+    diff().expected_file("output.txt").actual_file("actual.txt").normalize(r#"\r"#, "").run();
+}
diff --git a/tests/run-make/raw-dylib-custom-dlltool/script.cmd b/tests/run-make/raw-dylib-custom-dlltool/script.cmd
index 95f85c61c67..51834590be0 100644
--- a/tests/run-make/raw-dylib-custom-dlltool/script.cmd
+++ b/tests/run-make/raw-dylib-custom-dlltool/script.cmd
@@ -1,2 +1,2 @@
-echo Called dlltool via script.cmd> %TMPDIR%\output.txt
+echo Called dlltool via script.cmd> actual.txt
 dlltool.exe %*
diff --git a/tests/run-make/raw-dylib-inline-cross-dylib/Makefile b/tests/run-make/raw-dylib-inline-cross-dylib/Makefile
deleted file mode 100644
index 6b44b40e253..00000000000
--- a/tests/run-make/raw-dylib-inline-cross-dylib/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-# Regression test for calling an inline function that uses a raw-dylib function.
-
-# only-windows
-
-include ../tools.mk
-
-# We'd be using the llvm-objdump instead of the system objdump to ensure compatibility
-# with the LLVM bitcode generated by rustc but on Windows  piping/IO redirection under MSYS2 is wonky with llvm-objdump.
-OBJDUMP = objdump
-
-all:
-	$(RUSTC) --crate-type dylib --crate-name raw_dylib_test lib.rs -C prefer-dynamic
-	$(RUSTC) --crate-type dylib --crate-name raw_dylib_test_wrapper lib_wrapper.rs -C prefer-dynamic
-	$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)" -C prefer-dynamic
-	# Make sure we don't find an import to the functions we expect to be inlined.
-	$(OBJDUMP) -p $(TMPDIR)/driver.exe | $(CGREP) -v -e "inline_library_function"
-	$(OBJDUMP) -p $(TMPDIR)/driver.exe | $(CGREP) -v -e "inline_library_function_calls_inline"
-	# Make sure we do find an import to the functions we expect to be imported.
-	$(OBJDUMP) -p $(TMPDIR)/driver.exe | $(CGREP) -e "library_function"
-	$(call COMPILE_OBJ,"$(TMPDIR)"/extern_1.obj,extern_1.c)
-	$(call COMPILE_OBJ,"$(TMPDIR)"/extern_2.obj,extern_2.c)
-ifdef IS_MSVC
-	$(CC) "$(TMPDIR)"/extern_1.obj -link -dll -out:"$(TMPDIR)"/extern_1.dll -noimplib
-	$(CC) "$(TMPDIR)"/extern_2.obj -link -dll -out:"$(TMPDIR)"/extern_2.dll -noimplib
-else
-	$(CC) "$(TMPDIR)"/extern_1.obj -shared -o "$(TMPDIR)"/extern_1.dll
-	$(CC) "$(TMPDIR)"/extern_2.obj -shared -o "$(TMPDIR)"/extern_2.dll
-endif
-	$(call RUN,driver) | tr -d '\r' > "$(TMPDIR)"/output.txt
-	$(RUSTC_TEST_OP) "$(TMPDIR)"/output.txt output.txt
diff --git a/tests/run-make/raw-dylib-inline-cross-dylib/rmake.rs b/tests/run-make/raw-dylib-inline-cross-dylib/rmake.rs
new file mode 100644
index 00000000000..6e3b31a0cdb
--- /dev/null
+++ b/tests/run-make/raw-dylib-inline-cross-dylib/rmake.rs
@@ -0,0 +1,61 @@
+// When we generate the import library for a dylib or bin crate, we should generate it
+// for the symbols both for the current crate and all upstream crates. This allows for
+// using the link kind `raw-dylib` inside inline functions successfully. This test checks
+// that the import symbols in the object files match this convention, and that execution
+// of the binary results in all function names exported successfully.
+// See https://github.com/rust-lang/rust/pull/102988
+
+//@ only-windows
+
+use run_make_support::{cc, diff, is_msvc, llvm_objdump, run, rustc};
+
+fn main() {
+    rustc()
+        .crate_type("dylib")
+        .crate_name("raw_dylib_test")
+        .input("lib.rs")
+        .arg("-Cprefer-dynamic")
+        .run();
+    rustc()
+        .crate_type("dylib")
+        .crate_name("raw_dylib_test_wrapper")
+        .input("lib_wrapper.rs")
+        .arg("-Cprefer-dynamic")
+        .run();
+    rustc().crate_type("bin").input("driver.rs").arg("-Cprefer-dynamic").run();
+    llvm_objdump()
+        .arg("--private-headers")
+        .input("driver.exe")
+        .run()
+        // Make sure we don't find an import to the functions we expect to be inlined.
+        .assert_stdout_not_contains("inline_library_function")
+        // Make sure we do find an import to the functions we expect to be imported.
+        .assert_stdout_contains("library_function");
+    if is_msvc() {
+        cc().arg("-c").out_exe("extern_1").input("extern_1.c").run();
+        cc().arg("-c").out_exe("extern_2").input("extern_2.c").run();
+        cc().input("extern_1.obj")
+            .arg("-link")
+            .arg("-dll")
+            .arg("-out:extern_1.dll")
+            .arg("-noimplib")
+            .run();
+        cc().input("extern_2.obj")
+            .arg("-link")
+            .arg("-dll")
+            .arg("-out:extern_2.dll")
+            .arg("-noimplib")
+            .run();
+    } else {
+        cc().arg("-v").arg("-c").out_exe("extern_1").input("extern_1.c").run();
+        cc().arg("-v").arg("-c").out_exe("extern_2").input("extern_2.c").run();
+        cc().input("extern_1").out_exe("extern_1.dll").arg("-shared").run();
+        cc().input("extern_2").out_exe("extern_2.dll").arg("-shared").run();
+    }
+    let out = run("driver").stdout_utf8();
+    diff()
+        .expected_file("output.txt")
+        .actual_text("actual_output", out)
+        .normalize(r#"\r"#, "")
+        .run();
+}
diff --git a/tests/rustdoc-ui/track-diagnostics.stderr b/tests/rustdoc-ui/track-diagnostics.stderr
index 131adfd588c..f7f3e368a3c 100644
--- a/tests/rustdoc-ui/track-diagnostics.stderr
+++ b/tests/rustdoc-ui/track-diagnostics.stderr
@@ -3,7 +3,7 @@ error[E0308]: mismatched types
    |
 LL | const S: A = B;
    |              ^ expected `A`, found `B`
--Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC
+-Ztrack-diagnostics: created at compiler/rustc_infer/src/error_reporting/infer/mod.rs:LL:CC
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/delegation/bad-resolve.rs b/tests/ui/delegation/bad-resolve.rs
index f378e05304b..f15e6aa81af 100644
--- a/tests/ui/delegation/bad-resolve.rs
+++ b/tests/ui/delegation/bad-resolve.rs
@@ -34,6 +34,9 @@ impl Trait for S {
 
     reuse foo { &self.0 }
     //~^ ERROR cannot find function `foo` in this scope
+    reuse Trait::foo2 { self.0 }
+    //~^ ERROR cannot find function `foo2` in trait `Trait`
+    //~| ERROR method `foo2` is not a member of trait `Trait`
 }
 
 mod prefix {}
diff --git a/tests/ui/delegation/bad-resolve.stderr b/tests/ui/delegation/bad-resolve.stderr
index 883ff523bcf..32d2f3b26cb 100644
--- a/tests/ui/delegation/bad-resolve.stderr
+++ b/tests/ui/delegation/bad-resolve.stderr
@@ -25,6 +25,15 @@ LL |     reuse <F as Trait>::baz;
    |     |                   help: there is an associated function with a similar name: `bar`
    |     not a member of trait `Trait`
 
+error[E0407]: method `foo2` is not a member of trait `Trait`
+  --> $DIR/bad-resolve.rs:37:5
+   |
+LL |     reuse Trait::foo2 { self.0 }
+   |     ^^^^^^^^^^^^^----^^^^^^^^^^^
+   |     |            |
+   |     |            help: there is an associated function with a similar name: `foo`
+   |     not a member of trait `Trait`
+
 error[E0423]: expected function, found associated constant `Trait::C`
   --> $DIR/bad-resolve.rs:24:11
    |
@@ -54,6 +63,15 @@ error[E0425]: cannot find function `foo` in this scope
 LL |     reuse foo { &self.0 }
    |           ^^^ not found in this scope
 
+error[E0425]: cannot find function `foo2` in trait `Trait`
+  --> $DIR/bad-resolve.rs:37:18
+   |
+LL |     fn foo(&self, x: i32) -> i32 { x }
+   |     ---------------------------- similarly named associated function `foo` defined here
+...
+LL |     reuse Trait::foo2 { self.0 }
+   |                  ^^^^ help: an associated function with a similar name exists: `foo`
+
 error[E0046]: not all trait items implemented, missing: `Type`
   --> $DIR/bad-resolve.rs:22:1
    |
@@ -64,18 +82,18 @@ LL | impl Trait for S {
    | ^^^^^^^^^^^^^^^^ missing `Type` in implementation
 
 error[E0433]: failed to resolve: use of undeclared crate or module `unresolved_prefix`
-  --> $DIR/bad-resolve.rs:40:7
+  --> $DIR/bad-resolve.rs:43:7
    |
 LL | reuse unresolved_prefix::{a, b, c};
    |       ^^^^^^^^^^^^^^^^^ use of undeclared crate or module `unresolved_prefix`
 
 error[E0433]: failed to resolve: `crate` in paths can only be used in start position
-  --> $DIR/bad-resolve.rs:41:29
+  --> $DIR/bad-resolve.rs:44:29
    |
 LL | reuse prefix::{self, super, crate};
    |                             ^^^^^ `crate` in paths can only be used in start position
 
-error: aborting due to 10 previous errors
+error: aborting due to 12 previous errors
 
 Some errors have detailed explanations: E0046, E0324, E0407, E0423, E0425, E0433, E0575, E0576.
 For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/delegation/explicit-paths-pass.rs b/tests/ui/delegation/explicit-paths-pass.rs
index fada793bd11..dd0ee2c732f 100644
--- a/tests/ui/delegation/explicit-paths-pass.rs
+++ b/tests/ui/delegation/explicit-paths-pass.rs
@@ -24,8 +24,8 @@ reuse to_reuse::zero_args { self }
 
 struct S(F);
 impl Trait for S {
-    reuse Trait::bar { &self.0 }
-    reuse Trait::description { &self.0 }
+    reuse Trait::bar { self.0 }
+    reuse Trait::description { self.0 }
     reuse <F as Trait>::static_method;
     reuse <F as Trait>::static_method2 { S::static_method(self) }
 }
diff --git a/tests/ui/delegation/explicit-paths.rs b/tests/ui/delegation/explicit-paths.rs
index a91ca4cb931..d42e305b252 100644
--- a/tests/ui/delegation/explicit-paths.rs
+++ b/tests/ui/delegation/explicit-paths.rs
@@ -34,7 +34,7 @@ mod inherent_impl_assoc_fn_to_other {
     use crate::*;
 
     impl S {
-        reuse Trait::foo1 { &self.0 }
+        reuse Trait::foo1 { self.0 }
         reuse <S as Trait>::foo2;
         reuse to_reuse::foo3;
         reuse F::foo4 { &self.0 }
@@ -46,7 +46,7 @@ mod trait_impl_assoc_fn_to_other {
     use crate::*;
 
     impl Trait for S {
-        reuse Trait::foo1 { &self.0 }
+        reuse Trait::foo1 { self.0 }
         reuse <F as Trait>::foo2;
         reuse to_reuse::foo3;
         //~^ ERROR method `foo3` is not a member of trait `Trait`
diff --git a/tests/ui/delegation/explicit-paths.stderr b/tests/ui/delegation/explicit-paths.stderr
index d33c5da4377..b5afe19f878 100644
--- a/tests/ui/delegation/explicit-paths.stderr
+++ b/tests/ui/delegation/explicit-paths.stderr
@@ -91,10 +91,17 @@ error[E0308]: mismatched types
 LL |     trait Trait2 : Trait {
    |     -------------------- found this type parameter
 LL |         reuse <F as Trait>::foo1 { self }
-   |                                    ^^^^ expected `&F`, found `&Self`
+   |                             ----   ^^^^ expected `&F`, found `&Self`
+   |                             |
+   |                             arguments to this function are incorrect
    |
    = note: expected reference `&F`
               found reference `&Self`
+note: method defined here
+  --> $DIR/explicit-paths.rs:5:8
+   |
+LL |     fn foo1(&self, x: i32) -> i32 { x }
+   |        ^^^^ -----
 
 error[E0277]: the trait bound `S2: Trait` is not satisfied
   --> $DIR/explicit-paths.rs:78:16
diff --git a/tests/ui/delegation/ice-issue-122550.stderr b/tests/ui/delegation/ice-issue-122550.stderr
index c92170644e7..1a01bee3e1e 100644
--- a/tests/ui/delegation/ice-issue-122550.stderr
+++ b/tests/ui/delegation/ice-issue-122550.stderr
@@ -4,15 +4,6 @@ error[E0308]: mismatched types
 LL |     fn description(&self) -> &str {}
    |                                   ^^ expected `&str`, found `()`
 
-error[E0308]: mismatched types
-  --> $DIR/ice-issue-122550.rs:13:39
-   |
-LL |     reuse <S as Trait>::description { &self.0 }
-   |                                       ^^^^^^^ expected `&S`, found `&F`
-   |
-   = note: expected reference `&S`
-              found reference `&F`
-
 error[E0277]: the trait bound `S: Trait` is not satisfied
   --> $DIR/ice-issue-122550.rs:13:12
    |
@@ -25,6 +16,22 @@ help: this trait has no implementations, consider adding one
 LL | trait Trait {
    | ^^^^^^^^^^^
 
+error[E0308]: mismatched types
+  --> $DIR/ice-issue-122550.rs:13:39
+   |
+LL |     reuse <S as Trait>::description { &self.0 }
+   |                         -----------   ^^^^^^^ expected `&S`, found `&F`
+   |                         |
+   |                         arguments to this function are incorrect
+   |
+   = note: expected reference `&S`
+              found reference `&F`
+note: method defined here
+  --> $DIR/ice-issue-122550.rs:5:8
+   |
+LL |     fn description(&self) -> &str {}
+   |        ^^^^^^^^^^^ -----
+
 error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
diff --git a/tests/ui/delegation/method-call-choice.rs b/tests/ui/delegation/method-call-choice.rs
new file mode 100644
index 00000000000..8d53d8bfdb7
--- /dev/null
+++ b/tests/ui/delegation/method-call-choice.rs
@@ -0,0 +1,25 @@
+#![feature(fn_delegation)]
+#![allow(incomplete_features)]
+
+trait Trait {
+    fn foo(&self) {}
+}
+
+struct F;
+impl Trait for F {}
+struct S(F);
+
+pub mod to_reuse {
+    use crate::F;
+
+    pub fn foo(_: &F) {}
+}
+
+impl Trait for S {
+    // Make sure that the method call is not generated if the path resolution
+    // does not have a `self` parameter.
+    reuse to_reuse::foo { self.0 }
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/delegation/method-call-choice.stderr b/tests/ui/delegation/method-call-choice.stderr
new file mode 100644
index 00000000000..6757af20a6b
--- /dev/null
+++ b/tests/ui/delegation/method-call-choice.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+  --> $DIR/method-call-choice.rs:21:27
+   |
+LL |     reuse to_reuse::foo { self.0 }
+   |                     ---   ^^^^^^ expected `&F`, found `F`
+   |                     |
+   |                     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/method-call-choice.rs:15:12
+   |
+LL |     pub fn foo(_: &F) {}
+   |            ^^^ -----
+help: consider borrowing here
+   |
+LL |     reuse to_reuse::foo { &self.0 }
+   |                           +
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/delegation/method-call-priority.rs b/tests/ui/delegation/method-call-priority.rs
new file mode 100644
index 00000000000..8d68740d181
--- /dev/null
+++ b/tests/ui/delegation/method-call-priority.rs
@@ -0,0 +1,34 @@
+//@ run-pass
+
+#![feature(fn_delegation)]
+#![allow(incomplete_features)]
+#![allow(dead_code)]
+
+trait Trait1 {
+    fn foo(&self) -> i32 { 1 }
+}
+
+trait Trait2 {
+    fn foo(&self) -> i32 { 2 }
+}
+
+struct F;
+impl Trait1 for F {}
+impl Trait2 for F {}
+
+impl F {
+    fn foo(&self) -> i32 { 3 }
+}
+
+struct S(F);
+
+impl Trait1 for S {
+    // Make sure that the generated `self.0.foo()` does not turn into the inherent method `F::foo`
+    // that has a higher priority than methods from traits.
+    reuse Trait1::foo { self.0 }
+}
+
+fn main() {
+    let s = S(F);
+    assert_eq!(s.foo(), 1);
+}
diff --git a/tests/ui/delegation/self-coercion.rs b/tests/ui/delegation/self-coercion.rs
new file mode 100644
index 00000000000..96c1f1b140b
--- /dev/null
+++ b/tests/ui/delegation/self-coercion.rs
@@ -0,0 +1,26 @@
+//@ run-pass
+
+#![feature(fn_delegation)]
+#![allow(incomplete_features)]
+
+trait Trait : Sized {
+    fn by_value(self) -> i32 { 1 }
+    fn by_mut_ref(&mut self) -> i32 { 2 }
+    fn by_ref(&self) -> i32 { 3 }
+}
+
+struct F;
+impl Trait for F {}
+
+struct S(F);
+
+impl Trait for S {
+    reuse Trait::{by_value, by_mut_ref, by_ref} { self.0 }
+}
+
+fn main() {
+    let mut s = S(F);
+    assert_eq!(s.by_ref(), 3);
+    assert_eq!(s.by_mut_ref(), 2);
+    assert_eq!(s.by_value(), 1);
+}
diff --git a/tests/ui/parser/cfg-keyword-lifetime.rs b/tests/ui/parser/cfg-keyword-lifetime.rs
new file mode 100644
index 00000000000..a1588eddc07
--- /dev/null
+++ b/tests/ui/parser/cfg-keyword-lifetime.rs
@@ -0,0 +1,15 @@
+// Disallow `'keyword` even in cfg'd code.
+
+#[cfg(any())]
+fn hello() -> &'ref () {}
+//~^ ERROR lifetimes cannot use keyword names
+
+macro_rules! macro_invocation {
+    ($i:item) => {}
+}
+macro_invocation! {
+    fn hello() -> &'ref () {}
+    //~^ ERROR lifetimes cannot use keyword names
+}
+
+fn main() {}
diff --git a/tests/ui/parser/cfg-keyword-lifetime.stderr b/tests/ui/parser/cfg-keyword-lifetime.stderr
new file mode 100644
index 00000000000..52d305e2521
--- /dev/null
+++ b/tests/ui/parser/cfg-keyword-lifetime.stderr
@@ -0,0 +1,14 @@
+error: lifetimes cannot use keyword names
+  --> $DIR/cfg-keyword-lifetime.rs:4:16
+   |
+LL | fn hello() -> &'ref () {}
+   |                ^^^^
+
+error: lifetimes cannot use keyword names
+  --> $DIR/cfg-keyword-lifetime.rs:11:20
+   |
+LL |     fn hello() -> &'ref () {}
+   |                    ^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/parser/require-parens-for-chained-comparison.rs b/tests/ui/parser/require-parens-for-chained-comparison.rs
index 5b90e905a64..916f1b83db2 100644
--- a/tests/ui/parser/require-parens-for-chained-comparison.rs
+++ b/tests/ui/parser/require-parens-for-chained-comparison.rs
@@ -24,12 +24,14 @@ fn main() {
     //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
     //~| ERROR expected
     //~| HELP add `'` to close the char literal
+    //~| ERROR invalid label name
 
     f<'_>();
     //~^ comparison operators cannot be chained
     //~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
     //~| ERROR expected
     //~| HELP add `'` to close the char literal
+    //~| ERROR invalid label name
 
     let _ = f<u8>;
     //~^ ERROR comparison operators cannot be chained
diff --git a/tests/ui/parser/require-parens-for-chained-comparison.stderr b/tests/ui/parser/require-parens-for-chained-comparison.stderr
index 52e201c435c..857c4a55788 100644
--- a/tests/ui/parser/require-parens-for-chained-comparison.stderr
+++ b/tests/ui/parser/require-parens-for-chained-comparison.stderr
@@ -53,6 +53,12 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum
 LL |     let _ = f::<u8, i8>();
    |              ++
 
+error: invalid label name `'_`
+  --> $DIR/require-parens-for-chained-comparison.rs:22:15
+   |
+LL |     let _ = f<'_, i8>();
+   |               ^^
+
 error: expected `while`, `for`, `loop` or `{` after a label
   --> $DIR/require-parens-for-chained-comparison.rs:22:17
    |
@@ -75,8 +81,14 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum
 LL |     let _ = f::<'_, i8>();
    |              ++
 
+error: invalid label name `'_`
+  --> $DIR/require-parens-for-chained-comparison.rs:29:7
+   |
+LL |     f<'_>();
+   |       ^^
+
 error: expected `while`, `for`, `loop` or `{` after a label
-  --> $DIR/require-parens-for-chained-comparison.rs:28:9
+  --> $DIR/require-parens-for-chained-comparison.rs:29:9
    |
 LL |     f<'_>();
    |         ^ expected `while`, `for`, `loop` or `{` after a label
@@ -87,7 +99,7 @@ LL |     f<'_'>();
    |         +
 
 error: comparison operators cannot be chained
-  --> $DIR/require-parens-for-chained-comparison.rs:28:6
+  --> $DIR/require-parens-for-chained-comparison.rs:29:6
    |
 LL |     f<'_>();
    |      ^  ^
@@ -98,7 +110,7 @@ LL |     f::<'_>();
    |      ++
 
 error: comparison operators cannot be chained
-  --> $DIR/require-parens-for-chained-comparison.rs:34:14
+  --> $DIR/require-parens-for-chained-comparison.rs:36:14
    |
 LL |     let _ = f<u8>;
    |              ^  ^
@@ -106,5 +118,5 @@ LL |     let _ = f<u8>;
    = help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
    = help: or use `(...)` if you meant to specify fn arguments
 
-error: aborting due to 10 previous errors
+error: aborting due to 12 previous errors
 
diff --git a/tests/ui/self/self_type_keyword.stderr b/tests/ui/self/self_type_keyword.stderr
index 8298293a8cb..f9cde810cad 100644
--- a/tests/ui/self/self_type_keyword.stderr
+++ b/tests/ui/self/self_type_keyword.stderr
@@ -4,6 +4,12 @@ error: expected identifier, found keyword `Self`
 LL |   struct Self;
    |          ^^^^ expected identifier, found keyword
 
+error: lifetimes cannot use keyword names
+  --> $DIR/self_type_keyword.rs:6:12
+   |
+LL | struct Bar<'Self>;
+   |            ^^^^^
+
 error: expected identifier, found keyword `Self`
   --> $DIR/self_type_keyword.rs:14:13
    |
@@ -53,12 +59,6 @@ error: expected identifier, found keyword `Self`
 LL |     trait Self {}
    |           ^^^^ expected identifier, found keyword
 
-error: lifetimes cannot use keyword names
-  --> $DIR/self_type_keyword.rs:6:12
-   |
-LL | struct Bar<'Self>;
-   |            ^^^^^
-
 error: cannot find macro `Self` in this scope
   --> $DIR/self_type_keyword.rs:21:9
    |