about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-12-05 12:55:36 +0000
committerbors <bors@rust-lang.org>2022-12-05 12:55:36 +0000
commit552b63c1619498f1a17fd482f4bb87815d8fdc48 (patch)
tree3463b86894affc4a8aee0f10ac9dcfbe0cdc4de1
parentfaec28970f86f52ca37e0e8cec0a447ba2f1393b (diff)
parent7481ba7746fc5f5b82aaff0fe20cbf55c48d8fd9 (diff)
downloadrust-552b63c1619498f1a17fd482f4bb87815d8fdc48.tar.gz
rust-552b63c1619498f1a17fd482f4bb87815d8fdc48.zip
Auto merge of #2715 - RalfJung:rustup, r=RalfJung
Rustup
-rw-r--r--.github/workflows/ci.yml12
-rw-r--r--Cargo.lock32
-rw-r--r--LICENSES/LLVM-exception.txt15
-rw-r--r--compiler/rustc_abi/src/layout.rs10
-rw-r--r--compiler/rustc_ast/src/ast.rs8
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs4
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs8
-rw-r--r--compiler/rustc_ast/src/util/classify.rs1
-rw-r--r--compiler/rustc_ast/src/util/comments.rs4
-rw-r--r--compiler/rustc_ast/src/util/literal.rs10
-rw-r--r--compiler/rustc_ast/src/util/parser.rs6
-rw-r--r--compiler/rustc_ast/src/util/unicode.rs2
-rw-r--r--compiler/rustc_ast/src/visit.rs1
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs7
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs10
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs16
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs24
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs7
-rw-r--r--compiler/rustc_borrowck/src/nll.rs10
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.lock6
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.toml1
-rw-r--r--compiler/rustc_codegen_cranelift/src/archive.rs224
-rw-r--r--compiler/rustc_codegen_gcc/Cargo.lock14
-rw-r--r--compiler/rustc_codegen_gcc/Cargo.toml4
-rw-r--r--compiler/rustc_codegen_gcc/src/archive.rs177
-rw-r--r--compiler/rustc_codegen_gcc/src/errors.rs16
-rw-r--r--compiler/rustc_codegen_llvm/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs13
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs131
-rw-r--r--compiler/rustc_codegen_llvm/src/errors.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs13
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs5
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs231
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs27
-rw-r--r--compiler/rustc_data_structures/src/intern.rs4
-rw-r--r--compiler/rustc_data_structures/src/memmap.rs10
-rw-r--r--compiler/rustc_data_structures/src/owning_ref/mod.rs24
-rw-r--r--compiler/rustc_data_structures/src/profiling.rs6
-rw-r--r--compiler/rustc_data_structures/src/stable_hasher.rs6
-rw-r--r--compiler/rustc_data_structures/src/sync.rs2
-rw-r--r--compiler/rustc_driver/src/lib.rs6
-rw-r--r--compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl3
-rw-r--r--compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl6
-rw-r--r--compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl6
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs6
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs2
-rw-r--r--compiler/rustc_errors/src/emitter.rs26
-rw-r--r--compiler/rustc_errors/src/json.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs3
-rw-r--r--compiler/rustc_errors/src/translation.rs6
-rw-r--r--compiler/rustc_expand/src/build.rs3
-rw-r--r--compiler/rustc_fs_util/src/lib.rs2
-rw-r--r--compiler/rustc_graphviz/src/lib.rs6
-rw-r--r--compiler/rustc_hir/src/hir.rs5
-rw-r--r--compiler/rustc_hir/src/hir_id.rs2
-rw-r--r--compiler/rustc_hir/src/intravisit.rs37
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_method.rs39
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs47
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs33
-rw-r--r--compiler/rustc_hir_analysis/src/check_unused.rs19
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs5
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs16
-rw-r--r--compiler/rustc_hir_typeck/src/inherited.rs29
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs20
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs64
-rw-r--r--compiler/rustc_infer/src/infer/at.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs19
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs33
-rw-r--r--compiler/rustc_interface/src/passes.rs5
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_lexer/Cargo.toml2
-rw-r--r--compiler/rustc_lint/src/early.rs93
-rw-r--r--compiler/rustc_lint/src/late.rs100
-rw-r--r--compiler/rustc_lint/src/lib.rs275
-rw-r--r--compiler/rustc_lint/src/passes.rs25
-rw-r--r--compiler/rustc_llvm/build.rs1
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp4
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp96
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic.rs26
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs14
-rw-r--r--compiler/rustc_macros/src/diagnostics/subdiagnostic.rs4
-rw-r--r--compiler/rustc_macros/src/diagnostics/utils.rs20
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs41
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs32
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs13
-rw-r--r--compiler/rustc_middle/src/query/mod.rs1
-rw-r--r--compiler/rustc_middle/src/ty/context.rs8
-rw-r--r--compiler/rustc_middle/src/ty/query.rs6
-rw-r--r--compiler/rustc_middle/src/values.rs20
-rw-r--r--compiler/rustc_mir_build/src/build/custom/mod.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/engine.rs9
-rw-r--r--compiler/rustc_mir_transform/src/coverage/debug.rs4
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/dump_mir.rs5
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs8
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs4
-rw-r--r--compiler/rustc_mir_transform/src/pass_manager.rs33
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs5
-rw-r--r--compiler/rustc_mir_transform/src/simplify_branches.rs6
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs10
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs43
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs3
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs11
-rw-r--r--compiler/rustc_resolve/src/imports.rs21
-rw-r--r--compiler/rustc_resolve/src/late.rs28
-rw-r--r--compiler/rustc_session/src/cgu_reuse_tracker.rs2
-rw-r--r--compiler/rustc_session/src/config.rs12
-rw-r--r--compiler/rustc_session/src/errors.rs2
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_span/src/analyze_source_file.rs2
-rw-r--r--compiler/rustc_span/src/caching_source_map_view.rs2
-rw-r--r--compiler/rustc_span/src/hygiene.rs2
-rw-r--r--compiler/rustc_span/src/lib.rs2
-rw-r--r--compiler/rustc_span/src/span_encoding.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/sparc64.rs4
-rw-r--r--compiler/rustc_target/src/spec/aarch64_apple_darwin.rs4
-rw-r--r--compiler/rustc_target/src/spec/apple/tests.rs19
-rw-r--r--compiler/rustc_target/src/spec/apple_base.rs54
-rw-r--r--compiler/rustc_target/src/spec/i686_apple_darwin.rs3
-rw-r--r--compiler/rustc_target/src/spec/mod.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_darwin.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs18
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs102
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs40
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs35
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs17
-rw-r--r--library/alloc/src/vec/mod.rs11
-rw-r--r--library/core/src/num/nonzero.rs3
-rw-r--r--library/core/src/panicking.rs25
-rw-r--r--library/core/src/slice/index.rs21
-rw-r--r--library/std/src/fs.rs5
-rw-r--r--library/std/src/panicking.rs4
-rw-r--r--library/test/src/cli.rs5
-rw-r--r--library/test/src/console.rs2
-rw-r--r--library/test/src/lib.rs20
-rw-r--r--library/test/src/tests.rs1
-rw-r--r--src/bootstrap/Cargo.lock56
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/bootstrap/lib.rs17
-rw-r--r--src/ci/github-actions/ci.yml2
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/clean/mod.rs124
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css39
-rw-r--r--src/librustdoc/json/mod.rs53
-rw-r--r--src/librustdoc/lib.rs5
-rw-r--r--src/librustdoc/passes/bare_urls.rs110
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs209
-rw-r--r--src/librustdoc/passes/lint.rs33
-rw-r--r--src/librustdoc/passes/lint/bare_urls.rs89
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs170
-rw-r--r--src/librustdoc/passes/lint/html_tags.rs (renamed from src/librustdoc/passes/html_tags.rs)309
-rw-r--r--src/librustdoc/passes/mod.rs18
-rw-r--r--src/test/assembly/asm/aarch64-el2vmsa.rs37
-rw-r--r--src/test/assembly/sparc-struct-abi.rs5
-rw-r--r--src/test/codegen/enum-match.rs7
-rw-r--r--src/test/codegen/naked-nocoverage.rs19
-rw-r--r--src/test/run-make/macos-deployment-target/Makefile21
-rw-r--r--src/test/run-make/macos-deployment-target/with_deployment_target.rs4
-rw-r--r--src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs8
-rw-r--r--src/test/rustdoc-json/intra-doc-links/foreign_variant.rs13
-rw-r--r--src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs2
-rw-r--r--src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs10
-rw-r--r--src/test/rustdoc-json/traits/uses_extern_trait.rs11
-rw-r--r--src/test/rustdoc-ui/issue-91713.stdout8
-rw-r--r--src/test/rustdoc-ui/z-help.stdout1
-rw-r--r--src/test/rustdoc/bounds-in-multiple-parts.rs20
-rw-r--r--src/test/rustdoc/impl-parts.rs4
-rw-r--r--src/test/rustdoc/rfc-2632-const-trait-impl.rs2
-rw-r--r--src/test/rustdoc/whitespace-after-where-clause.enum.html2
-rw-r--r--src/test/rustdoc/whitespace-after-where-clause.struct.html2
-rw-r--r--src/test/rustdoc/whitespace-after-where-clause.union.html2
-rw-r--r--src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr16
-rw-r--r--src/test/ui-fulldeps/lint-plugin-deny-attr.stderr16
-rw-r--r--src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr16
-rw-r--r--src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs1
-rw-r--r--src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr27
-rw-r--r--src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs2
-rw-r--r--src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr26
-rw-r--r--src/test/ui-fulldeps/lint-plugin.stderr16
-rw-r--r--src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr22
-rw-r--r--src/test/ui-fulldeps/lint-tool-test.rs3
-rw-r--r--src/test/ui-fulldeps/lint-tool-test.stderr70
-rw-r--r--src/test/ui-fulldeps/pprust-expr-roundtrip.rs1
-rw-r--r--src/test/ui/associated-consts/issue-47814.rs14
-rw-r--r--src/test/ui/associated-consts/issue-47814.stderr14
-rw-r--r--src/test/ui/associated-inherent-types/struct-generics.rs15
-rw-r--r--src/test/ui/async-await/generator-not-future.rs45
-rw-r--r--src/test/ui/async-await/generator-not-future.stderr81
-rw-r--r--src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr8
-rw-r--r--src/test/ui/async-await/in-trait/async-generics.stderr8
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs3
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr23
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes.rs3
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes.stderr23
-rw-r--r--src/test/ui/async-await/in-trait/implied-bounds.rs13
-rw-r--r--src/test/ui/async-await/in-trait/lifetime-mismatch.rs20
-rw-r--r--src/test/ui/async-await/in-trait/lifetime-mismatch.stderr21
-rw-r--r--src/test/ui/attributes/unused-item-in-attr.rs6
-rw-r--r--src/test/ui/attributes/unused-item-in-attr.stderr16
-rw-r--r--src/test/ui/drop/drop_order.rs97
-rw-r--r--src/test/ui/drop/issue-103107.rs37
-rw-r--r--src/test/ui/enum-discriminant/issue-104519.rs36
-rw-r--r--src/test/ui/fn/signature-error-reporting-under-verbose.rs15
-rw-r--r--src/test/ui/fn/signature-error-reporting-under-verbose.stderr19
-rw-r--r--src/test/ui/impl-trait/in-trait/where-clause.rs24
-rw-r--r--src/test/ui/inline-const/expr-with-block-err.rs6
-rw-r--r--src/test/ui/inline-const/expr-with-block-err.stderr9
-rw-r--r--src/test/ui/inline-const/expr-with-block.rs10
-rw-r--r--src/test/ui/issues/issue-35976.rs14
-rw-r--r--src/test/ui/issues/issue-35976.unimported.stderr (renamed from src/test/ui/issues/issue-35976.stderr)7
-rw-r--r--src/test/ui/lint/issue-97094.nointerleaved.stderr53
-rw-r--r--src/test/ui/lint/issue-97094.rs9
-rw-r--r--src/test/ui/lint/issue-97094.stderr (renamed from src/test/ui/lint/issue-97094.interleaved.stderr)16
-rw-r--r--src/test/ui/macros/issue-103529.rs13
-rw-r--r--src/test/ui/macros/issue-103529.stderr39
-rw-r--r--src/test/ui/query-system/fn-sig-cycle-arity.rs8
-rw-r--r--src/test/ui/query-system/fn-sig-cycle-arity.stderr9
-rw-r--r--src/test/ui/resolve/bad-module.stderr12
-rw-r--r--src/test/ui/resolve/issue-101749-2.rs16
-rw-r--r--src/test/ui/resolve/issue-101749-2.stderr9
-rw-r--r--src/test/ui/resolve/issue-101749.fixed19
-rw-r--r--src/test/ui/resolve/issue-101749.rs19
-rw-r--r--src/test/ui/resolve/issue-101749.stderr14
-rw-r--r--src/test/ui/resolve/issue-105069.rs11
-rw-r--r--src/test/ui/resolve/issue-105069.stderr21
-rw-r--r--src/test/ui/resolve/issue-24968.stderr24
-rw-r--r--src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr42
-rw-r--r--src/test/ui/resolve/use_suggestion.stderr12
-rw-r--r--src/test/ui/return/tail-expr-as-potential-return.rs17
-rw-r--r--src/test/ui/return/tail-expr-as-potential-return.stderr21
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-79450.rs20
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-79450.stderr12
-rw-r--r--src/test/ui/suggestions/assoc-const-as-fn.rs18
-rw-r--r--src/test/ui/suggestions/assoc-const-as-fn.stderr14
-rw-r--r--src/test/ui/suggestions/crate-or-module-typo.stderr12
-rw-r--r--src/test/ui/suggestions/dont-suggest-ufcs-for-const.stderr8
-rw-r--r--src/test/ui/trait-bounds/impl-bound-with-references-error.rs20
-rw-r--r--src/test/ui/trait-bounds/impl-bound-with-references-error.stderr24
m---------src/tools/cargo0
-rw-r--r--src/tools/compiletest/src/main.rs1
-rw-r--r--src/tools/jsondoclint/src/validator.rs9
-rw-r--r--src/tools/jsondoclint/src/validator/tests.rs50
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/rustfmt/src/closures.rs1
-rw-r--r--src/tools/tidy/src/deps.rs28
261 files changed, 3308 insertions, 2590 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ebbed11d04b..b93166b80a5 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -309,7 +309,7 @@ jobs:
               NO_DEBUG_ASSERTIONS: 1
               NO_OVERFLOW_CHECKS: 1
               DIST_REQUIRE_ALL_TOOLS: 1
-            os: macos-latest
+            os: macos-12-xl
           - name: dist-apple-various
             env:
               SCRIPT: "./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim"
@@ -320,7 +320,7 @@ jobs:
               NO_LLVM_ASSERTIONS: 1
               NO_DEBUG_ASSERTIONS: 1
               NO_OVERFLOW_CHECKS: 1
-            os: macos-latest
+            os: macos-12-xl
           - name: dist-x86_64-apple-alt
             env:
               SCRIPT: "./x.py dist bootstrap --include-default-paths"
@@ -331,7 +331,7 @@ jobs:
               NO_LLVM_ASSERTIONS: 1
               NO_DEBUG_ASSERTIONS: 1
               NO_OVERFLOW_CHECKS: 1
-            os: macos-latest
+            os: macos-12-xl
           - name: x86_64-apple-1
             env:
               SCRIPT: "./x.py --stage 2 test --exclude src/test/ui --exclude src/test/rustdoc --exclude src/test/run-make-fulldeps"
@@ -342,7 +342,7 @@ jobs:
               NO_LLVM_ASSERTIONS: 1
               NO_DEBUG_ASSERTIONS: 1
               NO_OVERFLOW_CHECKS: 1
-            os: macos-latest
+            os: macos-12-xl
           - name: x86_64-apple-2
             env:
               SCRIPT: "./x.py --stage 2 test src/test/ui src/test/rustdoc src/test/run-make-fulldeps"
@@ -353,7 +353,7 @@ jobs:
               NO_LLVM_ASSERTIONS: 1
               NO_DEBUG_ASSERTIONS: 1
               NO_OVERFLOW_CHECKS: 1
-            os: macos-latest
+            os: macos-12-xl
           - name: dist-aarch64-apple
             env:
               SCRIPT: "./x.py dist bootstrap --include-default-paths --stage 2"
@@ -368,7 +368,7 @@ jobs:
               NO_OVERFLOW_CHECKS: 1
               DIST_REQUIRE_ALL_TOOLS: 1
               JEMALLOC_SYS_WITH_LG_PAGE: 14
-            os: macos-latest
+            os: macos-12-xl
           - name: x86_64-msvc-1
             env:
               RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-profiler"
diff --git a/Cargo.lock b/Cargo.lock
index 32dc32a9c07..dae79e5bc26 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -93,6 +93,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602"
 
 [[package]]
+name = "ar_archive_writer"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "276881980556fdadeb88aa1ffc667e4d2e8fe72531dfabcb7a82bb3c9ea9ba31"
+dependencies = [
+ "object",
+]
+
+[[package]]
 name = "array_tool"
 version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -906,9 +915,9 @@ version = "0.0.0"
 
 [[package]]
 name = "cpufeatures"
-version = "0.2.1"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
+checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
 dependencies = [
  "libc",
 ]
@@ -1086,12 +1095,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
 
 [[package]]
-name = "difference"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
-
-[[package]]
 name = "digest"
 version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1163,6 +1166,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "dissimilar"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c97b9233581d84b8e1e689cdd3a47b6f69770084fc246e86a7f78b0d9c1d4a5"
+
+[[package]]
 name = "dlmalloc"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1283,11 +1292,11 @@ dependencies = [
 
 [[package]]
 name = "expect-test"
-version = "1.0.1"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ceb96f3eaa0d4e8769c52dacfd4eb60183b817ed2f176171b3c691d5022b0f2e"
+checksum = "1d4661aca38d826eb7c72fe128e4238220616de4c0cc00db7bfc38e2e1364dd3"
 dependencies = [
- "difference",
+ "dissimilar",
  "once_cell",
 ]
 
@@ -3495,6 +3504,7 @@ dependencies = [
 name = "rustc_codegen_ssa"
 version = "0.0.0"
 dependencies = [
+ "ar_archive_writer",
  "bitflags",
  "cc",
  "itertools",
diff --git a/LICENSES/LLVM-exception.txt b/LICENSES/LLVM-exception.txt
new file mode 100644
index 00000000000..fa4b725a0ee
--- /dev/null
+++ b/LICENSES/LLVM-exception.txt
@@ -0,0 +1,15 @@
+---- LLVM Exceptions to the Apache 2.0 License ----
+
+   As an exception, if, as a result of your compiling your source code, portions
+   of this Software are embedded into an Object form of such source code, you
+   may redistribute such embedded portions in such Object form without complying
+   with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+   In addition, if you combine or link compiled forms of this Software with
+   software that is licensed under the GPLv2 ("Combined Software") and if a
+   court of competent jurisdiction determines that the patent provision (Section
+   3), the indemnity provision (Section 9) or other Section of the License
+   conflicts with the conditions of the GPLv2, you may retroactively and
+   prospectively choose to deem waived or otherwise exclude such Section(s) of
+   the License, but only in their entirety and only with respect to the Combined
+   Software.
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 11e7b80f85e..9c2cf58efed 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -354,7 +354,7 @@ pub trait LayoutCalculator {
                 if !always_sized { StructKind::MaybeUnsized } else { StructKind::AlwaysSized }
             };
 
-            let mut st = self.univariant(dl, &variants[v], &repr, kind)?;
+            let mut st = self.univariant(dl, &variants[v], repr, kind)?;
             st.variants = Variants::Single { index: v };
 
             if is_unsafe_cell {
@@ -457,7 +457,7 @@ pub trait LayoutCalculator {
             let mut variant_layouts = variants
                 .iter_enumerated()
                 .map(|(j, v)| {
-                    let mut st = self.univariant(dl, v, &repr, StructKind::AlwaysSized)?;
+                    let mut st = self.univariant(dl, v, repr, StructKind::AlwaysSized)?;
                     st.variants = Variants::Single { index: j };
 
                     align = align.max(st.align);
@@ -647,8 +647,8 @@ pub trait LayoutCalculator {
             .map(|(i, field_layouts)| {
                 let mut st = self.univariant(
                     dl,
-                    &field_layouts,
-                    &repr,
+                    field_layouts,
+                    repr,
                     StructKind::Prefixed(min_ity.size(), prefix_align),
                 )?;
                 st.variants = Variants::Single { index: i };
@@ -755,7 +755,7 @@ pub trait LayoutCalculator {
             // Try to use a ScalarPair for all tagged enums.
             let mut common_prim = None;
             let mut common_prim_initialized_in_all_variants = true;
-            for (field_layouts, layout_variant) in iter::zip(&*variants, &layout_variants) {
+            for (field_layouts, layout_variant) in iter::zip(variants, &layout_variants) {
                 let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else {
                     panic!();
                 };
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index f2f8e1386a5..4d80f904ac4 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1179,7 +1179,7 @@ impl Expr {
     pub fn peel_parens(&self) -> &Expr {
         let mut expr = self;
         while let ExprKind::Paren(inner) = &expr.kind {
-            expr = &inner;
+            expr = inner;
         }
         expr
     }
@@ -1312,8 +1312,10 @@ pub struct Closure {
     pub movability: Movability,
     pub fn_decl: P<FnDecl>,
     pub body: P<Expr>,
-    /// The span of the argument block `|...|`.
+    /// The span of the declaration block: 'move |...| -> ...'
     pub fn_decl_span: Span,
+    /// The span of the argument block `|...|`
+    pub fn_arg_span: Span,
 }
 
 /// Limit types of a range (inclusive or exclusive)
@@ -2027,7 +2029,7 @@ impl Ty {
     pub fn peel_refs(&self) -> &Self {
         let mut final_ty = self;
         while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind {
-            final_ty = &ty;
+            final_ty = ty;
         }
         final_ty
     }
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 963e5a608a4..a45ee6067bb 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -736,8 +736,7 @@ pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
             return; // Avoid visiting the span for the second time.
         }
         token::Interpolated(nt) => {
-            let mut nt = Lrc::make_mut(nt);
-            visit_nonterminal(&mut nt, vis);
+            visit_nonterminal(Lrc::make_mut(nt), vis);
         }
         _ => {}
     }
@@ -1368,6 +1367,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
             fn_decl,
             body,
             fn_decl_span,
+            fn_arg_span: _,
         }) => {
             vis.visit_closure_binder(binder);
             vis.visit_asyncness(asyncness);
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 58c6d397ea2..482c302950f 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -64,7 +64,7 @@ impl TokenTree {
         match (self, other) {
             (TokenTree::Token(token, _), TokenTree::Token(token2, _)) => token.kind == token2.kind,
             (TokenTree::Delimited(_, delim, tts), TokenTree::Delimited(_, delim2, tts2)) => {
-                delim == delim2 && tts.eq_unspanned(&tts2)
+                delim == delim2 && tts.eq_unspanned(tts2)
             }
             _ => false,
         }
@@ -402,7 +402,7 @@ impl TokenStream {
         let mut t1 = self.trees();
         let mut t2 = other.trees();
         for (t1, t2) in iter::zip(&mut t1, &mut t2) {
-            if !t1.eq_unspanned(&t2) {
+            if !t1.eq_unspanned(t2) {
                 return false;
             }
         }
@@ -475,7 +475,7 @@ impl TokenStream {
             token::Interpolated(nt) => TokenTree::Delimited(
                 DelimSpan::from_single(token.span),
                 Delimiter::Invisible,
-                TokenStream::from_nonterminal_ast(&nt).flattened(),
+                TokenStream::from_nonterminal_ast(nt).flattened(),
             ),
             _ => TokenTree::Token(token.clone(), spacing),
         }
@@ -511,7 +511,7 @@ impl TokenStream {
     fn try_glue_to_last(vec: &mut Vec<TokenTree>, tt: &TokenTree) -> bool {
         if let Some(TokenTree::Token(last_tok, Spacing::Joint)) = vec.last()
             && let TokenTree::Token(tok, spacing) = tt
-            && let Some(glued_tok) = last_tok.glue(&tok)
+            && let Some(glued_tok) = last_tok.glue(tok)
         {
             // ...then overwrite the last token tree in `vec` with the
             // glued token, and skip the first token tree from `stream`.
diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs
index fbb4cf43a95..cdc244c1218 100644
--- a/compiler/rustc_ast/src/util/classify.rs
+++ b/compiler/rustc_ast/src/util/classify.rs
@@ -21,6 +21,7 @@ pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
             | ast::ExprKind::Loop(..)
             | ast::ExprKind::ForLoop(..)
             | ast::ExprKind::TryBlock(..)
+            | ast::ExprKind::ConstBlock(..)
     )
 }
 
diff --git a/compiler/rustc_ast/src/util/comments.rs b/compiler/rustc_ast/src/util/comments.rs
index c96474ccb42..35454c3a670 100644
--- a/compiler/rustc_ast/src/util/comments.rs
+++ b/compiler/rustc_ast/src/util/comments.rs
@@ -110,7 +110,7 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol {
         } else {
             &mut lines
         };
-        if let Some(horizontal) = get_horizontal_trim(&lines, kind) {
+        if let Some(horizontal) = get_horizontal_trim(lines, kind) {
             changes = true;
             // remove a "[ \t]*\*" block from each line, if possible
             for line in lines.iter_mut() {
@@ -147,7 +147,7 @@ fn all_whitespace(s: &str, col: CharPos) -> Option<usize> {
 
 fn trim_whitespace_prefix(s: &str, col: CharPos) -> &str {
     let len = s.len();
-    match all_whitespace(&s, col) {
+    match all_whitespace(s, col) {
         Some(col) => {
             if col < len {
                 &s[col..]
diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index 1d6e7914f3a..f6f186b5107 100644
--- a/compiler/rustc_ast/src/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
@@ -52,14 +52,14 @@ impl LitKind {
                 // new symbol because the string in the LitKind is different to the
                 // string in the token.
                 let s = symbol.as_str();
-                let symbol = if s.contains(&['\\', '\r']) {
+                let symbol = if s.contains(['\\', '\r']) {
                     let mut buf = String::with_capacity(s.len());
                     let mut error = Ok(());
                     // Force-inlining here is aggressive but the closure is
                     // called on every char in the string, so it can be
                     // hot in programs with many long strings.
                     unescape_literal(
-                        &s,
+                        s,
                         Mode::Str,
                         &mut #[inline(always)]
                         |_, unescaped_char| match unescaped_char {
@@ -85,7 +85,7 @@ impl LitKind {
                     if s.contains('\r') {
                         let mut buf = String::with_capacity(s.len());
                         let mut error = Ok(());
-                        unescape_literal(&s, Mode::RawStr, &mut |_, unescaped_char| {
+                        unescape_literal(s, Mode::RawStr, &mut |_, unescaped_char| {
                             match unescaped_char {
                                 Ok(c) => buf.push(c),
                                 Err(err) => {
@@ -106,7 +106,7 @@ impl LitKind {
                 let s = symbol.as_str();
                 let mut buf = Vec::with_capacity(s.len());
                 let mut error = Ok(());
-                unescape_literal(&s, Mode::ByteStr, &mut |_, c| match c {
+                unescape_literal(s, Mode::ByteStr, &mut |_, c| match c {
                     Ok(c) => buf.push(byte_from_char(c)),
                     Err(err) => {
                         if err.is_fatal() {
@@ -122,7 +122,7 @@ impl LitKind {
                 let bytes = if s.contains('\r') {
                     let mut buf = Vec::with_capacity(s.len());
                     let mut error = Ok(());
-                    unescape_literal(&s, Mode::RawByteStr, &mut |_, c| match c {
+                    unescape_literal(s, Mode::RawByteStr, &mut |_, c| match c {
                         Ok(c) => buf.push(byte_from_char(c)),
                         Err(err) => {
                             if err.is_fatal() {
diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index f65f1f069cb..819f1884a06 100644
--- a/compiler/rustc_ast/src/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
@@ -384,7 +384,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
         | ast::ExprKind::AssignOp(_, lhs, rhs)
         | ast::ExprKind::Binary(_, lhs, rhs) => {
             // X { y: 1 } + X { y: 2 }
-            contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs)
+            contains_exterior_struct_lit(lhs) || contains_exterior_struct_lit(rhs)
         }
         ast::ExprKind::Await(x)
         | ast::ExprKind::Unary(_, x)
@@ -393,12 +393,12 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
         | ast::ExprKind::Field(x, _)
         | ast::ExprKind::Index(x, _) => {
             // &X { y: 1 }, X { y: 1 }.y
-            contains_exterior_struct_lit(&x)
+            contains_exterior_struct_lit(x)
         }
 
         ast::ExprKind::MethodCall(box ast::MethodCall { receiver, .. }) => {
             // X { y: 1 }.bar(...)
-            contains_exterior_struct_lit(&receiver)
+            contains_exterior_struct_lit(receiver)
         }
 
         _ => false,
diff --git a/compiler/rustc_ast/src/util/unicode.rs b/compiler/rustc_ast/src/util/unicode.rs
index f009f7b300c..0eae791b25e 100644
--- a/compiler/rustc_ast/src/util/unicode.rs
+++ b/compiler/rustc_ast/src/util/unicode.rs
@@ -17,7 +17,7 @@ pub fn contains_text_flow_control_chars(s: &str) -> bool {
     // U+2069 - E2 81 A9
     let mut bytes = s.as_bytes();
     loop {
-        match core::slice::memchr::memchr(0xE2, &bytes) {
+        match core::slice::memchr::memchr(0xE2, bytes) {
             Some(idx) => {
                 // bytes are valid UTF-8 -> E2 must be followed by two bytes
                 let ch = &bytes[idx..idx + 3];
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index fe27d7fa8de..991eb489f6b 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -840,6 +840,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
             fn_decl,
             body,
             fn_decl_span: _,
+            fn_arg_span: _,
         }) => {
             visitor.visit_fn(FnKind::Closure(binder, fn_decl, body), expression.span, expression.id)
         }
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 2a0338adc9c..dfef6ec70fc 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -222,7 +222,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             // Wrap the expression in an AnonConst.
                             let parent_def_id = self.current_hir_id_owner;
                             let node_id = self.next_node_id();
-                            self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst);
+                            self.create_def(
+                                parent_def_id.def_id,
+                                node_id,
+                                DefPathData::AnonConst,
+                                *op_sp,
+                            );
                             let anon_const = AnonConst { id: node_id, value: P(expr) };
                             hir::InlineAsmOperand::SymFn {
                                 anon_const: self.lower_anon_const(&anon_const),
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 82912a733d5..4260805f1dd 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -176,6 +176,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     fn_decl,
                     body,
                     fn_decl_span,
+                    fn_arg_span,
                 }) => {
                     if let Async::Yes { closure_id, .. } = asyncness {
                         self.lower_expr_async_closure(
@@ -186,6 +187,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             fn_decl,
                             body,
                             *fn_decl_span,
+                            *fn_arg_span,
                         )
                     } else {
                         self.lower_expr_closure(
@@ -196,6 +198,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             fn_decl,
                             body,
                             *fn_decl_span,
+                            *fn_arg_span,
                         )
                     }
                 }
@@ -365,7 +368,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 let node_id = self.next_node_id();
 
                 // Add a definition for the in-band const def.
-                self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst);
+                self.create_def(parent_def_id.def_id, node_id, DefPathData::AnonConst, f.span);
 
                 let anon_const = AnonConst { id: node_id, value: arg };
                 generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const)));
@@ -642,6 +645,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 fn_decl,
                 body,
                 fn_decl_span: self.lower_span(span),
+                fn_arg_span: None,
                 movability: Some(hir::Movability::Static),
             });
 
@@ -898,6 +902,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         decl: &FnDecl,
         body: &Expr,
         fn_decl_span: Span,
+        fn_arg_span: Span,
     ) -> hir::ExprKind<'hir> {
         let (binder_clause, generic_params) = self.lower_closure_binder(binder);
 
@@ -928,6 +933,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             fn_decl,
             body: body_id,
             fn_decl_span: self.lower_span(fn_decl_span),
+            fn_arg_span: Some(self.lower_span(fn_arg_span)),
             movability: generator_option,
         });
 
@@ -984,6 +990,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         decl: &FnDecl,
         body: &Expr,
         fn_decl_span: Span,
+        fn_arg_span: Span,
     ) -> hir::ExprKind<'hir> {
         if let &ClosureBinder::For { span, .. } = binder {
             self.tcx.sess.emit_err(NotSupportedForLifetimeBinderAsyncClosure { span });
@@ -1038,6 +1045,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             fn_decl,
             body,
             fn_decl_span: self.lower_span(fn_decl_span),
+            fn_arg_span: Some(self.lower_span(fn_arg_span)),
             movability: None,
         });
         hir::ExprKind::Closure(c)
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 1d279706278..0258f8fd2d9 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -487,6 +487,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         parent: LocalDefId,
         node_id: ast::NodeId,
         data: DefPathData,
+        span: Span,
     ) -> LocalDefId {
         debug_assert_ne!(node_id, ast::DUMMY_NODE_ID);
         assert!(
@@ -497,7 +498,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             self.tcx.hir().def_key(self.local_def_id(node_id)),
         );
 
-        let def_id = self.tcx.create_def(parent, data).def_id();
+        let def_id = self.tcx.at(span).create_def(parent, data).def_id();
 
         debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
         self.resolver.node_id_to_def_id.insert(node_id, def_id);
@@ -823,6 +824,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     self.current_hir_id_owner.def_id,
                     param,
                     DefPathData::LifetimeNs(kw::UnderscoreLifetime),
+                    ident.span,
                 );
                 debug!(?_def_id);
 
@@ -1151,15 +1153,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
                                 let parent_def_id = self.current_hir_id_owner;
                                 let node_id = self.next_node_id();
+                                let span = self.lower_span(ty.span);
 
                                 // Add a definition for the in-band const def.
                                 let def_id = self.create_def(
                                     parent_def_id.def_id,
                                     node_id,
                                     DefPathData::AnonConst,
+                                    span,
                                 );
 
-                                let span = self.lower_span(ty.span);
                                 let path_expr = Expr {
                                     id: ty.id,
                                     kind: ExprKind::Path(qself.clone(), path.clone()),
@@ -1353,12 +1356,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         itctx,
                     ),
                     ImplTraitContext::Universal => {
+                        let span = t.span;
                         self.create_def(
                             self.current_hir_id_owner.def_id,
                             *def_node_id,
                             DefPathData::ImplTrait,
+                            span,
                         );
-                        let span = t.span;
                         let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
                         let (param, bounds, path) =
                             self.lower_generic_and_bounds(*def_node_id, span, ident, bounds);
@@ -1455,6 +1459,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             self.current_hir_id_owner.def_id,
             opaque_ty_node_id,
             DefPathData::ImplTrait,
+            opaque_ty_span,
         );
         debug!(?opaque_ty_def_id);
 
@@ -1608,6 +1613,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             parent_def_id,
                             node_id,
                             DefPathData::LifetimeNs(lifetime.ident.name),
+                            lifetime.ident.span,
                         );
                         remapping.insert(old_def_id, new_def_id);
 
@@ -1624,6 +1630,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             parent_def_id,
                             node_id,
                             DefPathData::LifetimeNs(kw::UnderscoreLifetime),
+                            lifetime.ident.span,
                         );
                         remapping.insert(old_def_id, new_def_id);
 
@@ -1806,7 +1813,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let fn_def_id = self.local_def_id(fn_node_id);
 
         let opaque_ty_def_id =
-            self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait);
+            self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait, opaque_ty_span);
 
         // When we create the opaque type for this async fn, it is going to have
         // to capture all the lifetimes involved in the signature (including in the
@@ -1866,6 +1873,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 opaque_ty_def_id,
                 inner_node_id,
                 DefPathData::LifetimeNs(ident.name),
+                ident.span,
             );
             new_remapping.insert(outer_def_id, inner_def_id);
 
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index ebe55a4b771..d3d8431c163 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -519,7 +519,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
             ast::MetaItemKind::List(items) => {
                 self.print_path(&item.path, false, 0);
                 self.popen();
-                self.commasep(Consistent, &items, |s, i| s.print_meta_list_item(i));
+                self.commasep(Consistent, items, |s, i| s.print_meta_list_item(i));
                 self.pclose();
             }
         }
@@ -536,7 +536,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
     fn print_tt(&mut self, tt: &TokenTree, convert_dollar_crate: bool) {
         match tt {
             TokenTree::Token(token, _) => {
-                let token_str = self.token_to_string_ext(&token, convert_dollar_crate);
+                let token_str = self.token_to_string_ext(token, convert_dollar_crate);
                 self.word(token_str);
                 if let token::DocComment(..) = token.kind {
                     self.hardbreak()
@@ -998,7 +998,7 @@ impl<'a> State<'a> {
             ast::AssocConstraintKind::Bound { bounds } => {
                 if !bounds.is_empty() {
                     self.word_nbsp(":");
-                    self.print_type_bounds(&bounds);
+                    self.print_type_bounds(bounds);
                 }
             }
         }
@@ -1035,7 +1035,7 @@ impl<'a> State<'a> {
             }
             ast::TyKind::Tup(elts) => {
                 self.popen();
-                self.commasep(Inconsistent, &elts, |s, ty| s.print_type(ty));
+                self.commasep(Inconsistent, elts, |s, ty| s.print_type(ty));
                 if elts.len() == 1 {
                     self.word(",");
                 }
@@ -1254,7 +1254,7 @@ impl<'a> State<'a> {
 
         self.popen();
         self.commasep(Consistent, &args, |s, arg| match arg {
-            AsmArg::Template(template) => s.print_string(&template, ast::StrStyle::Cooked),
+            AsmArg::Template(template) => s.print_string(template, ast::StrStyle::Cooked),
             AsmArg::Operand(op) => {
                 let print_reg_or_class = |s: &mut Self, r: &InlineAsmRegOrRegClass| match r {
                     InlineAsmRegOrRegClass::Reg(r) => s.print_symbol(*r, ast::StrStyle::Cooked),
@@ -1424,11 +1424,11 @@ impl<'a> State<'a> {
                     self.print_path(path, true, 0);
                 }
                 self.popen();
-                self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p));
+                self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
                 self.pclose();
             }
             PatKind::Or(pats) => {
-                self.strsep("|", true, Inconsistent, &pats, |s, p| s.print_pat(p));
+                self.strsep("|", true, Inconsistent, pats, |s, p| s.print_pat(p));
             }
             PatKind::Path(None, path) => {
                 self.print_path(path, true, 0);
@@ -1450,7 +1450,7 @@ impl<'a> State<'a> {
                 }
                 self.commasep_cmnt(
                     Consistent,
-                    &fields,
+                    fields,
                     |s, f| {
                         s.cbox(INDENT_UNIT);
                         if !f.is_shorthand {
@@ -1475,7 +1475,7 @@ impl<'a> State<'a> {
             }
             PatKind::Tuple(elts) => {
                 self.popen();
-                self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p));
+                self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
                 if elts.len() == 1 {
                     self.word(",");
                 }
@@ -1498,7 +1498,7 @@ impl<'a> State<'a> {
                     self.print_pat(inner);
                 }
             }
-            PatKind::Lit(e) => self.print_expr(&**e),
+            PatKind::Lit(e) => self.print_expr(e),
             PatKind::Range(begin, end, Spanned { node: end_kind, .. }) => {
                 if let Some(e) = begin {
                     self.print_expr(e);
@@ -1514,7 +1514,7 @@ impl<'a> State<'a> {
             }
             PatKind::Slice(elts) => {
                 self.word("[");
-                self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p));
+                self.commasep(Inconsistent, elts, |s, p| s.print_pat(p));
                 self.word("]");
             }
             PatKind::Rest => self.word(".."),
@@ -1600,7 +1600,7 @@ impl<'a> State<'a> {
 
         self.word("<");
 
-        self.commasep(Inconsistent, &generic_params, |s, param| {
+        self.commasep(Inconsistent, generic_params, |s, param| {
             s.print_outer_attributes_inline(&param.attrs);
 
             match &param.kind {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 81483ac30d1..4ed16e337d2 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -305,10 +305,10 @@ impl<'a> State<'a> {
                 self.print_expr_tup(exprs);
             }
             ast::ExprKind::Call(func, args) => {
-                self.print_expr_call(func, &args);
+                self.print_expr_call(func, args);
             }
             ast::ExprKind::MethodCall(box ast::MethodCall { seg, receiver, args, .. }) => {
-                self.print_expr_method_call(seg, &receiver, &args);
+                self.print_expr_method_call(seg, receiver, args);
             }
             ast::ExprKind::Binary(op, lhs, rhs) => {
                 self.print_expr_binary(*op, lhs, rhs);
@@ -402,6 +402,7 @@ impl<'a> State<'a> {
                 fn_decl,
                 body,
                 fn_decl_span: _,
+                fn_arg_span: _,
             }) => {
                 self.print_closure_binder(binder);
                 self.print_movability(*movability);
@@ -605,7 +606,7 @@ impl<'a> State<'a> {
         match binder {
             ast::ClosureBinder::NotPresent => {}
             ast::ClosureBinder::For { generic_params, .. } => {
-                self.print_formal_generic_params(&generic_params)
+                self.print_formal_generic_params(generic_params)
             }
         }
     }
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 4a12e1b1b92..e379e647062 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -73,7 +73,7 @@ pub(crate) fn replace_regions_in_mir<'tcx>(
     // Replace all remaining regions with fresh inference variables.
     renumber::renumber_mir(infcx, body, promoted);
 
-    dump_mir(infcx.tcx, None, "renumber", &0, body, |_, _| Ok(()));
+    dump_mir(infcx.tcx, false, "renumber", &0, body, |_, _| Ok(()));
 
     universal_regions
 }
@@ -331,7 +331,7 @@ pub(super) fn dump_mir_results<'tcx>(
         return;
     }
 
-    dump_mir(infcx.tcx, None, "nll", &0, body, |pass_where, out| {
+    dump_mir(infcx.tcx, false, "nll", &0, body, |pass_where, out| {
         match pass_where {
             // Before the CFG, dump out the values for each region variable.
             PassWhere::BeforeCFG => {
@@ -358,15 +358,13 @@ pub(super) fn dump_mir_results<'tcx>(
 
     // Also dump the inference graph constraints as a graphviz file.
     let _: io::Result<()> = try {
-        let mut file =
-            create_dump_file(infcx.tcx, "regioncx.all.dot", None, "nll", &0, body.source)?;
+        let mut file = create_dump_file(infcx.tcx, "regioncx.all.dot", false, "nll", &0, body)?;
         regioncx.dump_graphviz_raw_constraints(&mut file)?;
     };
 
     // Also dump the inference graph constraints as a graphviz file.
     let _: io::Result<()> = try {
-        let mut file =
-            create_dump_file(infcx.tcx, "regioncx.scc.dot", None, "nll", &0, body.source)?;
+        let mut file = create_dump_file(infcx.tcx, "regioncx.scc.dot", false, "nll", &0, body)?;
         regioncx.dump_graphviz_scc_constraints(&mut file)?;
     };
 }
diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock
index 3fa9d56cd01..3b406036c35 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.lock
+++ b/compiler/rustc_codegen_cranelift/Cargo.lock
@@ -20,11 +20,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c794e162a5eff65c72ef524dfe393eb923c354e350bb78b9c7383df13f3bc142"
 
 [[package]]
-name = "ar"
-version = "0.8.0"
-source = "git+https://github.com/bjorn3/rust-ar.git?branch=do_not_remove_cg_clif_ranlib#de9ab0e56bf3a208381d342aa5b60f9ff2891648"
-
-[[package]]
 name = "arrayvec"
 version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -324,7 +319,6 @@ dependencies = [
 name = "rustc_codegen_cranelift"
 version = "0.1.0"
 dependencies = [
- "ar",
  "cranelift-codegen",
  "cranelift-frontend",
  "cranelift-jit",
diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml
index 09cf5b4a1ed..0fdd5de118c 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.toml
+++ b/compiler/rustc_codegen_cranelift/Cargo.toml
@@ -18,7 +18,6 @@ target-lexicon = "0.12.0"
 gimli = { version = "0.26.0", default-features = false, features = ["write"]}
 object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
 
-ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
 indexmap = "1.9.1"
 libloading = { version = "0.7.3", optional = true }
 once_cell = "1.10.0"
diff --git a/compiler/rustc_codegen_cranelift/src/archive.rs b/compiler/rustc_codegen_cranelift/src/archive.rs
index f2e3bf16e61..5a29bc18def 100644
--- a/compiler/rustc_codegen_cranelift/src/archive.rs
+++ b/compiler/rustc_codegen_cranelift/src/archive.rs
@@ -1,35 +1,15 @@
-//! Creation of ar archives like for the lib and staticlib crate type
-
-use std::collections::BTreeMap;
-use std::fs::File;
-use std::io::{self, Read, Seek};
 use std::path::{Path, PathBuf};
 
-use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
+use rustc_codegen_ssa::back::archive::{
+    get_native_object_symbols, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
+};
 use rustc_session::Session;
 
-use object::read::archive::ArchiveFile;
-use object::{Object, ObjectSymbol, ReadCache};
-
-#[derive(Debug)]
-enum ArchiveEntry {
-    FromArchive { archive_index: usize, file_range: (u64, u64) },
-    File(PathBuf),
-}
-
 pub(crate) struct ArArchiveBuilderBuilder;
 
 impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a> {
-        Box::new(ArArchiveBuilder {
-            sess,
-            use_gnu_style_archive: sess.target.archive_format == "gnu",
-            // FIXME fix builtin ranlib on macOS
-            no_builtin_ranlib: sess.target.is_like_osx,
-
-            src_archives: vec![],
-            entries: vec![],
-        })
+        Box::new(ArArchiveBuilder::new(sess, get_native_object_symbols))
     }
 
     fn create_dll_import_lib(
@@ -40,200 +20,6 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
         _tmpdir: &Path,
         _is_direct_dependency: bool,
     ) -> PathBuf {
-        bug!("creating dll imports is not supported");
-    }
-}
-
-pub(crate) struct ArArchiveBuilder<'a> {
-    sess: &'a Session,
-    use_gnu_style_archive: bool,
-    no_builtin_ranlib: bool,
-
-    src_archives: Vec<File>,
-    // Don't use `HashMap` here, as the order is important. `rust.metadata.bin` must always be at
-    // the end of an archive for linkers to not get confused.
-    entries: Vec<(Vec<u8>, ArchiveEntry)>,
-}
-
-impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
-    fn add_file(&mut self, file: &Path) {
-        self.entries.push((
-            file.file_name().unwrap().to_str().unwrap().to_string().into_bytes(),
-            ArchiveEntry::File(file.to_owned()),
-        ));
-    }
-
-    fn add_archive(
-        &mut self,
-        archive_path: &Path,
-        mut skip: Box<dyn FnMut(&str) -> bool + 'static>,
-    ) -> std::io::Result<()> {
-        let read_cache = ReadCache::new(std::fs::File::open(&archive_path)?);
-        let archive = ArchiveFile::parse(&read_cache).unwrap();
-        let archive_index = self.src_archives.len();
-
-        for entry in archive.members() {
-            let entry = entry.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
-            let file_name = String::from_utf8(entry.name().to_vec())
-                .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
-            if !skip(&file_name) {
-                self.entries.push((
-                    file_name.into_bytes(),
-                    ArchiveEntry::FromArchive { archive_index, file_range: entry.file_range() },
-                ));
-            }
-        }
-
-        self.src_archives.push(read_cache.into_inner());
-        Ok(())
-    }
-
-    fn build(mut self: Box<Self>, output: &Path) -> bool {
-        enum BuilderKind {
-            Bsd(ar::Builder<File>),
-            Gnu(ar::GnuBuilder<File>),
-        }
-
-        let sess = self.sess;
-
-        let mut symbol_table = BTreeMap::new();
-
-        let mut entries = Vec::new();
-
-        for (mut entry_name, entry) in self.entries {
-            // FIXME only read the symbol table of the object files to avoid having to keep all
-            // object files in memory at once, or read them twice.
-            let data = match entry {
-                ArchiveEntry::FromArchive { archive_index, file_range } => {
-                    // FIXME read symbols from symtab
-                    let src_read_cache = &mut self.src_archives[archive_index];
-
-                    src_read_cache.seek(io::SeekFrom::Start(file_range.0)).unwrap();
-                    let mut data = std::vec::from_elem(0, usize::try_from(file_range.1).unwrap());
-                    src_read_cache.read_exact(&mut data).unwrap();
-
-                    data
-                }
-                ArchiveEntry::File(file) => std::fs::read(file).unwrap_or_else(|err| {
-                    sess.fatal(&format!(
-                        "error while reading object file during archive building: {}",
-                        err
-                    ));
-                }),
-            };
-
-            if !self.no_builtin_ranlib {
-                if symbol_table.contains_key(&entry_name) {
-                    // The ar crate can't handle creating a symbol table in case of multiple archive
-                    // members with the same name. Work around this by prepending a number until we
-                    // get a unique name.
-                    for i in 1.. {
-                        let new_name = format!("{}_", i)
-                            .into_bytes()
-                            .into_iter()
-                            .chain(entry_name.iter().copied())
-                            .collect::<Vec<_>>();
-                        if !symbol_table.contains_key(&new_name) {
-                            entry_name = new_name;
-                            break;
-                        }
-                    }
-                }
-
-                match object::File::parse(&*data) {
-                    Ok(object) => {
-                        symbol_table.insert(
-                            entry_name.to_vec(),
-                            object
-                                .symbols()
-                                .filter_map(|symbol| {
-                                    if symbol.is_undefined() || symbol.is_local() {
-                                        None
-                                    } else {
-                                        symbol.name().map(|name| name.as_bytes().to_vec()).ok()
-                                    }
-                                })
-                                .collect::<Vec<_>>(),
-                        );
-                    }
-                    Err(err) => {
-                        let err = err.to_string();
-                        if err == "Unknown file magic" {
-                            // Not an object file; skip it.
-                        } else if object::read::archive::ArchiveFile::parse(&*data).is_ok() {
-                            // Nested archive file; skip it.
-                        } else {
-                            sess.fatal(&format!(
-                                "error parsing `{}` during archive creation: {}",
-                                String::from_utf8_lossy(&entry_name),
-                                err
-                            ));
-                        }
-                    }
-                }
-            }
-
-            entries.push((entry_name, data));
-        }
-
-        let mut builder = if self.use_gnu_style_archive {
-            BuilderKind::Gnu(
-                ar::GnuBuilder::new(
-                    File::create(output).unwrap_or_else(|err| {
-                        sess.fatal(&format!(
-                            "error opening destination during archive building: {}",
-                            err
-                        ));
-                    }),
-                    entries.iter().map(|(name, _)| name.clone()).collect(),
-                    ar::GnuSymbolTableFormat::Size32,
-                    symbol_table,
-                )
-                .unwrap(),
-            )
-        } else {
-            BuilderKind::Bsd(
-                ar::Builder::new(
-                    File::create(output).unwrap_or_else(|err| {
-                        sess.fatal(&format!(
-                            "error opening destination during archive building: {}",
-                            err
-                        ));
-                    }),
-                    symbol_table,
-                )
-                .unwrap(),
-            )
-        };
-
-        let any_members = !entries.is_empty();
-
-        // Add all files
-        for (entry_name, data) in entries.into_iter() {
-            let header = ar::Header::new(entry_name, data.len() as u64);
-            match builder {
-                BuilderKind::Bsd(ref mut builder) => builder.append(&header, &mut &*data).unwrap(),
-                BuilderKind::Gnu(ref mut builder) => builder.append(&header, &mut &*data).unwrap(),
-            }
-        }
-
-        // Finalize archive
-        std::mem::drop(builder);
-
-        if self.no_builtin_ranlib {
-            let ranlib = crate::toolchain::get_toolchain_binary(self.sess, "ranlib");
-
-            // Run ranlib to be able to link the archive
-            let status = std::process::Command::new(ranlib)
-                .arg(output)
-                .status()
-                .expect("Couldn't run ranlib");
-
-            if !status.success() {
-                self.sess.fatal(&format!("Ranlib exited with code {:?}", status.code()));
-            }
-        }
-
-        any_members
+        unimplemented!("creating dll imports is not yet supported");
     }
 }
diff --git a/compiler/rustc_codegen_gcc/Cargo.lock b/compiler/rustc_codegen_gcc/Cargo.lock
index 6df2102470f..1cb219e12e0 100644
--- a/compiler/rustc_codegen_gcc/Cargo.lock
+++ b/compiler/rustc_codegen_gcc/Cargo.lock
@@ -12,12 +12,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "ar"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "450575f58f7bee32816abbff470cbc47797397c2a81e0eaced4b98436daf52e1"
-
-[[package]]
 name = "bitflags"
 version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -212,10 +206,8 @@ dependencies = [
 name = "rustc_codegen_gcc"
 version = "0.1.0"
 dependencies = [
- "ar",
  "gccjit",
  "lang_tester",
- "target-lexicon",
  "tempfile",
 ]
 
@@ -229,12 +221,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "target-lexicon"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d"
-
-[[package]]
 name = "tempfile"
 version = "3.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_codegen_gcc/Cargo.toml b/compiler/rustc_codegen_gcc/Cargo.toml
index 211d19a8dc8..1f3da2f799b 100644
--- a/compiler/rustc_codegen_gcc/Cargo.toml
+++ b/compiler/rustc_codegen_gcc/Cargo.toml
@@ -27,10 +27,6 @@ gccjit = { git = "https://github.com/antoyo/gccjit.rs" }
 # Local copy.
 #gccjit = { path = "../gccjit.rs" }
 
-target-lexicon = "0.10.0"
-
-ar = "0.8.0"
-
 [dev-dependencies]
 lang_tester = "0.3.9"
 tempfile = "3.1.0"
diff --git a/compiler/rustc_codegen_gcc/src/archive.rs b/compiler/rustc_codegen_gcc/src/archive.rs
index f18ae7ea5e9..11fa074f5ac 100644
--- a/compiler/rustc_codegen_gcc/src/archive.rs
+++ b/compiler/rustc_codegen_gcc/src/archive.rs
@@ -1,44 +1,17 @@
-use std::fs::File;
 use std::path::{Path, PathBuf};
 
-use crate::errors::RanlibFailure;
-
-use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
+use rustc_codegen_ssa::back::archive::{
+    get_native_object_symbols, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
+};
 use rustc_session::Session;
 
 use rustc_session::cstore::DllImport;
 
-struct ArchiveConfig<'a> {
-    sess: &'a Session,
-    use_native_ar: bool,
-    use_gnu_style_archive: bool,
-}
-
-#[derive(Debug)]
-enum ArchiveEntry {
-    FromArchive {
-        archive_index: usize,
-        entry_index: usize,
-    },
-    File(PathBuf),
-}
-
-pub struct ArArchiveBuilderBuilder;
+pub(crate) struct ArArchiveBuilderBuilder;
 
 impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a> {
-        let config = ArchiveConfig {
-            sess,
-            use_native_ar: false,
-            // FIXME test for linux and System V derivatives instead
-            use_gnu_style_archive: sess.target.options.archive_format == "gnu",
-        };
-
-        Box::new(ArArchiveBuilder {
-            config,
-            src_archives: vec![],
-            entries: vec![],
-        })
+        Box::new(ArArchiveBuilder::new(sess, get_native_object_symbols))
     }
 
     fn create_dll_import_lib(
@@ -49,144 +22,6 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
         _tmpdir: &Path,
         _is_direct_dependency: bool,
     ) -> PathBuf {
-        unimplemented!();
-    }
-}
-
-pub struct ArArchiveBuilder<'a> {
-    config: ArchiveConfig<'a>,
-    src_archives: Vec<(PathBuf, ar::Archive<File>)>,
-    // Don't use `HashMap` here, as the order is important. `rust.metadata.bin` must always be at
-    // the end of an archive for linkers to not get confused.
-    entries: Vec<(String, ArchiveEntry)>,
-}
-
-impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
-    fn add_file(&mut self, file: &Path) {
-        self.entries.push((
-            file.file_name().unwrap().to_str().unwrap().to_string(),
-            ArchiveEntry::File(file.to_owned()),
-        ));
-    }
-
-    fn add_archive(
-        &mut self,
-        archive_path: &Path,
-        mut skip: Box<dyn FnMut(&str) -> bool + 'static>,
-    ) -> std::io::Result<()> {
-        let mut archive = ar::Archive::new(std::fs::File::open(&archive_path)?);
-        let archive_index = self.src_archives.len();
-
-        let mut i = 0;
-        while let Some(entry) = archive.next_entry() {
-            let entry = entry?;
-            let file_name = String::from_utf8(entry.header().identifier().to_vec())
-                .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;
-            if !skip(&file_name) {
-                self.entries
-                    .push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i }));
-            }
-            i += 1;
-        }
-
-        self.src_archives.push((archive_path.to_owned(), archive));
-        Ok(())
-    }
-
-    fn build(mut self: Box<Self>, output: &Path) -> bool {
-        use std::process::Command;
-
-        fn add_file_using_ar(archive: &Path, file: &Path) {
-            Command::new("ar")
-                .arg("r") // add or replace file
-                .arg("-c") // silence created file message
-                .arg(archive)
-                .arg(&file)
-                .status()
-                .unwrap();
-        }
-
-        enum BuilderKind<'a> {
-            Bsd(ar::Builder<File>),
-            Gnu(ar::GnuBuilder<File>),
-            NativeAr(&'a Path),
-        }
-
-        let mut builder = if self.config.use_native_ar {
-            BuilderKind::NativeAr(output)
-        } else if self.config.use_gnu_style_archive {
-            BuilderKind::Gnu(ar::GnuBuilder::new(
-                File::create(output).unwrap(),
-                self.entries
-                    .iter()
-                    .map(|(name, _)| name.as_bytes().to_vec())
-                    .collect(),
-            ))
-        } else {
-            BuilderKind::Bsd(ar::Builder::new(File::create(output).unwrap()))
-        };
-
-        let any_members = !self.entries.is_empty();
-
-        // Add all files
-        for (entry_name, entry) in self.entries.into_iter() {
-            match entry {
-                ArchiveEntry::FromArchive {
-                    archive_index,
-                    entry_index,
-                } => {
-                    let (ref src_archive_path, ref mut src_archive) =
-                        self.src_archives[archive_index];
-                    let entry = src_archive.jump_to_entry(entry_index).unwrap();
-                    let header = entry.header().clone();
-
-                    match builder {
-                        BuilderKind::Bsd(ref mut builder) => {
-                            builder.append(&header, entry).unwrap()
-                        }
-                        BuilderKind::Gnu(ref mut builder) => {
-                            builder.append(&header, entry).unwrap()
-                        }
-                        BuilderKind::NativeAr(archive_file) => {
-                            Command::new("ar")
-                                .arg("x")
-                                .arg(src_archive_path)
-                                .arg(&entry_name)
-                                .status()
-                                .unwrap();
-                            add_file_using_ar(archive_file, Path::new(&entry_name));
-                            std::fs::remove_file(entry_name).unwrap();
-                        }
-                    }
-                }
-                ArchiveEntry::File(file) =>
-                    match builder {
-                        BuilderKind::Bsd(ref mut builder) => {
-                            builder
-                                .append_file(entry_name.as_bytes(), &mut File::open(file).expect("file for bsd builder"))
-                                .unwrap()
-                        },
-                        BuilderKind::Gnu(ref mut builder) => {
-                            builder
-                                .append_file(entry_name.as_bytes(), &mut File::open(&file).expect(&format!("file {:?} for gnu builder", file)))
-                                .unwrap()
-                        },
-                        BuilderKind::NativeAr(archive_file) => add_file_using_ar(archive_file, &file),
-                    },
-            }
-        }
-
-        // Finalize archive
-        std::mem::drop(builder);
-
-        // Run ranlib to be able to link the archive
-        let status =
-            std::process::Command::new("ranlib").arg(output).status().expect("Couldn't run ranlib");
-
-        if !status.success() {
-            self.config.sess.emit_fatal(RanlibFailure::new(status.code()));
-        }
-
-        any_members
+        unimplemented!("creating dll imports is not yet supported");
     }
 }
diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs
index 15ad90f9043..89fed7be131 100644
--- a/compiler/rustc_codegen_gcc/src/errors.rs
+++ b/compiler/rustc_codegen_gcc/src/errors.rs
@@ -17,18 +17,6 @@ impl IntoDiagnosticArg for ExitCode {
 }
 
 #[derive(Diagnostic)]
-#[diag(codegen_gcc_ranlib_failure)]
-pub(crate) struct RanlibFailure {
-    exit_code: ExitCode,
-}
-
-impl RanlibFailure {
-    pub fn new(exit_code: Option<i32>) -> Self {
-        RanlibFailure { exit_code: ExitCode(exit_code) }
-    }
-}
-
-#[derive(Diagnostic)]
 #[diag(codegen_gcc_invalid_monomorphization_basic_integer, code = "E0511")]
 pub(crate) struct InvalidMonomorphizationBasicInteger<'a> {
     #[primary_span]
@@ -227,7 +215,7 @@ pub(crate) struct InvalidMonomorphizationUnsupportedOperation<'a> {
 #[diag(codegen_gcc_linkage_const_or_mut_type)]
 pub(crate) struct LinkageConstOrMutType {
     #[primary_span]
-    pub span: Span
+    pub span: Span,
 }
 
 #[derive(Diagnostic)]
@@ -238,5 +226,5 @@ pub(crate) struct LTONotSupported;
 #[diag(codegen_gcc_unwinding_inline_asm)]
 pub(crate) struct UnwindingInlineAsm {
     #[primary_span]
-    pub span: Span
+    pub span: Span,
 }
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index 0ad39c24025..93d6234dc88 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -11,7 +11,7 @@ bitflags = "1.0"
 cstr = "0.2"
 libc = "0.2"
 measureme = "10.0.0"
-object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "archive", "coff", "elf", "macho", "pe"] }
+object = { version = "0.29.0", default-features = false, features = ["std", "read"] }
 tracing = "0.1"
 rustc_middle = { path = "../rustc_middle" }
 rustc-demangle = "0.1.21"
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index a8b47633519..f3bdacf6085 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -258,13 +258,12 @@ pub fn from_fn_attrs<'ll, 'tcx>(
         OptimizeAttr::Speed => {}
     }
 
-    let inline = if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
-        InlineAttr::Never
-    } else if codegen_fn_attrs.inline == InlineAttr::None && instance.def.requires_inline(cx.tcx) {
-        InlineAttr::Hint
-    } else {
-        codegen_fn_attrs.inline
-    };
+    let inline =
+        if codegen_fn_attrs.inline == InlineAttr::None && instance.def.requires_inline(cx.tcx) {
+            InlineAttr::Hint
+        } else {
+            codegen_fn_attrs.inline
+        };
     to_add.extend(inline_attr(cx, inline));
 
     // The `uwtable` attribute according to LLVM is:
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index 5c68abeb08b..0aee1a1439b 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -1,31 +1,30 @@
 //! A helper class for dealing with static archives
 
 use std::env;
-use std::ffi::{CStr, CString, OsString};
-use std::fs;
-use std::io::{self, Write};
+use std::ffi::{c_char, c_void, CStr, CString, OsString};
+use std::io;
 use std::mem;
 use std::path::{Path, PathBuf};
 use std::ptr;
 use std::str;
 
-use object::read::macho::FatArch;
-
 use crate::common;
 use crate::errors::{
-    ArchiveBuildFailure, DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary,
-    ErrorWritingDEFFile, UnknownArchiveKind,
+    DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, ErrorWritingDEFFile,
 };
 use crate::llvm::archive_ro::{ArchiveRO, Child};
 use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
-use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
-use rustc_data_structures::memmap::Mmap;
+use rustc_codegen_ssa::back::archive::{
+    get_native_object_symbols, try_extract_macho_fat_archive, ArArchiveBuilder,
+    ArchiveBuildFailure, ArchiveBuilder, ArchiveBuilderBuilder, UnknownArchiveKind,
+};
+
 use rustc_session::cstore::DllImport;
 use rustc_session::Session;
 
 /// Helper for adding many files to an archive.
 #[must_use = "must call build() to finish building the archive"]
-pub struct LlvmArchiveBuilder<'a> {
+pub(crate) struct LlvmArchiveBuilder<'a> {
     sess: &'a Session,
     additions: Vec<Addition>,
 }
@@ -61,57 +60,6 @@ fn llvm_machine_type(cpu: &str) -> LLVMMachineType {
     }
 }
 
-fn try_filter_fat_archs(
-    archs: object::read::Result<&[impl FatArch]>,
-    target_arch: object::Architecture,
-    archive_path: &Path,
-    archive_map_data: &[u8],
-) -> io::Result<Option<PathBuf>> {
-    let archs = archs.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
-
-    let desired = match archs.iter().filter(|a| a.architecture() == target_arch).next() {
-        Some(a) => a,
-        None => return Ok(None),
-    };
-
-    let (mut new_f, extracted_path) = tempfile::Builder::new()
-        .suffix(archive_path.file_name().unwrap())
-        .tempfile()?
-        .keep()
-        .unwrap();
-
-    new_f.write_all(
-        desired.data(archive_map_data).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?,
-    )?;
-
-    Ok(Some(extracted_path))
-}
-
-fn try_extract_macho_fat_archive(
-    sess: &Session,
-    archive_path: &Path,
-) -> io::Result<Option<PathBuf>> {
-    let archive_map = unsafe { Mmap::map(fs::File::open(&archive_path)?)? };
-    let target_arch = match sess.target.arch.as_ref() {
-        "aarch64" => object::Architecture::Aarch64,
-        "x86_64" => object::Architecture::X86_64,
-        _ => return Ok(None),
-    };
-
-    match object::macho::FatHeader::parse(&*archive_map) {
-        Ok(h) if h.magic.get(object::endian::BigEndian) == object::macho::FAT_MAGIC => {
-            let archs = object::macho::FatHeader::parse_arch32(&*archive_map);
-            try_filter_fat_archs(archs, target_arch, archive_path, &*archive_map)
-        }
-        Ok(h) if h.magic.get(object::endian::BigEndian) == object::macho::FAT_MAGIC_64 => {
-            let archs = object::macho::FatHeader::parse_arch64(&*archive_map);
-            try_filter_fat_archs(archs, target_arch, archive_path, &*archive_map)
-        }
-        // Not a FatHeader at all, just return None.
-        _ => Ok(None),
-    }
-}
-
 impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
     fn add_archive(
         &mut self,
@@ -160,7 +108,11 @@ pub struct LlvmArchiveBuilderBuilder;
 
 impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a> {
-        Box::new(LlvmArchiveBuilder { sess, additions: Vec::new() })
+        if sess.target.arch == "wasm32" || sess.target.arch == "wasm64" {
+            Box::new(LlvmArchiveBuilder { sess, additions: Vec::new() })
+        } else {
+            Box::new(ArArchiveBuilder::new(sess, get_llvm_object_symbols))
+        }
     }
 
     fn create_dll_import_lib(
@@ -309,6 +261,61 @@ 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.
+#[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()) };
+
+    // 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");
+
+    if is_bitcode || is_unsupported_windows_obj_file {
+        let mut state = Box::new(f);
+
+        let err = unsafe {
+            llvm::LLVMRustGetSymbols(
+                buf.as_ptr(),
+                buf.len(),
+                &mut *state as *mut &mut _ 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) });
+        }
+
+        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)
+    }
+}
+
 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/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs
index 0fafc214f2f..fddfbb23c67 100644
--- a/compiler/rustc_codegen_llvm/src/errors.rs
+++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -73,12 +73,6 @@ pub(crate) struct LinkageConstOrMutType {
 pub(crate) struct SanitizerMemtagRequiresMte;
 
 #[derive(Diagnostic)]
-#[diag(codegen_llvm_archive_build_failure)]
-pub(crate) struct ArchiveBuildFailure {
-    pub error: std::io::Error,
-}
-
-#[derive(Diagnostic)]
 #[diag(codegen_llvm_error_writing_def_file)]
 pub(crate) struct ErrorWritingDEFFile {
     pub error: std::io::Error,
@@ -98,12 +92,6 @@ pub(crate) struct DlltoolFailImportLibrary<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(codegen_llvm_unknown_archive_kind)]
-pub(crate) struct UnknownArchiveKind<'a> {
-    pub kind: &'a str,
-}
-
-#[derive(Diagnostic)]
 #[diag(codegen_llvm_dynamic_linking_with_lto)]
 #[note]
 pub(crate) struct DynamicLinkingWithLTO;
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index c14e1656291..8a9392255b8 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -983,6 +983,9 @@ pub type SelfProfileBeforePassCallback =
     unsafe extern "C" fn(*mut c_void, *const c_char, *const c_char);
 pub type SelfProfileAfterPassCallback = unsafe extern "C" fn(*mut c_void);
 
+pub type GetSymbolsCallback = unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void;
+pub type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void;
+
 extern "C" {
     pub fn LLVMRustInstallFatalErrorHandler();
     pub fn LLVMRustDisableSystemDialogsOnCrash();
@@ -2474,4 +2477,14 @@ extern "C" {
     pub fn LLVMRustGetMangledName(V: &Value, out: &RustString);
 
     pub fn LLVMRustGetElementTypeArgIndex(CallSite: &Value) -> i32;
+
+    pub fn LLVMRustIsBitcode(ptr: *const u8, len: usize) -> bool;
+
+    pub fn LLVMRustGetSymbols(
+        buf_ptr: *const u8,
+        buf_len: usize,
+        state: *mut c_void,
+        callback: GetSymbolsCallback,
+        error_callback: GetSymbolsErrorCallback,
+    ) -> *mut c_void;
 }
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index c9f5dd0f2c6..2fa602520dc 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -494,6 +494,11 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
         .flatten();
     features.extend(feats);
 
+    // FIXME: Move v8a to target definition list when earliest supported LLVM is 14.
+    if get_version() >= (14, 0, 0) && sess.target.arch == "aarch64" {
+        features.push("+v8a".into());
+    }
+
     if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
         sess.emit_err(TargetFeatureDisableOrEnable {
             features: f,
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index d868e3d56ba..345174fb595 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -7,6 +7,7 @@ edition = "2021"
 test = false
 
 [dependencies]
+ar_archive_writer = "0.1.1"
 bitflags = "1.2.1"
 cc = "1.0.69"
 itertools = "0.10.1"
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 2b1b06d1644..58558fb8c4b 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -6,14 +6,19 @@ 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};
 use object::read::archive::ArchiveFile;
+use object::read::macho::FatArch;
+use tempfile::Builder as TempFileBuilder;
 
 use std::error::Error;
 use std::fs::File;
-use std::io;
+use std::io::{self, Write};
 use std::path::{Path, PathBuf};
 
-use crate::errors::ExtractBundledLibsError;
+// Re-exporting for rustc_codegen_llvm::back::archive
+pub use crate::errors::{ArchiveBuildFailure, ExtractBundledLibsError, UnknownArchiveKind};
 
 pub trait ArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a>;
@@ -80,3 +85,225 @@ pub trait ArchiveBuilder<'a> {
 
     fn build(self: Box<Self>, output: &Path) -> bool;
 }
+
+#[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>,
+
+    src_archives: Vec<(PathBuf, Mmap)>,
+    // Don't use an `HashMap` here, as the order is important. `lib.rmeta` needs
+    // to be at the end of an archive in some cases for linkers to not get confused.
+    entries: Vec<(Vec<u8>, ArchiveEntry)>,
+}
+
+#[derive(Debug)]
+enum ArchiveEntry {
+    FromArchive { archive_index: usize, file_range: (u64, u64) },
+    File(PathBuf),
+}
+
+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![] }
+    }
+}
+
+fn try_filter_fat_archs(
+    archs: object::read::Result<&[impl FatArch]>,
+    target_arch: object::Architecture,
+    archive_path: &Path,
+    archive_map_data: &[u8],
+) -> io::Result<Option<PathBuf>> {
+    let archs = archs.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
+
+    let desired = match archs.iter().filter(|a| a.architecture() == target_arch).next() {
+        Some(a) => a,
+        None => return Ok(None),
+    };
+
+    let (mut new_f, extracted_path) = tempfile::Builder::new()
+        .suffix(archive_path.file_name().unwrap())
+        .tempfile()?
+        .keep()
+        .unwrap();
+
+    new_f.write_all(
+        desired.data(archive_map_data).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?,
+    )?;
+
+    Ok(Some(extracted_path))
+}
+
+pub fn try_extract_macho_fat_archive(
+    sess: &Session,
+    archive_path: &Path,
+) -> io::Result<Option<PathBuf>> {
+    let archive_map = unsafe { Mmap::map(File::open(&archive_path)?)? };
+    let target_arch = match sess.target.arch.as_ref() {
+        "aarch64" => object::Architecture::Aarch64,
+        "x86_64" => object::Architecture::X86_64,
+        _ => return Ok(None),
+    };
+
+    match object::macho::FatHeader::parse(&*archive_map) {
+        Ok(h) if h.magic.get(object::endian::BigEndian) == object::macho::FAT_MAGIC => {
+            let archs = object::macho::FatHeader::parse_arch32(&*archive_map);
+            try_filter_fat_archs(archs, target_arch, archive_path, &*archive_map)
+        }
+        Ok(h) if h.magic.get(object::endian::BigEndian) == object::macho::FAT_MAGIC_64 => {
+            let archs = object::macho::FatHeader::parse_arch64(&*archive_map);
+            try_filter_fat_archs(archs, target_arch, archive_path, &*archive_map)
+        }
+        // Not a FatHeader at all, just return None.
+        _ => Ok(None),
+    }
+}
+
+impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
+    fn add_archive(
+        &mut self,
+        archive_path: &Path,
+        mut skip: Box<dyn FnMut(&str) -> bool + 'static>,
+    ) -> io::Result<()> {
+        let mut archive_path = archive_path.to_path_buf();
+        if self.sess.target.llvm_target.contains("-apple-macosx") {
+            if let Some(new_archive_path) =
+                try_extract_macho_fat_archive(&self.sess, &archive_path)?
+            {
+                archive_path = new_archive_path
+            }
+        }
+
+        if self.src_archives.iter().any(|archive| archive.0 == archive_path) {
+            return Ok(());
+        }
+
+        let archive_map = unsafe { Mmap::map(File::open(&archive_path)?)? };
+        let archive = ArchiveFile::parse(&*archive_map)
+            .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
+        let archive_index = self.src_archives.len();
+
+        for entry in archive.members() {
+            let entry = entry.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
+            let file_name = String::from_utf8(entry.name().to_vec())
+                .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
+            if !skip(&file_name) {
+                self.entries.push((
+                    file_name.into_bytes(),
+                    ArchiveEntry::FromArchive { archive_index, file_range: entry.file_range() },
+                ));
+            }
+        }
+
+        self.src_archives.push((archive_path.to_owned(), archive_map));
+        Ok(())
+    }
+
+    /// Adds an arbitrary file to this archive
+    fn add_file(&mut self, file: &Path) {
+        self.entries.push((
+            file.file_name().unwrap().to_str().unwrap().to_string().into_bytes(),
+            ArchiveEntry::File(file.to_owned()),
+        ));
+    }
+
+    /// Combine the provided files, rlibs, and native libraries into a single
+    /// `Archive`.
+    fn build(self: Box<Self>, output: &Path) -> bool {
+        let sess = self.sess;
+        match self.build_inner(output) {
+            Ok(any_members) => any_members,
+            Err(e) => sess.emit_fatal(ArchiveBuildFailure { error: e }),
+        }
+    }
+}
+
+impl<'a> ArArchiveBuilder<'a> {
+    fn build_inner(self, output: &Path) -> io::Result<bool> {
+        let archive_kind = match &*self.sess.target.archive_format {
+            "gnu" => ArchiveKind::Gnu,
+            "bsd" => ArchiveKind::Bsd,
+            "darwin" => ArchiveKind::Darwin,
+            "coff" => ArchiveKind::Coff,
+            kind => {
+                self.sess.emit_fatal(UnknownArchiveKind { kind });
+            }
+        };
+
+        let mut entries = Vec::new();
+
+        for (entry_name, entry) in self.entries {
+            let data =
+                match entry {
+                    ArchiveEntry::FromArchive { archive_index, file_range } => {
+                        let src_archive = &self.src_archives[archive_index];
+
+                        let data = &src_archive.1
+                            [file_range.0 as usize..file_range.0 as usize + file_range.1 as usize];
+
+                        Box::new(data) as Box<dyn AsRef<[u8]>>
+                    }
+                    ArchiveEntry::File(file) => unsafe {
+                        Box::new(
+                            Mmap::map(File::open(file).map_err(|err| {
+                                io_error_context("failed to open object file", err)
+                            })?)
+                            .map_err(|err| io_error_context("failed to map object file", err))?,
+                        ) as Box<dyn AsRef<[u8]>>
+                    },
+                };
+
+            entries.push(NewArchiveMember {
+                buf: data,
+                get_symbols: self.get_object_symbols,
+                member_name: String::from_utf8(entry_name).unwrap(),
+                mtime: 0,
+                uid: 0,
+                gid: 0,
+                perms: 0o644,
+            })
+        }
+
+        // Write to a temporary file first before atomically renaming to the final name.
+        // This prevents programs (including rustc) from attempting to read a partial archive.
+        // It also enables writing an archive with the same filename as a dependency on Windows as
+        // required by a test.
+        let mut archive_tmpfile = TempFileBuilder::new()
+            .suffix(".temp-archive")
+            .tempfile_in(output.parent().unwrap_or_else(|| Path::new("")))
+            .map_err(|err| io_error_context("couldn't create a temp file", err))?;
+
+        write_archive_to_stream(
+            archive_tmpfile.as_file_mut(),
+            &entries,
+            true,
+            archive_kind,
+            true,
+            false,
+        )?;
+
+        let any_entries = !entries.is_empty();
+        drop(entries);
+        // Drop src_archives to unmap all input archives, which is necessary if we want to write the
+        // output archive to the same location as an input archive on Windows.
+        drop(self.src_archives);
+
+        archive_tmpfile
+            .persist(output)
+            .map_err(|err| io_error_context("failed to rename archive file", err.error))?;
+
+        Ok(any_entries)
+    }
+}
+
+fn io_error_context(context: &str, err: io::Error) -> io::Error {
+    io::Error::new(io::ErrorKind::Other, format!("{context}: {err}"))
+}
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index ade50af0aee..e3b6fbf1bc7 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -534,3 +534,17 @@ pub struct ReadFileError {
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_unsupported_link_self_contained)]
 pub struct UnsupportedLinkSelfContained;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_archive_build_failure)]
+// Public for rustc_codegen_llvm::back::archive
+pub struct ArchiveBuildFailure {
+    pub error: std::io::Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_unknown_archive_kind)]
+// Public for rustc_codegen_llvm::back::archive
+pub struct UnknownArchiveKind<'a> {
+    pub kind: &'a str,
+}
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 90855538589..fbe30154a7c 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -309,14 +309,14 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
                 // In the algorithm above, we can change
                 // cast(relative_tag) + niche_variants.start()
                 // into
-                // cast(tag) + (niche_variants.start() - niche_start)
+                // cast(tag + (niche_variants.start() - niche_start))
                 // if either the casted type is no larger than the original
                 // type, or if the niche values are contiguous (in either the
                 // signed or unsigned sense).
-                let can_incr_after_cast = cast_smaller || niches_ule || niches_sle;
+                let can_incr = cast_smaller || niches_ule || niches_sle;
 
                 let data_for_boundary_niche = || -> Option<(IntPredicate, u128)> {
-                    if !can_incr_after_cast {
+                    if !can_incr {
                         None
                     } else if niche_start == low_unsigned {
                         Some((IntPredicate::IntULE, niche_end))
@@ -353,24 +353,33 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
                     // The algorithm is now this:
                     // is_niche = tag <= niche_end
                     // discr = if is_niche {
-                    //     cast(tag) + (niche_variants.start() - niche_start)
+                    //     cast(tag + (niche_variants.start() - niche_start))
                     // } else {
                     //     untagged_variant
                     // }
                     // (the first line may instead be tag >= niche_start,
                     // and may be a signed or unsigned comparison)
+                    // The arithmetic must be done before the cast, so we can
+                    // have the correct wrapping behavior. See issue #104519 for
+                    // the consequences of getting this wrong.
                     let is_niche =
                         bx.icmp(predicate, tag, bx.cx().const_uint_big(tag_llty, constant));
+                    let delta = (niche_variants.start().as_u32() as u128).wrapping_sub(niche_start);
+                    let incr_tag = if delta == 0 {
+                        tag
+                    } else {
+                        bx.add(tag, bx.cx().const_uint_big(tag_llty, delta))
+                    };
+
                     let cast_tag = if cast_smaller {
-                        bx.intcast(tag, cast_to, false)
+                        bx.intcast(incr_tag, cast_to, false)
                     } else if niches_ule {
-                        bx.zext(tag, cast_to)
+                        bx.zext(incr_tag, cast_to)
                     } else {
-                        bx.sext(tag, cast_to)
+                        bx.sext(incr_tag, cast_to)
                     };
 
-                    let delta = (niche_variants.start().as_u32() as u128).wrapping_sub(niche_start);
-                    (is_niche, cast_tag, delta)
+                    (is_niche, cast_tag, 0)
                 } else {
                     // The special cases don't apply, so we'll have to go with
                     // the general algorithm.
diff --git a/compiler/rustc_data_structures/src/intern.rs b/compiler/rustc_data_structures/src/intern.rs
index 11cbff8ea6a..76a1288e6d3 100644
--- a/compiler/rustc_data_structures/src/intern.rs
+++ b/compiler/rustc_data_structures/src/intern.rs
@@ -72,7 +72,7 @@ impl<'a, T: PartialOrd> PartialOrd for Interned<'a, T> {
         if ptr::eq(self.0, other.0) {
             Some(Ordering::Equal)
         } else {
-            let res = self.0.partial_cmp(&other.0);
+            let res = self.0.partial_cmp(other.0);
             debug_assert_ne!(res, Some(Ordering::Equal));
             res
         }
@@ -86,7 +86,7 @@ impl<'a, T: Ord> Ord for Interned<'a, T> {
         if ptr::eq(self.0, other.0) {
             Ordering::Equal
         } else {
-            let res = self.0.cmp(&other.0);
+            let res = self.0.cmp(other.0);
             debug_assert_ne!(res, Ordering::Equal);
             res
         }
diff --git a/compiler/rustc_data_structures/src/memmap.rs b/compiler/rustc_data_structures/src/memmap.rs
index 917416df6b8..3d44e17f31d 100644
--- a/compiler/rustc_data_structures/src/memmap.rs
+++ b/compiler/rustc_data_structures/src/memmap.rs
@@ -36,6 +36,12 @@ impl Deref for Mmap {
 
     #[inline]
     fn deref(&self) -> &[u8] {
+        &self.0
+    }
+}
+
+impl AsRef<[u8]> for Mmap {
+    fn as_ref(&self) -> &[u8] {
         &*self.0
     }
 }
@@ -96,13 +102,13 @@ impl Deref for MmapMut {
 
     #[inline]
     fn deref(&self) -> &[u8] {
-        &*self.0
+        &self.0
     }
 }
 
 impl DerefMut for MmapMut {
     #[inline]
     fn deref_mut(&mut self) -> &mut [u8] {
-        &mut *self.0
+        &mut self.0
     }
 }
diff --git a/compiler/rustc_data_structures/src/owning_ref/mod.rs b/compiler/rustc_data_structures/src/owning_ref/mod.rs
index ed5e566184f..980a540ccba 100644
--- a/compiler/rustc_data_structures/src/owning_ref/mod.rs
+++ b/compiler/rustc_data_structures/src/owning_ref/mod.rs
@@ -899,25 +899,25 @@ unsafe impl<O, T: ?Sized> StableAddress for OwningRef<O, T> {}
 
 impl<O, T: ?Sized> AsRef<T> for OwningRef<O, T> {
     fn as_ref(&self) -> &T {
-        &*self
+        self
     }
 }
 
 impl<O, T: ?Sized> AsRef<T> for OwningRefMut<O, T> {
     fn as_ref(&self) -> &T {
-        &*self
+        self
     }
 }
 
 impl<O, T: ?Sized> AsMut<T> for OwningRefMut<O, T> {
     fn as_mut(&mut self) -> &mut T {
-        &mut *self
+        self
     }
 }
 
 impl<O, T: ?Sized> Borrow<T> for OwningRef<O, T> {
     fn borrow(&self) -> &T {
-        &*self
+        self
     }
 }
 
@@ -1021,7 +1021,7 @@ where
     T: PartialEq,
 {
     fn eq(&self, other: &Self) -> bool {
-        (&*self as &T).eq(&*other as &T)
+        self.deref().eq(other.deref())
     }
 }
 
@@ -1032,7 +1032,7 @@ where
     T: PartialOrd,
 {
     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        (&*self as &T).partial_cmp(&*other as &T)
+        self.deref().partial_cmp(other.deref())
     }
 }
 
@@ -1041,7 +1041,7 @@ where
     T: Ord,
 {
     fn cmp(&self, other: &Self) -> Ordering {
-        (&*self as &T).cmp(&*other as &T)
+        self.deref().cmp(other.deref())
     }
 }
 
@@ -1050,7 +1050,7 @@ where
     T: Hash,
 {
     fn hash<H: Hasher>(&self, state: &mut H) {
-        (&*self as &T).hash(state);
+        self.deref().hash(state);
     }
 }
 
@@ -1059,7 +1059,7 @@ where
     T: PartialEq,
 {
     fn eq(&self, other: &Self) -> bool {
-        (&*self as &T).eq(&*other as &T)
+        self.deref().eq(other.deref())
     }
 }
 
@@ -1070,7 +1070,7 @@ where
     T: PartialOrd,
 {
     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        (&*self as &T).partial_cmp(&*other as &T)
+        self.deref().partial_cmp(other.deref())
     }
 }
 
@@ -1079,7 +1079,7 @@ where
     T: Ord,
 {
     fn cmp(&self, other: &Self) -> Ordering {
-        (&*self as &T).cmp(&*other as &T)
+        self.deref().cmp(other.deref())
     }
 }
 
@@ -1088,7 +1088,7 @@ where
     T: Hash,
 {
     fn hash<H: Hasher>(&self, state: &mut H) {
-        (&*self as &T).hash(state);
+        self.deref().hash(state);
     }
 }
 
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index ba1960805d8..aa7a01eed15 100644
--- a/compiler/rustc_data_structures/src/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
@@ -192,7 +192,7 @@ impl SelfProfilerRef {
             F: for<'a> FnOnce(&'a SelfProfiler) -> TimingGuard<'a>,
         {
             let profiler = profiler_ref.profiler.as_ref().unwrap();
-            f(&**profiler)
+            f(profiler)
         }
 
         if self.event_filter_mask.contains(event_filter) {
@@ -466,7 +466,7 @@ impl SelfProfilerRef {
 
     pub fn with_profiler(&self, f: impl FnOnce(&SelfProfiler)) {
         if let Some(profiler) = &self.profiler {
-            f(&profiler)
+            f(profiler)
         }
     }
 
@@ -733,7 +733,7 @@ impl Drop for VerboseTimingGuard<'_> {
         if let Some((start_time, start_rss, ref message)) = self.start_and_message {
             let end_rss = get_resident_set_size();
             let dur = start_time.elapsed();
-            print_time_passes_entry(&message, dur, start_rss, end_rss);
+            print_time_passes_entry(message, dur, start_rss, end_rss);
         }
     }
 }
diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs
index e2c33e7e062..cd392a7b678 100644
--- a/compiler/rustc_data_structures/src/stable_hasher.rs
+++ b/compiler/rustc_data_structures/src/stable_hasher.rs
@@ -366,7 +366,7 @@ impl<CTX> HashStable<CTX> for [u8] {
 impl<T: HashStable<CTX>, CTX> HashStable<CTX> for Vec<T> {
     #[inline]
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
-        (&self[..]).hash_stable(ctx, hasher);
+        self[..].hash_stable(ctx, hasher);
     }
 }
 
@@ -405,7 +405,7 @@ where
 {
     #[inline]
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
-        (&self[..]).hash_stable(ctx, hasher);
+        self[..].hash_stable(ctx, hasher);
     }
 }
 
@@ -440,7 +440,7 @@ impl<CTX> HashStable<CTX> for str {
 impl<CTX> HashStable<CTX> for String {
     #[inline]
     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
-        (&self[..]).hash_stable(hcx, hasher);
+        self[..].hash_stable(hcx, hasher);
     }
 }
 
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index c550f246e09..e4f47b22ac3 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -201,7 +201,7 @@ cfg_if! {
 
             #[inline(always)]
             fn deref(&self) -> &T {
-                &*self.0
+                &self.0
             }
         }
 
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs
index 380fbd732d5..22f87514dd8 100644
--- a/compiler/rustc_driver/src/lib.rs
+++ b/compiler/rustc_driver/src/lib.rs
@@ -245,10 +245,8 @@ fn run_compiler(
                 interface::run_compiler(config, |compiler| {
                     let sopts = &compiler.session().opts;
                     if sopts.describe_lints {
-                        let mut lint_store = rustc_lint::new_lint_store(
-                            sopts.unstable_opts.no_interleave_lints,
-                            compiler.session().enable_internal_lints(),
-                        );
+                        let mut lint_store =
+                            rustc_lint::new_lint_store(compiler.session().enable_internal_lints());
                         let registered_lints =
                             if let Some(register_lints) = compiler.register_lints() {
                                 register_lints(compiler.session(), &mut lint_store);
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl
index 178e1a67cce..a1b7afeb709 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl
@@ -1,6 +1,3 @@
-codegen_gcc_ranlib_failure =
-    Ranlib exited with code {$exit_code}
-
 codegen_gcc_linkage_const_or_mut_type =
     must have type `*const T` or `*mut T` due to `#[linkage]` attribute
 
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl
index 68a205df6c7..e273476b60b 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl
@@ -29,9 +29,6 @@ codegen_llvm_linkage_const_or_mut_type =
 codegen_llvm_sanitizer_memtag_requires_mte =
     `-Zsanitizer=memtag` requires `-Ctarget-feature=+mte`
 
-codegen_llvm_archive_build_failure =
-    failed to build archive: {$error}
-
 codegen_llvm_error_writing_def_file =
     Error writing .DEF file: {$error}
 
@@ -41,9 +38,6 @@ codegen_llvm_error_calling_dlltool =
 codegen_llvm_dlltool_fail_import_library =
     Dlltool could not create import library: {$stdout}\n{$stderr}
 
-codegen_llvm_unknown_archive_kind =
-    Don't know how to build archive of type: {$kind}
-
 codegen_llvm_target_feature_disable_or_enable =
     the target features {$features} must all be either enabled or disabled together
 
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
index 70ce559526c..4d1f9c1c901 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
@@ -186,3 +186,9 @@ codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {erro
 codegen_ssa_read_file = failed to read file: {message}
 
 codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target
+
+codegen_ssa_archive_build_failure =
+    failed to build archive: {$error}
+
+codegen_ssa_unknown_archive_kind =
+    Don't know how to build archive of type: {$kind}
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index c450c276366..d8879bf70ed 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -39,7 +39,7 @@ impl Translate for AnnotateSnippetEmitterWriter {
     }
 
     fn fallback_fluent_bundle(&self) -> &FluentBundle {
-        &**self.fallback_bundle
+        &self.fallback_bundle
     }
 }
 
@@ -49,7 +49,7 @@ impl Emitter for AnnotateSnippetEmitterWriter {
         let fluent_args = to_fluent_args(diag.args());
 
         let mut children = diag.children.clone();
-        let (mut primary_span, suggestions) = self.primary_span_formatted(&diag, &fluent_args);
+        let (mut primary_span, suggestions) = self.primary_span_formatted(diag, &fluent_args);
 
         self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
             &mut primary_span,
@@ -65,7 +65,7 @@ impl Emitter for AnnotateSnippetEmitterWriter {
             &diag.code,
             &primary_span,
             &children,
-            &suggestions,
+            suggestions,
         );
     }
 
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 7d5e4723a6d..06bb5edc090 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -292,7 +292,7 @@ impl Diagnostic {
             let lint_index = expectation_id.get_lint_index();
             expectation_id.set_lint_index(None);
             let mut stable_id = unstable_to_stable
-                .get(&expectation_id)
+                .get(expectation_id)
                 .expect("each unstable `LintExpectationId` must have a matching stable id")
                 .normalize();
 
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 1fabe15ff83..db595df8ec1 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -283,7 +283,7 @@ pub trait Emitter: Translate {
                         if self
                             .source_map()
                             .map(|sm| is_case_difference(
-                                &**sm,
+                                sm,
                                 substitution,
                                 sugg.substitutions[0].parts[0].span,
                             ))
@@ -525,7 +525,7 @@ impl Translate for EmitterWriter {
     }
 
     fn fallback_fluent_bundle(&self) -> &FluentBundle {
-        &**self.fallback_bundle
+        &self.fallback_bundle
     }
 }
 
@@ -538,7 +538,7 @@ impl Emitter for EmitterWriter {
         let fluent_args = to_fluent_args(diag.args());
 
         let mut children = diag.children.clone();
-        let (mut primary_span, suggestions) = self.primary_span_formatted(&diag, &fluent_args);
+        let (mut primary_span, suggestions) = self.primary_span_formatted(diag, &fluent_args);
         debug!("emit_diagnostic: suggestions={:?}", suggestions);
 
         self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
@@ -555,7 +555,7 @@ impl Emitter for EmitterWriter {
             &diag.code,
             &primary_span,
             &children,
-            &suggestions,
+            suggestions,
             self.track_diagnostics.then_some(&diag.emitted_at),
         );
     }
@@ -801,7 +801,7 @@ impl EmitterWriter {
         }
 
         let source_string = match file.get_line(line.line_index - 1) {
-            Some(s) => normalize_whitespace(&*s),
+            Some(s) => normalize_whitespace(&s),
             None => return Vec::new(),
         };
 
@@ -1148,7 +1148,7 @@ impl EmitterWriter {
                 (pos + 2, annotation.start_col.saturating_sub(left))
             };
             if let Some(ref label) = annotation.label {
-                buffer.puts(line_offset + pos, code_offset + col, &label, style);
+                buffer.puts(line_offset + pos, code_offset + col, label, style);
             }
         }
 
@@ -1358,7 +1358,7 @@ impl EmitterWriter {
             // only render error codes, not lint codes
             if let Some(DiagnosticId::Error(ref code)) = *code {
                 buffer.append(0, "[", Style::Level(*level));
-                buffer.append(0, &code, Style::Level(*level));
+                buffer.append(0, code, Style::Level(*level));
                 buffer.append(0, "]", Style::Level(*level));
                 label_width += 2 + code.len();
             }
@@ -1683,7 +1683,7 @@ impl EmitterWriter {
         };
 
         // Render the replacements for each suggestion
-        let suggestions = suggestion.splice_lines(&**sm);
+        let suggestions = suggestion.splice_lines(sm);
         debug!("emit_suggestion_default: suggestions={:?}", suggestions);
 
         if suggestions.is_empty() {
@@ -1784,7 +1784,7 @@ impl EmitterWriter {
                     buffer.puts(
                         row_num - 1 + line - line_start,
                         max_line_num_len + 3,
-                        &normalize_whitespace(&*file_lines.file.get_line(line - 1).unwrap()),
+                        &normalize_whitespace(&file_lines.file.get_line(line - 1).unwrap()),
                         Style::Removal,
                     );
                 }
@@ -1926,7 +1926,7 @@ impl EmitterWriter {
                             buffer.putc(
                                 row_num,
                                 (padding as isize + p) as usize,
-                                if part.is_addition(&sm) { '+' } else { '~' },
+                                if part.is_addition(sm) { '+' } else { '~' },
                                 Style::Addition,
                             );
                         }
@@ -1973,7 +1973,7 @@ impl EmitterWriter {
             buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
         } else if notice_capitalization {
             let msg = "notice the capitalization difference";
-            buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
+            buffer.puts(row_num, max_line_num_len + 3, msg, Style::NoStyle);
         }
         emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
         Ok(())
@@ -2028,7 +2028,7 @@ impl EmitterWriter {
                     for child in children {
                         let span = child.render_span.as_ref().unwrap_or(&child.span);
                         if let Err(err) = self.emit_message_default(
-                            &span,
+                            span,
                             &child.message,
                             args,
                             &None,
@@ -2113,7 +2113,7 @@ impl EmitterWriter {
                 *row_num - 1,
                 max_line_num_len + 3,
                 &normalize_whitespace(
-                    &*file_lines.file.get_line(file_lines.lines[line_pos].line_index).unwrap(),
+                    &file_lines.file.get_line(file_lines.lines[line_pos].line_index).unwrap(),
                 ),
                 Style::NoStyle,
             );
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index c4498eafa4e..a37073d8fa3 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -136,7 +136,7 @@ impl Translate for JsonEmitter {
     }
 
     fn fallback_fluent_bundle(&self) -> &FluentBundle {
-        &**self.fallback_bundle
+        &self.fallback_bundle
     }
 }
 
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 2be36a6eeb4..eb0506c459a 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -470,6 +470,7 @@ pub enum StashKey {
     /// Maybe there was a typo where a comma was forgotten before
     /// FRU syntax
     MaybeFruTypo,
+    CallAssocMethod,
 }
 
 fn default_track_diagnostic(_: &Diagnostic) {}
@@ -1328,7 +1329,7 @@ impl HandlerInner {
 
             diagnostic.children.drain_filter(already_emitted_sub).for_each(|_| {});
 
-            self.emitter.emit_diagnostic(&diagnostic);
+            self.emitter.emit_diagnostic(diagnostic);
             if diagnostic.is_error() {
                 self.deduplicated_err_count += 1;
             } else if let Warning(_) = diagnostic.level {
diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs
index a452fac0747..afd660ff1bf 100644
--- a/compiler/rustc_errors/src/translation.rs
+++ b/compiler/rustc_errors/src/translation.rs
@@ -59,13 +59,13 @@ pub trait Translate {
         trace!(?message, ?args);
         let (identifier, attr) = match message {
             DiagnosticMessage::Str(msg) | DiagnosticMessage::Eager(msg) => {
-                return Cow::Borrowed(&msg);
+                return Cow::Borrowed(msg);
             }
             DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr),
         };
 
         let translate_with_bundle = |bundle: &'a FluentBundle| -> Option<(Cow<'_, str>, Vec<_>)> {
-            let message = bundle.get_message(&identifier)?;
+            let message = bundle.get_message(identifier)?;
             let value = match attr {
                 Some(attr) => message.get_attribute(attr)?.value(),
                 None => message.value()?,
@@ -73,7 +73,7 @@ pub trait Translate {
             debug!(?message, ?value);
 
             let mut errs = vec![];
-            let translated = bundle.format_pattern(value, Some(&args), &mut errs);
+            let translated = bundle.format_pattern(value, Some(args), &mut errs);
             debug!(?translated, ?errs);
             Some((translated, errs))
         };
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index c978297295d..4812bdd9dd8 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -539,6 +539,9 @@ impl<'a> ExtCtxt<'a> {
                 fn_decl,
                 body,
                 fn_decl_span: span,
+                // FIXME(SarthakSingh31): This points to the start of the declaration block and
+                // not the span of the argument block.
+                fn_arg_span: span,
             })),
         )
     }
diff --git a/compiler/rustc_fs_util/src/lib.rs b/compiler/rustc_fs_util/src/lib.rs
index 63998bb6b00..a7dfce3b9b8 100644
--- a/compiler/rustc_fs_util/src/lib.rs
+++ b/compiler/rustc_fs_util/src/lib.rs
@@ -65,7 +65,7 @@ pub enum LinkOrCopy {
 pub fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(p: P, q: Q) -> io::Result<LinkOrCopy> {
     let p = p.as_ref();
     let q = q.as_ref();
-    match fs::remove_file(&q) {
+    match fs::remove_file(q) {
         Ok(()) => (),
         Err(err) if err.kind() == io::ErrorKind::NotFound => (),
         Err(err) => return Err(err),
diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs
index 401d3f6689c..1f8268cc17c 100644
--- a/compiler/rustc_graphviz/src/lib.rs
+++ b/compiler/rustc_graphviz/src/lib.rs
@@ -410,7 +410,7 @@ impl<'a> Id<'a> {
     }
 
     pub fn as_slice(&'a self) -> &'a str {
-        &*self.name
+        &self.name
     }
 }
 
@@ -515,7 +515,7 @@ impl<'a> LabelText<'a> {
     pub fn to_dot_string(&self) -> String {
         match *self {
             LabelStr(ref s) => format!("\"{}\"", s.escape_default()),
-            EscStr(ref s) => format!("\"{}\"", LabelText::escape_str(&s)),
+            EscStr(ref s) => format!("\"{}\"", LabelText::escape_str(s)),
             HtmlStr(ref s) => format!("<{}>", s),
         }
     }
@@ -529,7 +529,7 @@ impl<'a> LabelText<'a> {
             EscStr(s) => s,
             LabelStr(s) => {
                 if s.contains('\\') {
-                    (&*s).escape_default().to_string().into()
+                    s.escape_default().to_string().into()
                 } else {
                     s
                 }
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 118eafe2910..636e6e1b48d 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -943,7 +943,10 @@ pub struct Closure<'hir> {
     pub bound_generic_params: &'hir [GenericParam<'hir>],
     pub fn_decl: &'hir FnDecl<'hir>,
     pub body: BodyId,
+    /// The span of the declaration block: 'move |...| -> ...'
     pub fn_decl_span: Span,
+    /// The span of the argument block `|...|`
+    pub fn_arg_span: Option<Span>,
     pub movability: Option<Movability>,
 }
 
@@ -2434,7 +2437,7 @@ impl<'hir> Ty<'hir> {
     pub fn peel_refs(&self) -> &Self {
         let mut final_ty = self;
         while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind {
-            final_ty = &ty;
+            final_ty = ty;
         }
         final_ty
     }
diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs
index 33f02a115ef..93613ef27d4 100644
--- a/compiler/rustc_hir/src/hir_id.rs
+++ b/compiler/rustc_hir/src/hir_id.rs
@@ -116,7 +116,7 @@ impl Ord for HirId {
 
 impl PartialOrd for HirId {
     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
-        Some(self.cmp(&other))
+        Some(self.cmp(other))
     }
 }
 
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index cbb530424ca..938ace2c785 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -448,7 +448,7 @@ pub trait Visitor<'v>: Sized {
 
 pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) {
     visitor.visit_id(param.hir_id);
-    visitor.visit_pat(&param.pat);
+    visitor.visit_pat(param.pat);
 }
 
 pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
@@ -470,7 +470,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
         }
         ItemKind::Fn(ref sig, ref generics, body_id) => visitor.visit_fn(
             FnKind::ItemFn(item.ident, generics, sig.header),
-            &sig.decl,
+            sig.decl,
             body_id,
             item.span,
             item.hir_id(),
@@ -544,7 +544,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
 
 pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body<'v>) {
     walk_list!(visitor, visit_param, body.params);
-    visitor.visit_expr(&body.value);
+    visitor.visit_expr(body.value);
 }
 
 pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, ident: Ident) {
@@ -580,7 +580,7 @@ pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local<'v>) {
     // dominates the local's definition.
     walk_list!(visitor, visit_expr, &local.init);
     visitor.visit_id(local.hir_id);
-    visitor.visit_pat(&local.pat);
+    visitor.visit_pat(local.pat);
     if let Some(els) = local.els {
         visitor.visit_block(els);
     }
@@ -606,7 +606,7 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) {
 
 pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) {
     visitor.visit_id(arm.hir_id);
-    visitor.visit_pat(&arm.pat);
+    visitor.visit_pat(arm.pat);
     if let Some(ref g) = arm.guard {
         match g {
             Guard::If(ref e) => visitor.visit_expr(e),
@@ -615,7 +615,7 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) {
             }
         }
     }
-    visitor.visit_expr(&arm.body);
+    visitor.visit_expr(arm.body);
 }
 
 pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
@@ -660,7 +660,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
 pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'v>) {
     visitor.visit_id(field.hir_id);
     visitor.visit_ident(field.ident);
-    visitor.visit_pat(&field.pat)
+    visitor.visit_pat(field.pat)
 }
 
 pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen) {
@@ -740,6 +740,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
             body,
             capture_clause: _,
             fn_decl_span: _,
+            fn_arg_span: _,
             movability: _,
         }) => {
             walk_list!(visitor, visit_generic_param, bound_generic_params);
@@ -799,7 +800,7 @@ pub fn walk_let_expr<'v, V: Visitor<'v>>(visitor: &mut V, let_expr: &'v Let<'v>)
 pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField<'v>) {
     visitor.visit_id(field.hir_id);
     visitor.visit_ident(field.ident);
-    visitor.visit_expr(&field.expr)
+    visitor.visit_expr(field.expr)
 }
 
 pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
@@ -807,10 +808,10 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
 
     match typ.kind {
         TyKind::Slice(ref ty) => visitor.visit_ty(ty),
-        TyKind::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty),
+        TyKind::Ptr(ref mutable_type) => visitor.visit_ty(mutable_type.ty),
         TyKind::Rptr(ref lifetime, ref mutable_type) => {
             visitor.visit_lifetime(lifetime);
-            visitor.visit_ty(&mutable_type.ty)
+            visitor.visit_ty(mutable_type.ty)
         }
         TyKind::Never => {}
         TyKind::Tup(tuple_element_types) => {
@@ -818,7 +819,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
         }
         TyKind::BareFn(ref function_declaration) => {
             walk_list!(visitor, visit_generic_param, function_declaration.generic_params);
-            visitor.visit_fn_decl(&function_declaration.decl);
+            visitor.visit_fn_decl(function_declaration.decl);
         }
         TyKind::Path(ref qpath) => {
             visitor.visit_qpath(qpath, typ.hir_id, typ.span);
@@ -951,8 +952,8 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
     let TraitItem { ident, generics, ref defaultness, ref kind, span, owner_id: _ } = *trait_item;
     let hir_id = trait_item.hir_id();
     visitor.visit_ident(ident);
-    visitor.visit_generics(&generics);
-    visitor.visit_defaultness(&defaultness);
+    visitor.visit_generics(generics);
+    visitor.visit_defaultness(defaultness);
     match *kind {
         TraitItemKind::Const(ref ty, default) => {
             visitor.visit_id(hir_id);
@@ -961,13 +962,13 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
         }
         TraitItemKind::Fn(ref sig, TraitFn::Required(param_names)) => {
             visitor.visit_id(hir_id);
-            visitor.visit_fn_decl(&sig.decl);
+            visitor.visit_fn_decl(sig.decl);
             for &param_name in param_names {
                 visitor.visit_ident(param_name);
             }
         }
         TraitItemKind::Fn(ref sig, TraitFn::Provided(body_id)) => {
-            visitor.visit_fn(FnKind::Method(ident, sig), &sig.decl, body_id, span, hir_id);
+            visitor.visit_fn(FnKind::Method(ident, sig), sig.decl, body_id, span, hir_id);
         }
         TraitItemKind::Type(bounds, ref default) => {
             visitor.visit_id(hir_id);
@@ -1009,7 +1010,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
         ImplItemKind::Fn(ref sig, body_id) => {
             visitor.visit_fn(
                 FnKind::Method(impl_item.ident, sig),
-                &sig.decl,
+                sig.decl,
                 body_id,
                 impl_item.span,
                 impl_item.hir_id(),
@@ -1042,7 +1043,7 @@ pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'
 
 pub fn walk_trait_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_ref: &'v TraitRef<'v>) {
     visitor.visit_id(trait_ref.hir_ref_id);
-    visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id)
+    visitor.visit_path(trait_ref.path, trait_ref.hir_ref_id)
 }
 
 pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericBound<'v>) {
@@ -1074,7 +1075,7 @@ pub fn walk_struct_def<'v, V: Visitor<'v>>(
 pub fn walk_field_def<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v FieldDef<'v>) {
     visitor.visit_id(field.hir_id);
     visitor.visit_ident(field.ident);
-    visitor.visit_ty(&field.ty);
+    visitor.visit_ty(field.ty);
 }
 
 pub fn walk_enum_def<'v, V: Visitor<'v>>(
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index 47915b4bd4e..f64d65cc6ad 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -11,7 +11,6 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::GenericArg;
-use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::ty::{
     self, subst, subst::SubstsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, TyCtxt,
 };
@@ -83,9 +82,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 Res::Def(DefKind::TyParam, src_def_id) => {
                     if let Some(param_local_id) = param.def_id.as_local() {
                         let param_name = tcx.hir().ty_param_name(param_local_id);
-                        let infcx = tcx.infer_ctxt().build();
-                        let param_type =
-                            infcx.resolve_numeric_literals_with_default(tcx.type_of(param.def_id));
+                        let param_type = tcx.type_of(param.def_id);
                         if param_type.is_suggestable(tcx, false) {
                             err.span_suggestion(
                                 tcx.def_span(src_def_id),
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 82150310638..f204d59d005 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -347,7 +347,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 assert!(self_ty.is_some());
             }
         } else {
-            assert!(self_ty.is_none() && parent_substs.is_empty());
+            assert!(self_ty.is_none());
         }
 
         let arg_count = Self::check_generic_arg_count(
@@ -1821,7 +1821,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         // Check if we have an enum variant.
         let mut variant_resolution = None;
-        if let ty::Adt(adt_def, _) = qself_ty.kind() {
+        if let ty::Adt(adt_def, adt_substs) = qself_ty.kind() {
             if adt_def.is_enum() {
                 let variant_def = adt_def
                     .variants()
@@ -1923,8 +1923,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 let Some(assoc_ty_did) = self.lookup_assoc_ty(assoc_ident, hir_ref_id, span, impl_) else {
                     continue;
                 };
-                // FIXME(inherent_associated_types): This does not substitute parameters.
-                let ty = tcx.type_of(assoc_ty_did);
+                let item_substs = self.create_substs_for_associated_item(
+                    span,
+                    assoc_ty_did,
+                    assoc_segment,
+                    adt_substs,
+                );
+                let ty = tcx.bound_type_of(assoc_ty_did).subst(tcx, item_substs);
                 return Ok((ty, DefKind::AssocTy, assoc_ty_did));
             }
         }
diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs
index ba58672e759..82a77416a19 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_method.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs
@@ -173,13 +173,11 @@ fn compare_predicate_entailment<'tcx>(
         impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
     debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs);
 
-    let impl_m_generics = tcx.generics_of(impl_m.def_id);
-    let trait_m_generics = tcx.generics_of(trait_m.def_id);
     let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
     let trait_m_predicates = tcx.predicates_of(trait_m.def_id);
 
     // Check region bounds.
-    check_region_bounds_on_impl_item(tcx, impl_m, trait_m, &trait_m_generics, &impl_m_generics)?;
+    check_region_bounds_on_impl_item(tcx, impl_m, trait_m, false)?;
 
     // Create obligations for each predicate declared by the impl
     // definition in the context of the trait's parameter
@@ -338,6 +336,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
     // First, check a few of the same thing as `compare_impl_method`, just so we don't ICE during substitutions later.
     compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?;
     compare_generic_param_kinds(tcx, impl_m, trait_m, true)?;
+    check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?;
 
     let trait_to_impl_substs = impl_trait_ref.substs;
 
@@ -722,12 +721,14 @@ fn check_region_bounds_on_impl_item<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_m: &ty::AssocItem,
     trait_m: &ty::AssocItem,
-    trait_generics: &ty::Generics,
-    impl_generics: &ty::Generics,
+    delay: bool,
 ) -> Result<(), ErrorGuaranteed> {
-    let trait_params = trait_generics.own_counts().lifetimes;
+    let impl_generics = tcx.generics_of(impl_m.def_id);
     let impl_params = impl_generics.own_counts().lifetimes;
 
+    let trait_generics = tcx.generics_of(trait_m.def_id);
+    let trait_params = trait_generics.own_counts().lifetimes;
+
     debug!(
         "check_region_bounds_on_impl_item: \
             trait_generics={:?} \
@@ -761,12 +762,16 @@ fn check_region_bounds_on_impl_item<'tcx>(
             None
         };
 
-        let reported = tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait {
-            span,
-            item_kind: assoc_item_kind_str(impl_m),
-            ident: impl_m.ident(tcx),
-            generics_span,
-        });
+        let reported = tcx
+            .sess
+            .create_err(LifetimesOrBoundsMismatchOnTrait {
+                span,
+                item_kind: assoc_item_kind_str(impl_m),
+                ident: impl_m.ident(tcx),
+                generics_span,
+            })
+            .emit_unless(delay);
+
         return Err(reported);
     }
 
@@ -1504,18 +1509,10 @@ fn compare_type_predicate_entailment<'tcx>(
     let trait_to_impl_substs =
         impl_substs.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.substs);
 
-    let impl_ty_generics = tcx.generics_of(impl_ty.def_id);
-    let trait_ty_generics = tcx.generics_of(trait_ty.def_id);
     let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id);
     let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
 
-    check_region_bounds_on_impl_item(
-        tcx,
-        impl_ty,
-        trait_ty,
-        &trait_ty_generics,
-        &impl_ty_generics,
-    )?;
+    check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?;
 
     let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_substs);
 
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index ff32329e431..b315ebad468 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -241,17 +241,46 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
             // scopes, meaning that temporaries cannot outlive them.
             // This ensures fixed size stacks.
             hir::ExprKind::Binary(
-                source_map::Spanned { node: hir::BinOpKind::And, .. },
-                _,
-                ref r,
-            )
-            | hir::ExprKind::Binary(
-                source_map::Spanned { node: hir::BinOpKind::Or, .. },
-                _,
+                source_map::Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
+                ref l,
                 ref r,
             ) => {
-                // For shortcircuiting operators, mark the RHS as a terminating
-                // scope since it only executes conditionally.
+                // expr is a short circuiting operator (|| or &&). As its
+                // functionality can't be overridden by traits, it always
+                // processes bool sub-expressions. bools are Copy and thus we
+                // can drop any temporaries in evaluation (read) order
+                // (with the exception of potentially failing let expressions).
+                // We achieve this by enclosing the operands in a terminating
+                // scope, both the LHS and the RHS.
+
+                // We optimize this a little in the presence of chains.
+                // Chains like a && b && c get lowered to AND(AND(a, b), c).
+                // In here, b and c are RHS, while a is the only LHS operand in
+                // that chain. This holds true for longer chains as well: the
+                // leading operand is always the only LHS operand that is not a
+                // binop itself. Putting a binop like AND(a, b) into a
+                // terminating scope is not useful, thus we only put the LHS
+                // into a terminating scope if it is not a binop.
+
+                let terminate_lhs = match l.kind {
+                    // let expressions can create temporaries that live on
+                    hir::ExprKind::Let(_) => false,
+                    // binops already drop their temporaries, so there is no
+                    // need to put them into a terminating scope.
+                    // This is purely an optimization to reduce the number of
+                    // terminating scopes.
+                    hir::ExprKind::Binary(
+                        source_map::Spanned {
+                            node: hir::BinOpKind::And | hir::BinOpKind::Or, ..
+                        },
+                        ..,
+                    ) => false,
+                    // otherwise: mark it as terminating
+                    _ => true,
+                };
+                if terminate_lhs {
+                    terminating(l.hir_id.local_id);
+                }
 
                 // `Let` expressions (in a let-chain) shouldn't be terminating, as their temporaries
                 // should live beyond the immediate expression
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 7daed74e9de..b065ace6bf5 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1544,7 +1544,7 @@ fn check_fn_or_method<'tcx>(
     check_where_clauses(wfcx, span, def_id);
 
     check_return_position_impl_trait_in_trait_bounds(
-        tcx,
+        wfcx,
         def_id,
         sig.output(),
         hir_decl.output.span(),
@@ -1580,13 +1580,14 @@ fn check_fn_or_method<'tcx>(
 
 /// Basically `check_associated_type_bounds`, but separated for now and should be
 /// deduplicated when RPITITs get lowered into real associated items.
-#[tracing::instrument(level = "trace", skip(tcx))]
+#[tracing::instrument(level = "trace", skip(wfcx))]
 fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
-    tcx: TyCtxt<'tcx>,
+    wfcx: &WfCheckingCtxt<'_, 'tcx>,
     fn_def_id: LocalDefId,
     fn_output: Ty<'tcx>,
     span: Span,
 ) {
+    let tcx = wfcx.tcx();
     if let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id())
         && assoc_item.container == ty::AssocItemContainer::TraitContainer
     {
@@ -1596,22 +1597,20 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
                 && tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
                 && tcx.impl_trait_in_trait_parent(proj.item_def_id) == fn_def_id.to_def_id()
             {
-                // Create a new context, since we want the opaque's ParamEnv and not the parent's.
                 let span = tcx.def_span(proj.item_def_id);
-                enter_wf_checking_ctxt(tcx, span, proj.item_def_id.expect_local(), |wfcx| {
-                    let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id);
-                    let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
-                        let normalized_bound = wfcx.normalize(span, None, bound);
-                        traits::wf::predicate_obligations(
-                            wfcx.infcx,
-                            wfcx.param_env,
-                            wfcx.body_id,
-                            normalized_bound,
-                            bound_span,
-                        )
-                    });
-                    wfcx.register_obligations(wf_obligations);
+                let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id);
+                let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
+                    let bound = ty::EarlyBinder(bound).subst(tcx, proj.substs);
+                    let normalized_bound = wfcx.normalize(span, None, bound);
+                    traits::wf::predicate_obligations(
+                        wfcx.infcx,
+                        wfcx.param_env,
+                        wfcx.body_id,
+                        normalized_bound,
+                        bound_span,
+                    )
                 });
+                wfcx.register_obligations(wf_obligations);
             }
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs
index d0c31733481..5749b04783c 100644
--- a/compiler/rustc_hir_analysis/src/check_unused.rs
+++ b/compiler/rustc_hir_analysis/src/check_unused.rs
@@ -57,25 +57,6 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
         .maybe_unused_extern_crates(())
         .iter()
         .filter(|&&(def_id, _)| {
-            // The `def_id` here actually was calculated during resolution (at least
-            // at the time of this writing) and is being shipped to us via a side
-            // channel of the tcx. There may have been extra expansion phases,
-            // however, which ended up removing the `def_id` *after* expansion.
-            //
-            // As a result we need to verify that `def_id` is indeed still valid for
-            // our AST and actually present in the HIR map. If it's not there then
-            // there's safely nothing to warn about, and otherwise we carry on with
-            // our execution.
-            //
-            // Note that if we carry through to the `extern_mod_stmt_cnum` query
-            // below it'll cause a panic because `def_id` is actually bogus at this
-            // point in time otherwise.
-            if tcx.hir().find(tcx.hir().local_def_id_to_hir_id(def_id)).is_none() {
-                return false;
-            }
-            true
-        })
-        .filter(|&&(def_id, _)| {
             tcx.extern_mod_stmt_cnum(def_id).map_or(true, |cnum| {
                 !tcx.is_compiler_builtins(cnum)
                     && !tcx.is_panic_runtime(cnum)
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index d623e726139..b7084303aaf 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -2073,6 +2073,11 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
         }
     }
 
+    if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
+        codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE;
+        codegen_fn_attrs.inline = InlineAttr::Never;
+    }
+
     // Weak lang items have the same semantics as "std internal" symbols in the
     // sense that they're preserved through all our LTO passes and only
     // strippable by the linker.
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 2460a23bb3f..3791b2c8661 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1480,6 +1480,7 @@ impl<'a> State<'a> {
                 fn_decl,
                 body,
                 fn_decl_span: _,
+                fn_arg_span: _,
                 movability: _,
                 def_id: _,
             }) => {
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 5d3419b3b6e..429cb60ba2b 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -456,10 +456,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .iter()
             .map(|ty| ArgKind::from_expected_ty(*ty, None))
             .collect();
-        let (closure_span, found_args) = match self.get_fn_like_arguments(expr_map_node) {
-            Some((sp, args)) => (Some(sp), args),
-            None => (None, Vec::new()),
-        };
+        let (closure_span, closure_arg_span, found_args) =
+            match self.get_fn_like_arguments(expr_map_node) {
+                Some((sp, arg_sp, args)) => (Some(sp), arg_sp, args),
+                None => (None, None, Vec::new()),
+            };
         let expected_span =
             expected_sig.cause_span.unwrap_or_else(|| self.tcx.def_span(expr_def_id));
         self.report_arg_count_mismatch(
@@ -468,6 +469,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             expected_args,
             found_args,
             true,
+            closure_arg_span,
         )
         .emit();
 
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 0c5bbb3e20b..4a112e80f1d 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -528,6 +528,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
         let ty = match res {
             Res::Err => {
+                self.suggest_assoc_method_call(segs);
                 let e =
                     self.tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
                 self.set_tainted_by_errors(e);
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 86384c7b93e..3078e0cbeda 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1918,6 +1918,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         receiver: Option<&'tcx hir::Expr<'tcx>>,
         args: &'tcx [hir::Expr<'tcx>],
     ) -> bool {
+        // Do not call `fn_sig` on non-functions.
+        if !matches!(
+            self.tcx.def_kind(def_id),
+            DefKind::Fn | DefKind::AssocFn | DefKind::Variant | DefKind::Ctor(..)
+        ) {
+            return false;
+        }
+
         let sig = self.tcx.fn_sig(def_id).skip_binder();
         let args_referencing_param: Vec<_> = sig
             .inputs()
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index ea141e815bf..1e9b5752130 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -22,7 +22,7 @@ use rustc_middle::ty::{self, Const, Ty, TyCtxt};
 use rustc_session::Session;
 use rustc_span::symbol::Ident;
 use rustc_span::{self, Span};
-use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
+use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
 
 use std::cell::{Cell, RefCell};
 use std::ops::Deref;
@@ -162,6 +162,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             infcx: &self.infcx,
             typeck_results: Some(self.typeck_results.borrow()),
             fallback_has_occurred: self.fallback_has_occurred.get(),
+            normalize_fn_sig: Box::new(|fn_sig| {
+                if fn_sig.has_escaping_bound_vars() {
+                    return fn_sig;
+                }
+                self.probe(|_| {
+                    let ocx = ObligationCtxt::new_in_snapshot(self);
+                    let normalized_fn_sig =
+                        ocx.normalize(&ObligationCause::dummy(), self.param_env, fn_sig);
+                    if ocx.select_all_or_error().is_empty() {
+                        let normalized_fn_sig = self.resolve_vars_if_possible(normalized_fn_sig);
+                        if !normalized_fn_sig.needs_infer() {
+                            return normalized_fn_sig;
+                        }
+                    }
+                    fn_sig
+                })
+            }),
         }
     }
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index b9a8d16311c..1daca464b47 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -10,7 +10,7 @@ use rustc_hir::{
     Expr, ExprKind, GenericBound, Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicate,
 };
 use rustc_hir_analysis::astconv::AstConv;
-use rustc_infer::infer::{self, TyCtxtInferExt};
+use rustc_infer::infer;
 use rustc_infer::traits::{self, StatementAsExpression};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Binder, DefIdTree, IsSuggestable, ToPredicate, Ty};
@@ -921,19 +921,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, ty);
             let bound_vars = self.tcx.late_bound_vars(fn_id);
             let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars));
-            let ty = self.normalize(expr.span, ty);
             let ty = match self.tcx.asyncness(fn_id.owner) {
-                hir::IsAsync::Async => {
-                    let infcx = self.tcx.infer_ctxt().build();
-                    infcx.get_impl_future_output_ty(ty).unwrap_or_else(|| {
-                        span_bug!(
-                            fn_decl.output.span(),
-                            "failed to get output type of async function"
-                        )
-                    })
-                }
+                hir::IsAsync::Async => self.get_impl_future_output_ty(ty).unwrap_or_else(|| {
+                    span_bug!(fn_decl.output.span(), "failed to get output type of async function")
+                }),
                 hir::IsAsync::NotAsync => ty,
             };
+            let ty = self.normalize(expr.span, ty);
             if self.can_coerce(found, ty) {
                 err.multipart_suggestion(
                     "you might have meant to return this value",
diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/inherited.rs
index 869ad07c00d..b33e7b8d68c 100644
--- a/compiler/rustc_hir_typeck/src/inherited.rs
+++ b/compiler/rustc_hir_typeck/src/inherited.rs
@@ -1,7 +1,6 @@
 use super::callee::DeferredCallResolution;
 
 use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::sync::Lrc;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::HirIdMap;
@@ -11,9 +10,7 @@ use rustc_middle::ty::visit::TypeVisitable;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::def_id::LocalDefIdMap;
 use rustc_span::{self, Span};
-use rustc_trait_selection::traits::{
-    self, ObligationCause, ObligationCtxt, TraitEngine, TraitEngineExt as _,
-};
+use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _};
 
 use std::cell::RefCell;
 use std::ops::Deref;
@@ -92,29 +89,7 @@ impl<'tcx> Inherited<'tcx> {
             infcx: tcx
                 .infer_ctxt()
                 .ignoring_regions()
-                .with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id))
-                .with_normalize_fn_sig_for_diagnostic(Lrc::new(move |infcx, fn_sig| {
-                    if fn_sig.has_escaping_bound_vars() {
-                        return fn_sig;
-                    }
-                    infcx.probe(|_| {
-                        let ocx = ObligationCtxt::new_in_snapshot(infcx);
-                        let normalized_fn_sig = ocx.normalize(
-                            &ObligationCause::dummy(),
-                            // FIXME(compiler-errors): This is probably not the right param-env...
-                            infcx.tcx.param_env(def_id),
-                            fn_sig,
-                        );
-                        if ocx.select_all_or_error().is_empty() {
-                            let normalized_fn_sig =
-                                infcx.resolve_vars_if_possible(normalized_fn_sig);
-                            if !normalized_fn_sig.needs_infer() {
-                                return normalized_fn_sig;
-                            }
-                        }
-                        fn_sig
-                    })
-                })),
+                .with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)),
             def_id,
             typeck_results: RefCell::new(ty::TypeckResults::new(hir_owner)),
         }
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index ebbd5eb1e64..a2ca5c3b7b7 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -20,7 +20,7 @@ use rustc_hir::def_id::DefId;
 use rustc_infer::infer::{self, InferOk};
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
-use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, Ty, TypeVisitable};
+use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitable};
 use rustc_span::symbol::Ident;
 use rustc_span::Span;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -217,7 +217,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
 
             // We probe again, taking all traits into account (not only those in scope).
-            let mut candidates =
+            let candidates =
                 match self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::AllTraits) {
                     // If we find a different result the caller probably forgot to import a trait.
                     Ok(ref new_pick) if pick.differs_from(new_pick) => {
@@ -236,7 +236,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         .collect(),
                     _ => Vec::new(),
                 };
-            candidates.retain(|candidate| *candidate != self.tcx.parent(result.callee.def_id));
 
             return Err(IllegalSizedBound(candidates, needs_mut, span));
         }
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index c78a32c29dc..ae299cc9d13 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -9,7 +9,6 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
-use rustc_hir::def::Namespace;
 use rustc_infer::infer::canonical::OriginalQueryValues;
 use rustc_infer::infer::canonical::{Canonical, QueryResponse};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -1876,6 +1875,15 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         self.tcx.erase_late_bound_regions(value)
     }
 
+    /// Determine if the given associated item type is relevant in the current context.
+    fn is_relevant_kind_for_mode(&self, kind: ty::AssocKind) -> bool {
+        match (self.mode, kind) {
+            (Mode::MethodCall, ty::AssocKind::Fn) => true,
+            (Mode::Path, ty::AssocKind::Const | ty::AssocKind::Fn) => true,
+            _ => false,
+        }
+    }
+
     /// Finds the method with the appropriate name (or return type, as the case may be). If
     /// `allow_similar_names` is set, find methods with close-matching names.
     // The length of the returned iterator is nearly always 0 or 1 and this
@@ -1888,7 +1896,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     .associated_items(def_id)
                     .in_definition_order()
                     .filter(|x| {
-                        if x.kind.namespace() != Namespace::ValueNS {
+                        if !self.is_relevant_kind_for_mode(x.kind) {
                             return false;
                         }
                         match lev_distance_with_substrings(name.as_str(), x.name.as_str(), max_dist)
@@ -1902,10 +1910,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             } else {
                 self.fcx
                     .associated_value(def_id, name)
+                    .filter(|x| self.is_relevant_kind_for_mode(x.kind))
                     .map_or_else(SmallVec::new, |x| SmallVec::from_buf([x]))
             }
         } else {
-            self.tcx.associated_items(def_id).in_definition_order().copied().collect()
+            self.tcx
+                .associated_items(def_id)
+                .in_definition_order()
+                .filter(|x| self.is_relevant_kind_for_mode(x.kind))
+                .copied()
+                .collect()
         }
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 727fab9e7aa..9ba4ddfd5cf 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -5,6 +5,7 @@ use crate::errors;
 use crate::FnCtxt;
 use rustc_ast::ast::Mutability;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_errors::StashKey;
 use rustc_errors::{
     pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
     MultiSpan,
@@ -13,6 +14,8 @@ use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
+use rustc_hir::PatKind::Binding;
+use rustc_hir::PathSegment;
 use rustc_hir::{ExprKind, Node, QPath};
 use rustc_infer::infer::{
     type_variable::{TypeVariableOrigin, TypeVariableOriginKind},
@@ -35,11 +38,11 @@ use rustc_trait_selection::traits::{
     FulfillmentError, Obligation, ObligationCause, ObligationCauseCode,
 };
 
-use std::cmp::Ordering;
-use std::iter;
-
 use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope};
 use super::{CandidateSource, MethodError, NoMatchData};
+use rustc_hir::intravisit::Visitor;
+use std::cmp::Ordering;
+use std::iter;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
@@ -1462,6 +1465,61 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         false
     }
 
+    /// For code `rect::area(...)`,
+    /// if `rect` is a local variable and `area` is a valid assoc method for it,
+    /// we try to suggest `rect.area()`
+    pub(crate) fn suggest_assoc_method_call(&self, segs: &[PathSegment<'_>]) {
+        debug!("suggest_assoc_method_call segs: {:?}", segs);
+        let [seg1, seg2] = segs else { return; };
+        let Some(mut diag) =
+                self.tcx.sess.diagnostic().steal_diagnostic(seg1.ident.span, StashKey::CallAssocMethod)
+                else { return };
+
+        let map = self.infcx.tcx.hir();
+        let body = map.body(rustc_hir::BodyId { hir_id: self.body_id });
+        struct LetVisitor<'a> {
+            result: Option<&'a hir::Expr<'a>>,
+            ident_name: Symbol,
+        }
+
+        impl<'v> Visitor<'v> for LetVisitor<'v> {
+            fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) {
+                if let hir::StmtKind::Local(hir::Local { pat, init, .. }) = &ex.kind {
+                    if let Binding(_, _, ident, ..) = pat.kind &&
+                        ident.name == self.ident_name {
+                        self.result = *init;
+                    }
+                }
+                hir::intravisit::walk_stmt(self, ex);
+            }
+        }
+
+        let mut visitor = LetVisitor { result: None, ident_name: seg1.ident.name };
+        visitor.visit_body(&body);
+
+        let parent = self.tcx.hir().get_parent_node(seg1.hir_id);
+        if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) &&
+            let Some(expr) = visitor.result {
+            let self_ty = self.node_ty(expr.hir_id);
+            let probe = self.lookup_probe(
+                seg2.ident,
+                self_ty,
+                call_expr,
+                ProbeScope::TraitsInScope,
+            );
+            if probe.is_ok() {
+                let sm = self.infcx.tcx.sess.source_map();
+                diag.span_suggestion_verbose(
+                    sm.span_extend_while(seg1.ident.span.shrink_to_hi(), |c| c == ':').unwrap(),
+                    "you may have meant to call an instance method",
+                    ".".to_string(),
+                    Applicability::MaybeIncorrect
+                );
+            }
+        }
+        diag.emit();
+    }
+
     /// Suggest calling a method on a field i.e. `a.field.bar()` instead of `a.bar()`
     fn suggest_calling_method_on_field(
         &self,
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 2483ab724a4..4429e4f4362 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -77,10 +77,6 @@ impl<'tcx> InferCtxt<'tcx> {
             err_count_on_creation: self.err_count_on_creation,
             in_snapshot: self.in_snapshot.clone(),
             universe: self.universe.clone(),
-            normalize_fn_sig_for_diagnostic: self
-                .normalize_fn_sig_for_diagnostic
-                .as_ref()
-                .map(|f| f.clone()),
             intercrate: self.intercrate,
         }
     }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index e2be8fb12d0..662136ca18d 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -95,6 +95,7 @@ pub mod nice_region_error;
 pub struct TypeErrCtxt<'a, 'tcx> {
     pub infcx: &'a InferCtxt<'tcx>,
     pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
+    pub normalize_fn_sig: Box<dyn Fn(ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> + 'a>,
     pub fallback_has_occurred: bool,
 }
 
@@ -1007,22 +1008,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         }
     }
 
-    fn normalize_fn_sig_for_diagnostic(&self, sig: ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> {
-        if let Some(normalize) = &self.normalize_fn_sig_for_diagnostic {
-            normalize(self, sig)
-        } else {
-            sig
-        }
-    }
-
     /// Given two `fn` signatures highlight only sub-parts that are different.
     fn cmp_fn_sig(
         &self,
         sig1: &ty::PolyFnSig<'tcx>,
         sig2: &ty::PolyFnSig<'tcx>,
     ) -> (DiagnosticStyledString, DiagnosticStyledString) {
-        let sig1 = &self.normalize_fn_sig_for_diagnostic(*sig1);
-        let sig2 = &self.normalize_fn_sig_for_diagnostic(*sig2);
+        let sig1 = &(self.normalize_fn_sig)(*sig1);
+        let sig2 = &(self.normalize_fn_sig)(*sig2);
 
         let get_lifetimes = |sig| {
             use rustc_hir::def::Namespace;
@@ -1262,7 +1255,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     let num_display_types = consts_offset - regions_len;
                     for (i, (ta1, ta2)) in type_arguments.take(num_display_types).enumerate() {
                         let i = i + regions_len;
-                        if ta1 == ta2 {
+                        if ta1 == ta2 && !self.tcx.sess.verbose() {
                             values.0.push_normal("_");
                             values.1.push_normal("_");
                         } else {
@@ -1278,7 +1271,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     let const_arguments = sub1.consts().zip(sub2.consts());
                     for (i, (ca1, ca2)) in const_arguments.enumerate() {
                         let i = i + consts_offset;
-                        if ca1 == ca2 {
+                        if ca1 == ca2 && !self.tcx.sess.verbose() {
                             values.0.push_normal("_");
                             values.1.push_normal("_");
                         } else {
@@ -1457,7 +1450,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             (ty::FnPtr(sig1), ty::FnPtr(sig2)) => self.cmp_fn_sig(sig1, sig2),
 
             _ => {
-                if t1 == t2 {
+                if t1 == t2 && !self.tcx.sess.verbose() {
                     // The two types are the same, elide and don't highlight.
                     (DiagnosticStyledString::normal("_"), DiagnosticStyledString::normal("_"))
                 } else {
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 2bcb47cc383..2ce7cd8beba 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -80,7 +80,6 @@ pub struct InferOk<'tcx, T> {
 }
 pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
 
-pub type Bound<T> = Option<T>;
 pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
 pub type FixupResult<'tcx, T> = Result<T, FixupError<'tcx>>; // "fixup result"
 
@@ -334,9 +333,6 @@ pub struct InferCtxt<'tcx> {
     /// bound.
     universe: Cell<ty::UniverseIndex>,
 
-    normalize_fn_sig_for_diagnostic:
-        Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
-
     /// During coherence we have to assume that other crates may add
     /// additional impls which we currently don't know about.
     ///
@@ -573,8 +569,6 @@ pub struct InferCtxtBuilder<'tcx> {
     considering_regions: bool,
     /// Whether we are in coherence mode.
     intercrate: bool,
-    normalize_fn_sig_for_diagnostic:
-        Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
 }
 
 pub trait TyCtxtInferExt<'tcx> {
@@ -587,7 +581,6 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
             tcx: self,
             defining_use_anchor: DefiningAnchor::Error,
             considering_regions: true,
-            normalize_fn_sig_for_diagnostic: None,
             intercrate: false,
         }
     }
@@ -615,14 +608,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
         self
     }
 
-    pub fn with_normalize_fn_sig_for_diagnostic(
-        mut self,
-        fun: Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>,
-    ) -> Self {
-        self.normalize_fn_sig_for_diagnostic = Some(fun);
-        self
-    }
-
     /// Given a canonical value `C` as a starting point, create an
     /// inference context that contains each of the bound values
     /// within instantiated as a fresh variable. The `f` closure is
@@ -644,13 +629,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
     }
 
     pub fn build(&mut self) -> InferCtxt<'tcx> {
-        let InferCtxtBuilder {
-            tcx,
-            defining_use_anchor,
-            considering_regions,
-            ref normalize_fn_sig_for_diagnostic,
-            intercrate,
-        } = *self;
+        let InferCtxtBuilder { tcx, defining_use_anchor, considering_regions, intercrate } = *self;
         InferCtxt {
             tcx,
             defining_use_anchor,
@@ -666,9 +645,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
             in_snapshot: Cell::new(false),
             skip_leak_check: Cell::new(false),
             universe: Cell::new(ty::UniverseIndex::ROOT),
-            normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic
-                .as_ref()
-                .map(|f| f.clone()),
             intercrate,
         }
     }
@@ -709,7 +685,12 @@ impl<'tcx> InferCtxt<'tcx> {
     /// Creates a `TypeErrCtxt` for emitting various inference errors.
     /// During typeck, use `FnCtxt::err_ctxt` instead.
     pub fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
-        TypeErrCtxt { infcx: self, typeck_results: None, fallback_has_occurred: false }
+        TypeErrCtxt {
+            infcx: self,
+            typeck_results: None,
+            fallback_has_occurred: false,
+            normalize_fn_sig: Box::new(|fn_sig| fn_sig),
+        }
     }
 
     pub fn is_in_snapshot(&self) -> bool {
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 7f1d21bf1d8..6b5b5df9e2a 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -207,10 +207,7 @@ pub fn register_plugins<'a>(
         });
     }
 
-    let mut lint_store = rustc_lint::new_lint_store(
-        sess.opts.unstable_opts.no_interleave_lints,
-        sess.enable_internal_lints(),
-    );
+    let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
     register_lints(sess, &mut lint_store);
 
     let registrars =
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index a03e7b0dae5..a6205f4d3a5 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -666,7 +666,6 @@ fn test_unstable_options_tracking_hash() {
     untracked!(mir_pretty_relative_line_numbers, true);
     untracked!(nll_facts, true);
     untracked!(no_analysis, true);
-    untracked!(no_interleave_lints, true);
     untracked!(no_leak_check, true);
     untracked!(no_parallel_llvm, true);
     untracked!(parse_only, true);
diff --git a/compiler/rustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml
index ad685c2ad19..23294dc2e1b 100644
--- a/compiler/rustc_lexer/Cargo.toml
+++ b/compiler/rustc_lexer/Cargo.toml
@@ -19,4 +19,4 @@ unicode-xid = "0.2.0"
 unic-emoji-char = "0.9.0"
 
 [dev-dependencies]
-expect-test = "1.0"
+expect-test = "1.4.0"
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index a7a4d0ca527..215df567e0e 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -25,8 +25,6 @@ use rustc_session::Session;
 use rustc_span::symbol::Ident;
 use rustc_span::Span;
 
-use std::slice;
-
 macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({
     $cx.pass.$f(&$cx.context, $($args),*);
 }) }
@@ -300,20 +298,14 @@ impl LintPass for EarlyLintPassObjects<'_> {
     }
 }
 
-macro_rules! expand_early_lint_pass_impl_methods {
-    ([$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
-        $(fn $name(&mut self, context: &EarlyContext<'_>, $($param: $arg),*) {
-            for obj in self.lints.iter_mut() {
-                obj.$name(context, $($param),*);
-            }
-        })*
-    )
-}
-
 macro_rules! early_lint_pass_impl {
-    ([], [$($methods:tt)*]) => (
+    ([], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
         impl EarlyLintPass for EarlyLintPassObjects<'_> {
-            expand_early_lint_pass_impl_methods!([$($methods)*]);
+            $(fn $name(&mut self, context: &EarlyContext<'_>, $($param: $arg),*) {
+                for obj in self.lints.iter_mut() {
+                    obj.$name(context, $($param),*);
+                }
+            })*
         }
     )
 }
@@ -371,87 +363,36 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast::
     }
 }
 
-fn early_lint_node<'a>(
-    sess: &Session,
-    warn_about_weird_lints: bool,
-    lint_store: &LintStore,
-    registered_tools: &RegisteredTools,
-    buffered: LintBuffer,
-    pass: impl EarlyLintPass,
-    check_node: impl EarlyCheckNode<'a>,
-) -> LintBuffer {
-    let mut cx = EarlyContextAndPass {
-        context: EarlyContext::new(
-            sess,
-            warn_about_weird_lints,
-            lint_store,
-            registered_tools,
-            buffered,
-        ),
-        pass,
-    };
-
-    cx.with_lint_attrs(check_node.id(), check_node.attrs(), |cx| check_node.check(cx));
-    cx.context.buffered
-}
-
 pub fn check_ast_node<'a>(
     sess: &Session,
     pre_expansion: bool,
     lint_store: &LintStore,
     registered_tools: &RegisteredTools,
     lint_buffer: Option<LintBuffer>,
-    builtin_lints: impl EarlyLintPass,
+    builtin_lints: impl EarlyLintPass + 'static,
     check_node: impl EarlyCheckNode<'a>,
 ) {
     let passes =
         if pre_expansion { &lint_store.pre_expansion_passes } else { &lint_store.early_passes };
     let mut passes: Vec<_> = passes.iter().map(|p| (p)()).collect();
-    let mut buffered = lint_buffer.unwrap_or_default();
-
-    if sess.opts.unstable_opts.no_interleave_lints {
-        for (i, pass) in passes.iter_mut().enumerate() {
-            buffered =
-                sess.prof.verbose_generic_activity_with_arg("run_lint", pass.name()).run(|| {
-                    early_lint_node(
-                        sess,
-                        !pre_expansion && i == 0,
-                        lint_store,
-                        registered_tools,
-                        buffered,
-                        EarlyLintPassObjects { lints: slice::from_mut(pass) },
-                        check_node,
-                    )
-                });
-        }
-    } else {
-        buffered = early_lint_node(
+    passes.push(Box::new(builtin_lints));
+
+    let mut cx = EarlyContextAndPass {
+        context: EarlyContext::new(
             sess,
             !pre_expansion,
             lint_store,
             registered_tools,
-            buffered,
-            builtin_lints,
-            check_node,
-        );
-
-        if !passes.is_empty() {
-            buffered = early_lint_node(
-                sess,
-                false,
-                lint_store,
-                registered_tools,
-                buffered,
-                EarlyLintPassObjects { lints: &mut passes[..] },
-                check_node,
-            );
-        }
-    }
+            lint_buffer.unwrap_or_default(),
+        ),
+        pass: EarlyLintPassObjects { lints: &mut passes[..] },
+    };
+    cx.with_lint_attrs(check_node.id(), check_node.attrs(), |cx| check_node.check(cx));
 
     // All of the buffered lints should have been emitted at this point.
     // If not, that means that we somehow buffered a lint for a node id
     // that was not lint-checked (perhaps it doesn't exist?). This is a bug.
-    for (id, lints) in buffered.map {
+    for (id, lints) in cx.context.buffered.map {
         for early_lint in lints {
             sess.delay_span_bug(
                 early_lint.span,
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index 1d0b3f34d5d..e1aedc26d1b 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -28,7 +28,6 @@ use rustc_span::Span;
 
 use std::any::Any;
 use std::cell::Cell;
-use std::slice;
 
 /// Extract the `LintStore` from the query context.
 /// This function exists because we've erased `LintStore` as `dyn Any` in the context.
@@ -313,45 +312,42 @@ impl LintPass for LateLintPassObjects<'_, '_> {
     }
 }
 
-macro_rules! expand_late_lint_pass_impl_methods {
-    ([$hir:tt], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
-        $(fn $name(&mut self, context: &LateContext<$hir>, $($param: $arg),*) {
-            for obj in self.lints.iter_mut() {
-                obj.$name(context, $($param),*);
-            }
-        })*
-    )
-}
-
 macro_rules! late_lint_pass_impl {
-    ([], [$hir:tt], $methods:tt) => {
+    ([], [$hir:tt], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => {
         impl<$hir> LateLintPass<$hir> for LateLintPassObjects<'_, $hir> {
-            expand_late_lint_pass_impl_methods!([$hir], $methods);
+            $(fn $name(&mut self, context: &LateContext<$hir>, $($param: $arg),*) {
+                for obj in self.lints.iter_mut() {
+                    obj.$name(context, $($param),*);
+                }
+            })*
         }
     };
 }
 
 crate::late_lint_methods!(late_lint_pass_impl, [], ['tcx]);
 
-fn late_lint_mod_pass<'tcx, T: LateLintPass<'tcx>>(
+pub(super) fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
     tcx: TyCtxt<'tcx>,
     module_def_id: LocalDefId,
-    pass: T,
+    builtin_lints: T,
 ) {
-    let effective_visibilities = &tcx.effective_visibilities(());
-
     let context = LateContext {
         tcx,
         enclosing_body: None,
         cached_typeck_results: Cell::new(None),
         param_env: ty::ParamEnv::empty(),
-        effective_visibilities,
+        effective_visibilities: &tcx.effective_visibilities(()),
         lint_store: unerased_lint_store(tcx),
         last_node_with_lint_attrs: tcx.hir().local_def_id_to_hir_id(module_def_id),
         generics: None,
         only_module: true,
     };
 
+    let mut passes: Vec<_> =
+        unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
+    passes.push(Box::new(builtin_lints));
+    let pass = LateLintPassObjects { lints: &mut passes[..] };
+
     let mut cx = LateContextAndPass { context, pass };
 
     let (module, _span, hir_id) = tcx.hir().get_module(module_def_id);
@@ -365,46 +361,29 @@ fn late_lint_mod_pass<'tcx, T: LateLintPass<'tcx>>(
     }
 }
 
-pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx>>(
-    tcx: TyCtxt<'tcx>,
-    module_def_id: LocalDefId,
-    builtin_lints: T,
-) {
-    if tcx.sess.opts.unstable_opts.no_interleave_lints {
-        // These passes runs in late_lint_crate with -Z no_interleave_lints
-        return;
-    }
-
-    late_lint_mod_pass(tcx, module_def_id, builtin_lints);
-
-    let mut passes: Vec<_> =
-        unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
-
-    if !passes.is_empty() {
-        late_lint_mod_pass(tcx, module_def_id, LateLintPassObjects { lints: &mut passes[..] });
-    }
-}
-
-fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T) {
-    let effective_visibilities = &tcx.effective_visibilities(());
-
+fn late_lint_crate<'tcx, T: LateLintPass<'tcx> + 'tcx>(tcx: TyCtxt<'tcx>, builtin_lints: T) {
     let context = LateContext {
         tcx,
         enclosing_body: None,
         cached_typeck_results: Cell::new(None),
         param_env: ty::ParamEnv::empty(),
-        effective_visibilities,
+        effective_visibilities: &tcx.effective_visibilities(()),
         lint_store: unerased_lint_store(tcx),
         last_node_with_lint_attrs: hir::CRATE_HIR_ID,
         generics: None,
         only_module: false,
     };
 
+    let mut passes =
+        unerased_lint_store(tcx).late_passes.iter().map(|p| (p)(tcx)).collect::<Vec<_>>();
+    passes.push(Box::new(builtin_lints));
+    let pass = LateLintPassObjects { lints: &mut passes[..] };
+
     let mut cx = LateContextAndPass { context, pass };
 
     // Visit the whole crate.
     cx.with_lint_attrs(hir::CRATE_HIR_ID, |cx| {
-        // since the root module isn't visited as an item (because it isn't an
+        // Since the root module isn't visited as an item (because it isn't an
         // item), warn for it here.
         lint_callback!(cx, check_crate,);
         tcx.hir().walk_toplevel_module(cx);
@@ -413,41 +392,8 @@ fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T)
     })
 }
 
-fn late_lint_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) {
-    let mut passes =
-        unerased_lint_store(tcx).late_passes.iter().map(|p| (p)(tcx)).collect::<Vec<_>>();
-
-    if !tcx.sess.opts.unstable_opts.no_interleave_lints {
-        if !passes.is_empty() {
-            late_lint_pass_crate(tcx, LateLintPassObjects { lints: &mut passes[..] });
-        }
-
-        late_lint_pass_crate(tcx, builtin_lints);
-    } else {
-        for pass in &mut passes {
-            tcx.sess.prof.verbose_generic_activity_with_arg("run_late_lint", pass.name()).run(
-                || {
-                    late_lint_pass_crate(tcx, LateLintPassObjects { lints: slice::from_mut(pass) });
-                },
-            );
-        }
-
-        let mut passes: Vec<_> =
-            unerased_lint_store(tcx).late_module_passes.iter().map(|pass| (pass)(tcx)).collect();
-
-        for pass in &mut passes {
-            tcx.sess
-                .prof
-                .verbose_generic_activity_with_arg("run_late_module_lint", pass.name())
-                .run(|| {
-                    late_lint_pass_crate(tcx, LateLintPassObjects { lints: slice::from_mut(pass) });
-                });
-        }
-    }
-}
-
 /// Performs lint checking on a crate.
-pub fn check_crate<'tcx, T: LateLintPass<'tcx>>(
+pub fn check_crate<'tcx, T: LateLintPass<'tcx> + 'tcx>(
     tcx: TyCtxt<'tcx>,
     builtin_lints: impl FnOnce() -> T + Send,
 ) {
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index b6027476adf..10bae36e0fd 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -127,132 +127,116 @@ fn lint_mod(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
     late::late_lint_mod(tcx, module_def_id, BuiltinCombinedModuleLateLintPass::new());
 }
 
-macro_rules! pre_expansion_lint_passes {
-    ($macro:path, $args:tt) => {
-        $macro!($args, [KeywordIdents: KeywordIdents,]);
-    };
-}
-
-macro_rules! early_lint_passes {
-    ($macro:path, $args:tt) => {
-        $macro!(
-            $args,
-            [
-                UnusedParens: UnusedParens,
-                UnusedBraces: UnusedBraces,
-                UnusedImportBraces: UnusedImportBraces,
-                UnsafeCode: UnsafeCode,
-                SpecialModuleName: SpecialModuleName,
-                AnonymousParameters: AnonymousParameters,
-                EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
-                NonCamelCaseTypes: NonCamelCaseTypes,
-                DeprecatedAttr: DeprecatedAttr::new(),
-                WhileTrue: WhileTrue,
-                NonAsciiIdents: NonAsciiIdents,
-                HiddenUnicodeCodepoints: HiddenUnicodeCodepoints,
-                IncompleteFeatures: IncompleteFeatures,
-                RedundantSemicolons: RedundantSemicolons,
-                UnusedDocComment: UnusedDocComment,
-                UnexpectedCfgs: UnexpectedCfgs,
-            ]
-        );
-    };
-}
-
-macro_rules! declare_combined_early_pass {
-    ([$name:ident], $passes:tt) => (
-        early_lint_methods!(declare_combined_early_lint_pass, [pub $name, $passes]);
-    )
-}
-
-pre_expansion_lint_passes!(declare_combined_early_pass, [BuiltinCombinedPreExpansionLintPass]);
-early_lint_passes!(declare_combined_early_pass, [BuiltinCombinedEarlyLintPass]);
-
-macro_rules! late_lint_passes {
-    ($macro:path, $args:tt) => {
-        $macro!(
-            $args,
-            [
-                // Tracks state across modules
-                UnnameableTestItems: UnnameableTestItems::new(),
-                // Tracks attributes of parents
-                MissingDoc: MissingDoc::new(),
-                // Builds a global list of all impls of `Debug`.
-                // FIXME: Turn the computation of types which implement Debug into a query
-                // and change this to a module lint pass
-                MissingDebugImplementations: MissingDebugImplementations::default(),
-                // Keeps a global list of foreign declarations.
-                ClashingExternDeclarations: ClashingExternDeclarations::new(),
-            ]
-        );
-    };
-}
-
-macro_rules! late_lint_mod_passes {
-    ($macro:path, $args:tt) => {
-        $macro!(
-            $args,
-            [
-                ForLoopsOverFallibles: ForLoopsOverFallibles,
-                DerefIntoDynSupertrait: DerefIntoDynSupertrait,
-                HardwiredLints: HardwiredLints,
-                ImproperCTypesDeclarations: ImproperCTypesDeclarations,
-                ImproperCTypesDefinitions: ImproperCTypesDefinitions,
-                VariantSizeDifferences: VariantSizeDifferences,
-                BoxPointers: BoxPointers,
-                PathStatements: PathStatements,
-                LetUnderscore: LetUnderscore,
-                // Depends on referenced function signatures in expressions
-                UnusedResults: UnusedResults,
-                NonUpperCaseGlobals: NonUpperCaseGlobals,
-                NonShorthandFieldPatterns: NonShorthandFieldPatterns,
-                UnusedAllocation: UnusedAllocation,
-                // Depends on types used in type definitions
-                MissingCopyImplementations: MissingCopyImplementations,
-                // Depends on referenced function signatures in expressions
-                MutableTransmutes: MutableTransmutes,
-                TypeAliasBounds: TypeAliasBounds,
-                TrivialConstraints: TrivialConstraints,
-                TypeLimits: TypeLimits::new(),
-                NonSnakeCase: NonSnakeCase,
-                InvalidNoMangleItems: InvalidNoMangleItems,
-                // Depends on effective visibilities
-                UnreachablePub: UnreachablePub,
-                ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
-                InvalidValue: InvalidValue,
-                DerefNullPtr: DerefNullPtr,
-                // May Depend on constants elsewhere
-                UnusedBrokenConst: UnusedBrokenConst,
-                UnstableFeatures: UnstableFeatures,
-                ArrayIntoIter: ArrayIntoIter::default(),
-                DropTraitConstraints: DropTraitConstraints,
-                TemporaryCStringAsPtr: TemporaryCStringAsPtr,
-                NonPanicFmt: NonPanicFmt,
-                NoopMethodCall: NoopMethodCall,
-                EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums,
-                InvalidAtomicOrdering: InvalidAtomicOrdering,
-                NamedAsmLabels: NamedAsmLabels,
-                OpaqueHiddenInferredBound: OpaqueHiddenInferredBound,
-            ]
-        );
-    };
-}
-
-macro_rules! declare_combined_late_pass {
-    ([$v:vis $name:ident], $passes:tt) => (
-        late_lint_methods!(declare_combined_late_lint_pass, [$v $name, $passes], ['tcx]);
-    )
-}
+early_lint_methods!(
+    declare_combined_early_lint_pass,
+    [
+        pub BuiltinCombinedPreExpansionLintPass,
+        [
+            KeywordIdents: KeywordIdents,
+        ]
+    ]
+);
+
+early_lint_methods!(
+    declare_combined_early_lint_pass,
+    [
+        pub BuiltinCombinedEarlyLintPass,
+        [
+            UnusedParens: UnusedParens,
+            UnusedBraces: UnusedBraces,
+            UnusedImportBraces: UnusedImportBraces,
+            UnsafeCode: UnsafeCode,
+            SpecialModuleName: SpecialModuleName,
+            AnonymousParameters: AnonymousParameters,
+            EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
+            NonCamelCaseTypes: NonCamelCaseTypes,
+            DeprecatedAttr: DeprecatedAttr::new(),
+            WhileTrue: WhileTrue,
+            NonAsciiIdents: NonAsciiIdents,
+            HiddenUnicodeCodepoints: HiddenUnicodeCodepoints,
+            IncompleteFeatures: IncompleteFeatures,
+            RedundantSemicolons: RedundantSemicolons,
+            UnusedDocComment: UnusedDocComment,
+            UnexpectedCfgs: UnexpectedCfgs,
+        ]
+    ]
+);
 
 // FIXME: Make a separate lint type which do not require typeck tables
-late_lint_passes!(declare_combined_late_pass, [pub BuiltinCombinedLateLintPass]);
-
-late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLintPass]);
-
-pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> LintStore {
+late_lint_methods!(
+    declare_combined_late_lint_pass,
+    [
+        pub BuiltinCombinedLateLintPass,
+        [
+            // Tracks state across modules
+            UnnameableTestItems: UnnameableTestItems::new(),
+            // Tracks attributes of parents
+            MissingDoc: MissingDoc::new(),
+            // Builds a global list of all impls of `Debug`.
+            // FIXME: Turn the computation of types which implement Debug into a query
+            // and change this to a module lint pass
+            MissingDebugImplementations: MissingDebugImplementations::default(),
+            // Keeps a global list of foreign declarations.
+            ClashingExternDeclarations: ClashingExternDeclarations::new(),
+        ]
+    ],
+    ['tcx]
+);
+
+late_lint_methods!(
+    declare_combined_late_lint_pass,
+    [
+        BuiltinCombinedModuleLateLintPass,
+        [
+            ForLoopsOverFallibles: ForLoopsOverFallibles,
+            DerefIntoDynSupertrait: DerefIntoDynSupertrait,
+            HardwiredLints: HardwiredLints,
+            ImproperCTypesDeclarations: ImproperCTypesDeclarations,
+            ImproperCTypesDefinitions: ImproperCTypesDefinitions,
+            VariantSizeDifferences: VariantSizeDifferences,
+            BoxPointers: BoxPointers,
+            PathStatements: PathStatements,
+            LetUnderscore: LetUnderscore,
+            // Depends on referenced function signatures in expressions
+            UnusedResults: UnusedResults,
+            NonUpperCaseGlobals: NonUpperCaseGlobals,
+            NonShorthandFieldPatterns: NonShorthandFieldPatterns,
+            UnusedAllocation: UnusedAllocation,
+            // Depends on types used in type definitions
+            MissingCopyImplementations: MissingCopyImplementations,
+            // Depends on referenced function signatures in expressions
+            MutableTransmutes: MutableTransmutes,
+            TypeAliasBounds: TypeAliasBounds,
+            TrivialConstraints: TrivialConstraints,
+            TypeLimits: TypeLimits::new(),
+            NonSnakeCase: NonSnakeCase,
+            InvalidNoMangleItems: InvalidNoMangleItems,
+            // Depends on effective visibilities
+            UnreachablePub: UnreachablePub,
+            ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
+            InvalidValue: InvalidValue,
+            DerefNullPtr: DerefNullPtr,
+            // May Depend on constants elsewhere
+            UnusedBrokenConst: UnusedBrokenConst,
+            UnstableFeatures: UnstableFeatures,
+            ArrayIntoIter: ArrayIntoIter::default(),
+            DropTraitConstraints: DropTraitConstraints,
+            TemporaryCStringAsPtr: TemporaryCStringAsPtr,
+            NonPanicFmt: NonPanicFmt,
+            NoopMethodCall: NoopMethodCall,
+            EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums,
+            InvalidAtomicOrdering: InvalidAtomicOrdering,
+            NamedAsmLabels: NamedAsmLabels,
+            OpaqueHiddenInferredBound: OpaqueHiddenInferredBound,
+        ]
+    ],
+    ['tcx]
+);
+
+pub fn new_lint_store(internal_lints: bool) -> LintStore {
     let mut lint_store = LintStore::new();
 
-    register_builtins(&mut lint_store, no_interleave_lints);
+    register_builtins(&mut lint_store);
     if internal_lints {
         register_internals(&mut lint_store);
     }
@@ -263,54 +247,17 @@ pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> LintSt
 /// Tell the `LintStore` about all the built-in lints (the ones
 /// defined in this crate and the ones defined in
 /// `rustc_session::lint::builtin`).
-fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
+fn register_builtins(store: &mut LintStore) {
     macro_rules! add_lint_group {
         ($name:expr, $($lint:ident),*) => (
             store.register_group(false, $name, None, vec![$(LintId::of($lint)),*]);
         )
     }
 
-    macro_rules! register_early_pass {
-        ($method:ident, $ty:ident, $constructor:expr) => {
-            store.register_lints(&$ty::get_lints());
-            store.$method(|| Box::new($constructor));
-        };
-    }
-
-    macro_rules! register_late_pass {
-        ($method:ident, $ty:ident, $constructor:expr) => {
-            store.register_lints(&$ty::get_lints());
-            store.$method(|_| Box::new($constructor));
-        };
-    }
-
-    macro_rules! register_early_passes {
-        ($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
-            $(
-                register_early_pass!($method, $passes, $constructor);
-            )*
-        )
-    }
-
-    macro_rules! register_late_passes {
-        ($method:ident, [$($passes:ident: $constructor:expr,)*]) => (
-            $(
-                register_late_pass!($method, $passes, $constructor);
-            )*
-        )
-    }
-
-    if no_interleave_lints {
-        pre_expansion_lint_passes!(register_early_passes, register_pre_expansion_pass);
-        early_lint_passes!(register_early_passes, register_early_pass);
-        late_lint_passes!(register_late_passes, register_late_pass);
-        late_lint_mod_passes!(register_late_passes, register_late_mod_pass);
-    } else {
-        store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints());
-        store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints());
-        store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints());
-        store.register_lints(&BuiltinCombinedLateLintPass::get_lints());
-    }
+    store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints());
+    store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints());
+    store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints());
+    store.register_lints(&BuiltinCombinedLateLintPass::get_lints());
 
     add_lint_group!(
         "nonstandard_style",
diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs
index fc11d092ccb..2f53986139e 100644
--- a/compiler/rustc_lint/src/passes.rs
+++ b/compiler/rustc_lint/src/passes.rs
@@ -1,7 +1,6 @@
 use crate::context::{EarlyContext, LateContext};
 
 use rustc_ast as ast;
-use rustc_data_structures::sync;
 use rustc_hir as hir;
 use rustc_session::lint::builtin::HardwiredLints;
 use rustc_session::lint::LintPass;
@@ -66,16 +65,10 @@ macro_rules! late_lint_methods {
 // FIXME: eliminate the duplication with `Visitor`. But this also
 // contains a few lint-specific methods with no equivalent in `Visitor`.
 
-macro_rules! expand_lint_pass_methods {
-    ($context:ty, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
-        $(#[inline(always)] fn $name(&mut self, _: $context, $(_: $arg),*) {})*
-    )
-}
-
 macro_rules! declare_late_lint_pass {
-    ([], [$hir:tt], [$($methods:tt)*]) => (
+    ([], [$hir:tt], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
         pub trait LateLintPass<$hir>: LintPass {
-            expand_lint_pass_methods!(&LateContext<$hir>, [$($methods)*]);
+            $(#[inline(always)] fn $name(&mut self, _: &LateContext<$hir>, $(_: $arg),*) {})*
         }
     )
 }
@@ -175,16 +168,10 @@ macro_rules! early_lint_methods {
     )
 }
 
-macro_rules! expand_early_lint_pass_methods {
-    ($context:ty, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
-        $(#[inline(always)] fn $name(&mut self, _: $context, $(_: $arg),*) {})*
-    )
-}
-
 macro_rules! declare_early_lint_pass {
-    ([], [$($methods:tt)*]) => (
+    ([], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
         pub trait EarlyLintPass: LintPass {
-            expand_early_lint_pass_methods!(&EarlyContext<'_>, [$($methods)*]);
+            $(#[inline(always)] fn $name(&mut self, _: &EarlyContext<'_>, $(_: $arg),*) {})*
         }
     )
 }
@@ -243,5 +230,5 @@ macro_rules! declare_combined_early_lint_pass {
 }
 
 /// A lint pass boxed up as a trait object.
-pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + 'static>;
-pub type LateLintPassObject<'tcx> = Box<dyn LateLintPass<'tcx> + sync::Send + 'tcx>;
+pub type EarlyLintPassObject = Box<dyn EarlyLintPass + 'static>;
+pub type LateLintPassObject<'tcx> = Box<dyn LateLintPass<'tcx> + 'tcx>;
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index d35e4191cc0..79f06ac146c 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -222,6 +222,7 @@ fn main() {
         .file("llvm-wrapper/RustWrapper.cpp")
         .file("llvm-wrapper/ArchiveWrapper.cpp")
         .file("llvm-wrapper/CoverageMappingWrapper.cpp")
+        .file("llvm-wrapper/SymbolWrapper.cpp")
         .file("llvm-wrapper/Linker.cpp")
         .cpp(true)
         .cpp_link_stdlib(None) // we handle this below
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 216c35d6da0..792d921c6a4 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1967,3 +1967,7 @@ extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) {
 #endif
     return -1;
 }
+
+extern "C" bool LLVMRustIsBitcode(char *ptr, size_t len) {
+  return identify_magic(StringRef(ptr, len)) == file_magic::bitcode;
+}
diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
new file mode 100644
index 00000000000..974207e918c
--- /dev/null
+++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
@@ -0,0 +1,96 @@
+// Derived from code in LLVM, which is:
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// 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
+
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/ADT/Optional.h"
+
+using namespace llvm;
+using namespace llvm::sys;
+using namespace llvm::object;
+
+static bool isArchiveSymbol(const object::BasicSymbolRef &S) {
+  Expected<uint32_t> SymFlagsOrErr = S.getFlags();
+  if (!SymFlagsOrErr)
+    // FIXME: Actually report errors helpfully.
+    report_fatal_error(SymFlagsOrErr.takeError());
+  if (*SymFlagsOrErr & object::SymbolRef::SF_FormatSpecific)
+    return false;
+  if (!(*SymFlagsOrErr & object::SymbolRef::SF_Global))
+    return false;
+  if (*SymFlagsOrErr & object::SymbolRef::SF_Undefined)
+    return false;
+  return true;
+}
+
+typedef void *(*LLVMRustGetSymbolsCallback)(void *, const char *);
+typedef void *(*LLVMRustGetSymbolsErrorCallback)(const char *);
+
+// 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.
+extern "C" void *LLVMRustGetSymbols(
+  char *BufPtr, size_t BufLen, void *State, LLVMRustGetSymbolsCallback Callback,
+  LLVMRustGetSymbolsErrorCallback ErrorCallback) {
+  std::unique_ptr<MemoryBuffer> Buf =
+    MemoryBuffer::getMemBuffer(StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"),
+                               false);
+  SmallString<0> SymNameBuf;
+  raw_svector_ostream SymName(SymNameBuf);
+
+  // 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;
+      raw_svector_ostream Error(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;
+      raw_svector_ostream Error(ErrorBuf);
+      Error << E << '\0';
+      return ErrorCallback(Error.str().data());
+    }
+    Obj = std::move(*ObjOrErr);
+  }
+
+
+  for (const object::BasicSymbolRef &S : Obj->symbols()) {
+    if (!isArchiveSymbol(S))
+      continue;
+    if (Error E = S.printName(SymName)) {
+      SmallString<0> ErrorBuf;
+      raw_svector_ostream Error(ErrorBuf);
+      Error << E << '\0';
+      return ErrorCallback(Error.str().data());
+    }
+    SymName << '\0';
+    if (void *E = Callback(State, SymNameBuf.str().data())) {
+      return E;
+    }
+    SymNameBuf.clear();
+  }
+  return 0;
+}
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
index be9821c00f5..684835d8c5c 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
@@ -29,8 +29,8 @@ impl<'a> DiagnosticDerive<'a> {
         let DiagnosticDerive { mut structure, mut builder } = self;
 
         let implementation = builder.each_variant(&mut structure, |mut builder, variant| {
-            let preamble = builder.preamble(&variant);
-            let body = builder.body(&variant);
+            let preamble = builder.preamble(variant);
+            let body = builder.body(variant);
 
             let diag = &builder.parent.diag;
             let DiagnosticDeriveKind::Diagnostic { handler } = &builder.parent.kind else {
@@ -39,7 +39,7 @@ impl<'a> DiagnosticDerive<'a> {
             let init = match builder.slug.value_ref() {
                 None => {
                     span_err(builder.span, "diagnostic slug not specified")
-                        .help(&format!(
+                        .help(format!(
                             "specify the slug as the first argument to the `#[diag(...)]` \
                             attribute, such as `#[diag(hir_analysis_example_error)]`",
                         ))
@@ -48,10 +48,10 @@ impl<'a> DiagnosticDerive<'a> {
                 }
                 Some(slug) if let Some( Mismatch { slug_name, crate_name, slug_prefix }) = Mismatch::check(slug) => {
                     span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match")
-                        .note(&format!(
+                        .note(format!(
                             "slug is `{slug_name}` but the crate name is `{crate_name}`"
                         ))
-                        .help(&format!(
+                        .help(format!(
                             "expected a slug starting with `{slug_prefix}_...`"
                         ))
                         .emit();
@@ -113,8 +113,8 @@ impl<'a> LintDiagnosticDerive<'a> {
         let LintDiagnosticDerive { mut structure, mut builder } = self;
 
         let implementation = builder.each_variant(&mut structure, |mut builder, variant| {
-            let preamble = builder.preamble(&variant);
-            let body = builder.body(&variant);
+            let preamble = builder.preamble(variant);
+            let body = builder.body(variant);
 
             let diag = &builder.parent.diag;
             let formatting_init = &builder.formatting_init;
@@ -128,28 +128,28 @@ impl<'a> LintDiagnosticDerive<'a> {
 
         let msg = builder.each_variant(&mut structure, |mut builder, variant| {
             // Collect the slug by generating the preamble.
-            let _ = builder.preamble(&variant);
+            let _ = builder.preamble(variant);
 
             match builder.slug.value_ref() {
                 None => {
                     span_err(builder.span, "diagnostic slug not specified")
-                        .help(&format!(
+                        .help(format!(
                             "specify the slug as the first argument to the attribute, such as \
                             `#[diag(compiletest_example)]`",
                         ))
                         .emit();
-                    return DiagnosticDeriveError::ErrorHandled.to_compile_error();
+                    DiagnosticDeriveError::ErrorHandled.to_compile_error()
                 }
                 Some(slug) if let Some( Mismatch { slug_name, crate_name, slug_prefix }) = Mismatch::check(slug) => {
                     span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match")
-                        .note(&format!(
+                        .note(format!(
                             "slug is `{slug_name}` but the crate name is `{crate_name}`"
                         ))
-                        .help(&format!(
+                        .help(format!(
                             "expected a slug starting with `{slug_prefix}_...`"
                         ))
                         .emit();
-                    return DiagnosticDeriveError::ErrorHandled.to_compile_error();
+                    DiagnosticDeriveError::ErrorHandled.to_compile_error()
                 }
                 Some(slug) => {
                     quote! {
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
index 3ea83fd09c7..9f2ac5112f1 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
@@ -100,7 +100,7 @@ impl DiagnosticDeriveBuilder {
                 _ => variant.ast().ident.span().unwrap(),
             };
             let builder = DiagnosticDeriveVariantBuilder {
-                parent: &self,
+                parent: self,
                 span,
                 field_map: build_field_mapping(variant),
                 formatting_init: TokenStream::new(),
@@ -211,7 +211,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
                     nested_iter.next();
                 }
                 Some(NestedMeta::Meta(Meta::NameValue { .. })) => {}
-                Some(nested_attr) => throw_invalid_nested_attr!(attr, &nested_attr, |diag| diag
+                Some(nested_attr) => throw_invalid_nested_attr!(attr, nested_attr, |diag| diag
                     .help("a diagnostic slug is required as the first argument")),
                 None => throw_invalid_attr!(attr, &meta, |diag| diag
                     .help("a diagnostic slug is required as the first argument")),
@@ -227,13 +227,13 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
                         ..
                     })) => (value, path),
                     NestedMeta::Meta(Meta::Path(_)) => {
-                        invalid_nested_attr(attr, &nested_attr)
+                        invalid_nested_attr(attr, nested_attr)
                             .help("diagnostic slug must be the first argument")
                             .emit();
                         continue;
                     }
                     _ => {
-                        invalid_nested_attr(attr, &nested_attr).emit();
+                        invalid_nested_attr(attr, nested_attr).emit();
                         continue;
                     }
                 };
@@ -251,7 +251,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
                             #diag.code(rustc_errors::DiagnosticId::Error(#code.to_string()));
                         });
                     }
-                    _ => invalid_nested_attr(attr, &nested_attr)
+                    _ => invalid_nested_attr(attr, nested_attr)
                         .help("only `code` is a valid nested attributes following the slug")
                         .emit(),
                 }
@@ -427,9 +427,9 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
                 Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, slug))
             }
             SubdiagnosticKind::Note | SubdiagnosticKind::Help | SubdiagnosticKind::Warn => {
-                if type_matches_path(&info.ty, &["rustc_span", "Span"]) {
+                if type_matches_path(info.ty, &["rustc_span", "Span"]) {
                     Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, slug))
-                } else if type_is_unit(&info.ty) {
+                } else if type_is_unit(info.ty) {
                     Ok(self.add_subdiagnostic(&fn_ident, slug))
                 } else {
                     report_type_error(attr, "`Span` or `()`")?
diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
index fa0ca5a5242..446aebe4f83 100644
--- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
@@ -409,7 +409,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
                 let mut code = None;
                 for nested_attr in list.nested.iter() {
                     let NestedMeta::Meta(ref meta) = nested_attr else {
-                        throw_invalid_nested_attr!(attr, &nested_attr);
+                        throw_invalid_nested_attr!(attr, nested_attr);
                     };
 
                     let span = meta.span().unwrap();
@@ -427,7 +427,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
                             );
                             code.set_once((code_field, formatting_init), span);
                         }
-                        _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
+                        _ => throw_invalid_nested_attr!(attr, nested_attr, |diag| {
                             diag.help("`code` is the only valid nested attribute")
                         }),
                     }
diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs
index dff088b9bdf..da90233523c 100644
--- a/compiler/rustc_macros/src/diagnostics/utils.rs
+++ b/compiler/rustc_macros/src/diagnostics/utils.rs
@@ -80,7 +80,7 @@ fn report_error_if_not_applied_to_ty(
     path: &[&str],
     ty_name: &str,
 ) -> Result<(), DiagnosticDeriveError> {
-    if !type_matches_path(&info.ty, path) {
+    if !type_matches_path(info.ty, path) {
         report_type_error(attr, ty_name)?;
     }
 
@@ -105,8 +105,8 @@ pub(crate) fn report_error_if_not_applied_to_span(
     attr: &Attribute,
     info: &FieldInfo<'_>,
 ) -> Result<(), DiagnosticDeriveError> {
-    if !type_matches_path(&info.ty, &["rustc_span", "Span"])
-        && !type_matches_path(&info.ty, &["rustc_errors", "MultiSpan"])
+    if !type_matches_path(info.ty, &["rustc_span", "Span"])
+        && !type_matches_path(info.ty, &["rustc_errors", "MultiSpan"])
     {
         report_type_error(attr, "`Span` or `MultiSpan`")?;
     }
@@ -686,7 +686,7 @@ impl SubdiagnosticKind {
             let meta = match nested_attr {
                 NestedMeta::Meta(ref meta) => meta,
                 NestedMeta::Lit(_) => {
-                    invalid_nested_attr(attr, &nested_attr).emit();
+                    invalid_nested_attr(attr, nested_attr).emit();
                     continue;
                 }
             };
@@ -698,7 +698,7 @@ impl SubdiagnosticKind {
             let string_value = match meta {
                 Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(value), .. }) => Some(value),
 
-                Meta::Path(_) => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
+                Meta::Path(_) => throw_invalid_nested_attr!(attr, nested_attr, |diag| {
                     diag.help("a diagnostic slug must be the first argument to the attribute")
                 }),
                 _ => None,
@@ -720,7 +720,7 @@ impl SubdiagnosticKind {
                     | SubdiagnosticKind::MultipartSuggestion { ref mut applicability, .. },
                 ) => {
                     let Some(value) = string_value else {
-                        invalid_nested_attr(attr, &nested_attr).emit();
+                        invalid_nested_attr(attr, nested_attr).emit();
                         continue;
                     };
 
@@ -736,7 +736,7 @@ impl SubdiagnosticKind {
                     | SubdiagnosticKind::MultipartSuggestion { .. },
                 ) => {
                     let Some(value) = string_value else {
-                        invalid_nested_attr(attr, &nested_attr).emit();
+                        invalid_nested_attr(attr, nested_attr).emit();
                         continue;
                     };
 
@@ -752,19 +752,19 @@ impl SubdiagnosticKind {
 
                 // Invalid nested attribute
                 (_, SubdiagnosticKind::Suggestion { .. }) => {
-                    invalid_nested_attr(attr, &nested_attr)
+                    invalid_nested_attr(attr, nested_attr)
                         .help(
                             "only `style`, `code` and `applicability` are valid nested attributes",
                         )
                         .emit();
                 }
                 (_, SubdiagnosticKind::MultipartSuggestion { .. }) => {
-                    invalid_nested_attr(attr, &nested_attr)
+                    invalid_nested_attr(attr, nested_attr)
                         .help("only `style` and `applicability` are valid nested attributes")
                         .emit()
                 }
                 _ => {
-                    invalid_nested_attr(attr, &nested_attr).emit();
+                    invalid_nested_attr(attr, nested_attr).emit();
                 }
             }
         }
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 4617c17b153..1bd8f953508 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -1022,7 +1022,7 @@ impl<'hir> Map<'hir> {
                 ..
             }) => {
                 // Ensure that the returned span has the item's SyntaxContext.
-                fn_decl_span.find_ancestor_in_same_ctxt(*span).unwrap_or(*span)
+                fn_decl_span.find_ancestor_inside(*span).unwrap_or(*span)
             }
             _ => self.span_with_body(hir_id),
         };
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 20dde64e51b..a513444e1e0 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -100,13 +100,9 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
 /// pass will be named after the type, and it will consist of a main
 /// loop that goes over each available MIR and applies `run_pass`.
 pub trait MirPass<'tcx> {
-    fn name(&self) -> Cow<'_, str> {
+    fn name(&self) -> &str {
         let name = std::any::type_name::<Self>();
-        if let Some(tail) = name.rfind(':') {
-            Cow::from(&name[tail + 1..])
-        } else {
-            Cow::from(name)
-        }
+        if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }
     }
 
     /// Returns `true` if this pass is enabled with the current combination of compiler flags.
@@ -182,35 +178,6 @@ impl RuntimePhase {
     }
 }
 
-impl Display for MirPhase {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        match self {
-            MirPhase::Built => write!(f, "built"),
-            MirPhase::Analysis(p) => write!(f, "analysis-{}", p),
-            MirPhase::Runtime(p) => write!(f, "runtime-{}", p),
-        }
-    }
-}
-
-impl Display for AnalysisPhase {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        match self {
-            AnalysisPhase::Initial => write!(f, "initial"),
-            AnalysisPhase::PostCleanup => write!(f, "post_cleanup"),
-        }
-    }
-}
-
-impl Display for RuntimePhase {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        match self {
-            RuntimePhase::Initial => write!(f, "initial"),
-            RuntimePhase::PostCleanup => write!(f, "post_cleanup"),
-            RuntimePhase::Optimized => write!(f, "optimized"),
-        }
-    }
-}
-
 /// Where a specific `mir::Body` comes from.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 #[derive(HashStable, TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)]
@@ -368,7 +335,7 @@ impl<'tcx> Body<'tcx> {
 
         let mut body = Body {
             phase: MirPhase::Built,
-            pass_count: 1,
+            pass_count: 0,
             source,
             basic_blocks: BasicBlocks::new(basic_blocks),
             source_scopes,
@@ -403,7 +370,7 @@ impl<'tcx> Body<'tcx> {
     pub fn new_cfg_only(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self {
         let mut body = Body {
             phase: MirPhase::Built,
-            pass_count: 1,
+            pass_count: 0,
             source: MirSource::item(CRATE_DEF_ID.to_def_id()),
             basic_blocks: BasicBlocks::new(basic_blocks),
             source_scopes: IndexVec::new(),
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 1cac656674d..2a4ff4b8810 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -16,7 +16,6 @@ use rustc_middle::mir::interpret::{
     Pointer, Provenance,
 };
 use rustc_middle::mir::visit::Visitor;
-use rustc_middle::mir::MirSource;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_target::abi::Size;
@@ -74,7 +73,7 @@ pub enum PassWhere {
 #[inline]
 pub fn dump_mir<'tcx, F>(
     tcx: TyCtxt<'tcx>,
-    pass_num: Option<&dyn Display>,
+    pass_num: bool,
     pass_name: &str,
     disambiguator: &dyn Display,
     body: &Body<'tcx>,
@@ -111,7 +110,7 @@ pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, def_id: DefId) ->
 
 fn dump_matched_mir_node<'tcx, F>(
     tcx: TyCtxt<'tcx>,
-    pass_num: Option<&dyn Display>,
+    pass_num: bool,
     pass_name: &str,
     disambiguator: &dyn Display,
     body: &Body<'tcx>,
@@ -120,8 +119,7 @@ fn dump_matched_mir_node<'tcx, F>(
     F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
 {
     let _: io::Result<()> = try {
-        let mut file =
-            create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, body.source)?;
+        let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, body)?;
         // see notes on #41697 above
         let def_path =
             ty::print::with_forced_impl_filename_line!(tcx.def_path_str(body.source.def_id()));
@@ -143,16 +141,14 @@ fn dump_matched_mir_node<'tcx, F>(
 
     if tcx.sess.opts.unstable_opts.dump_mir_graphviz {
         let _: io::Result<()> = try {
-            let mut file =
-                create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, body.source)?;
+            let mut file = create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, body)?;
             write_mir_fn_graphviz(tcx, body, false, &mut file)?;
         };
     }
 
     if let Some(spanview) = tcx.sess.opts.unstable_opts.dump_mir_spanview {
         let _: io::Result<()> = try {
-            let file_basename =
-                dump_file_basename(tcx, pass_num, pass_name, disambiguator, body.source);
+            let file_basename = dump_file_basename(tcx, pass_num, pass_name, disambiguator, body);
             let mut file = create_dump_file_with_basename(tcx, &file_basename, "html")?;
             if body.source.def_id().is_local() {
                 write_mir_fn_spanview(tcx, body, spanview, &file_basename, &mut file)?;
@@ -165,11 +161,12 @@ fn dump_matched_mir_node<'tcx, F>(
 /// where we should dump a MIR representation output files.
 fn dump_file_basename<'tcx>(
     tcx: TyCtxt<'tcx>,
-    pass_num: Option<&dyn Display>,
+    pass_num: bool,
     pass_name: &str,
     disambiguator: &dyn Display,
-    source: MirSource<'tcx>,
+    body: &Body<'tcx>,
 ) -> String {
+    let source = body.source;
     let promotion_id = match source.promoted {
         Some(id) => format!("-{:?}", id),
         None => String::new(),
@@ -178,9 +175,10 @@ fn dump_file_basename<'tcx>(
     let pass_num = if tcx.sess.opts.unstable_opts.dump_mir_exclude_pass_number {
         String::new()
     } else {
-        match pass_num {
-            None => ".-------".to_string(),
-            Some(pass_num) => format!(".{}", pass_num),
+        if pass_num {
+            format!(".{:03}-{:03}", body.phase.phase_index(), body.pass_count)
+        } else {
+            ".-------".to_string()
         }
     };
 
@@ -250,14 +248,14 @@ fn create_dump_file_with_basename(
 pub fn create_dump_file<'tcx>(
     tcx: TyCtxt<'tcx>,
     extension: &str,
-    pass_num: Option<&dyn Display>,
+    pass_num: bool,
     pass_name: &str,
     disambiguator: &dyn Display,
-    source: MirSource<'tcx>,
+    body: &Body<'tcx>,
 ) -> io::Result<io::BufWriter<fs::File>> {
     create_dump_file_with_basename(
         tcx,
-        &dump_file_basename(tcx, pass_num, pass_name, disambiguator, source),
+        &dump_file_basename(tcx, pass_num, pass_name, disambiguator, body),
         extension,
     )
 }
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index f2030b91b9b..7d2a6bda569 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -89,6 +89,19 @@ pub enum MirPhase {
     Runtime(RuntimePhase),
 }
 
+impl MirPhase {
+    pub fn name(&self) -> &'static str {
+        match *self {
+            MirPhase::Built => "built",
+            MirPhase::Analysis(AnalysisPhase::Initial) => "analysis",
+            MirPhase::Analysis(AnalysisPhase::PostCleanup) => "analysis-post-cleanup",
+            MirPhase::Runtime(RuntimePhase::Initial) => "runtime",
+            MirPhase::Runtime(RuntimePhase::PostCleanup) => "runtime-post-cleanup",
+            MirPhase::Runtime(RuntimePhase::Optimized) => "runtime-optimized",
+        }
+    }
+}
+
 /// See [`MirPhase::Analysis`].
 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
 #[derive(HashStable)]
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index e1220320eea..d6dea0e9f30 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1109,6 +1109,7 @@ rustc_queries! {
         desc { |tcx| "looking up span for `{}`", tcx.def_path_str(def_id) }
         cache_on_disk_if { def_id.is_local() }
         separate_provide_extern
+        feedable
     }
 
     /// Gets the span for the identifier of the definition.
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index a9a7a2c8b01..c5683a9db94 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1507,7 +1507,9 @@ impl<'tcx> TyCtxt<'tcx> {
             self.def_path(def_id).to_string_no_crate_verbose()
         )
     }
+}
 
+impl<'tcx> TyCtxtAt<'tcx> {
     /// Create a new definition within the incr. comp. engine.
     pub fn create_def(
         self,
@@ -1536,9 +1538,13 @@ impl<'tcx> TyCtxt<'tcx> {
         // - this write will have happened before these queries are called.
         let def_id = self.definitions.write().create_def(parent, data);
 
-        TyCtxtFeed { tcx: self, def_id }
+        let feed = TyCtxtFeed { tcx: self.tcx, def_id };
+        feed.def_span(self.span);
+        feed
     }
+}
 
+impl<'tcx> TyCtxt<'tcx> {
     pub fn iter_local_def_id(self) -> impl Iterator<Item = LocalDefId> + 'tcx {
         // Create a dependency to the red node to be sure we re-execute this when the amount of
         // definitions change.
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 47c1379b308..a7fd1754960 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -344,12 +344,10 @@ macro_rules! define_feedable {
 
                 match cached {
                     Ok(old) => {
-                        assert_eq!(
-                            value, old,
-                            "Trying to feed an already recorded value for query {} key={key:?}",
+                        bug!(
+                            "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}",
                             stringify!($name),
                         );
-                        return old;
                     }
                     Err(()) => (),
                 }
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index f4562cdfb88..70b98e59a8b 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -32,13 +32,23 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::SymbolName<'_> {
 }
 
 impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
-    fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &[QueryInfo]) -> Self {
+    fn from_cycle_error(tcx: TyCtxt<'tcx>, stack: &[QueryInfo]) -> Self {
         let err = tcx.ty_error();
-        // FIXME(compiler-errors): It would be nice if we could get the
-        // query key, so we could at least generate a fn signature that
-        // has the right arity.
+
+        let arity = if let Some(frame) = stack.get(0)
+            && frame.query.name == "fn_sig"
+            && let Some(def_id) = frame.query.def_id
+            && let Some(node) = tcx.hir().get_if_local(def_id)
+            && let Some(sig) = node.fn_sig()
+        {
+            sig.decl.inputs.len() + sig.decl.implicit_self.has_implicit_self() as usize
+        } else {
+            tcx.sess.abort_if_errors();
+            unreachable!()
+        };
+
         let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig(
-            [].into_iter(),
+            std::iter::repeat(err).take(arity),
             err,
             false,
             rustc_hir::Unsafety::Normal,
diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs
index 2412824efeb..eb021f47757 100644
--- a/compiler/rustc_mir_build/src/build/custom/mod.rs
+++ b/compiler/rustc_mir_build/src/build/custom/mod.rs
@@ -57,7 +57,7 @@ pub(super) fn build_custom_mir<'tcx>(
         is_polymorphic: false,
         tainted_by_errors: None,
         injection_phase: None,
-        pass_count: 1,
+        pass_count: 0,
     };
 
     body.local_decls.push(LocalDecl::new(return_ty, return_ty_span));
diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs
index bc75645e7c9..6ddbe69e17e 100644
--- a/compiler/rustc_mir_dataflow/src/framework/engine.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs
@@ -294,14 +294,7 @@ where
         None if tcx.sess.opts.unstable_opts.dump_mir_dataflow
             && dump_enabled(tcx, A::NAME, def_id) =>
         {
-            create_dump_file(
-                tcx,
-                ".dot",
-                None,
-                A::NAME,
-                &pass_name.unwrap_or("-----"),
-                body.source,
-            )?
+            create_dump_file(tcx, ".dot", false, A::NAME, &pass_name.unwrap_or("-----"), body)?
         }
 
         _ => return Ok(()),
diff --git a/compiler/rustc_mir_transform/src/coverage/debug.rs b/compiler/rustc_mir_transform/src/coverage/debug.rs
index 0f8679b0bd6..d6a298fade4 100644
--- a/compiler/rustc_mir_transform/src/coverage/debug.rs
+++ b/compiler/rustc_mir_transform/src/coverage/debug.rs
@@ -638,7 +638,7 @@ pub(super) fn dump_coverage_spanview<'tcx>(
     let def_id = mir_source.def_id();
 
     let span_viewables = span_viewables(tcx, mir_body, basic_coverage_blocks, &coverage_spans);
-    let mut file = create_dump_file(tcx, "html", None, pass_name, &0, mir_source)
+    let mut file = create_dump_file(tcx, "html", false, pass_name, &0, mir_body)
         .expect("Unexpected error creating MIR spanview HTML file");
     let crate_name = tcx.crate_name(def_id.krate);
     let item_name = tcx.def_path(def_id).to_filename_friendly_no_crate();
@@ -739,7 +739,7 @@ pub(super) fn dump_coverage_graphviz<'tcx>(
                 .join("\n  ")
         ));
     }
-    let mut file = create_dump_file(tcx, "dot", None, pass_name, &0, mir_source)
+    let mut file = create_dump_file(tcx, "dot", false, pass_name, &0, mir_body)
         .expect("Unexpected error creating BasicCoverageBlock graphviz DOT file");
     graphviz_writer
         .write_graphviz(tcx, &mut file)
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 8cd44ab82cc..97485c4f57b 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -787,7 +787,7 @@ fn dest_prop_mir_dump<'body, 'tcx>(
     round: usize,
 ) {
     let mut reachable = None;
-    dump_mir(tcx, None, "DestinationPropagation-dataflow", &round, body, |pass_where, w| {
+    dump_mir(tcx, false, "DestinationPropagation-dataflow", &round, body, |pass_where, w| {
         let reachable = reachable.get_or_insert_with(|| traversal::reachable_as_bitset(body));
 
         match pass_where {
diff --git a/compiler/rustc_mir_transform/src/dump_mir.rs b/compiler/rustc_mir_transform/src/dump_mir.rs
index 6b995141a2b..778ae63c5a4 100644
--- a/compiler/rustc_mir_transform/src/dump_mir.rs
+++ b/compiler/rustc_mir_transform/src/dump_mir.rs
@@ -1,6 +1,5 @@
 //! This pass just dumps MIR at a specified point.
 
-use std::borrow::Cow;
 use std::fs::File;
 use std::io;
 
@@ -13,8 +12,8 @@ use rustc_session::config::{OutputFilenames, OutputType};
 pub struct Marker(pub &'static str);
 
 impl<'tcx> MirPass<'tcx> for Marker {
-    fn name(&self) -> Cow<'_, str> {
-        Cow::Borrowed(self.0)
+    fn name(&self) -> &str {
+        self.0
     }
 
     fn run_pass(&self, _tcx: TyCtxt<'tcx>, _body: &mut Body<'tcx>) {}
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index ffe4d43bc88..8922298ecaf 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -1000,7 +1000,7 @@ fn create_generator_drop_shim<'tcx>(
     // unrelated code from the resume part of the function
     simplify::remove_dead_blocks(tcx, &mut body);
 
-    dump_mir(tcx, None, "generator_drop", &0, &body, |_, _| Ok(()));
+    dump_mir(tcx, false, "generator_drop", &0, &body, |_, _| Ok(()));
 
     body
 }
@@ -1171,7 +1171,7 @@ fn create_generator_resume_function<'tcx>(
     // unrelated code from the drop part of the function
     simplify::remove_dead_blocks(tcx, body);
 
-    dump_mir(tcx, None, "generator_resume", &0, body, |_, _| Ok(()));
+    dump_mir(tcx, false, "generator_resume", &0, body, |_, _| Ok(()));
 }
 
 fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock {
@@ -1394,14 +1394,14 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
         // This is expanded to a drop ladder in `elaborate_generator_drops`.
         let drop_clean = insert_clean_drop(body);
 
-        dump_mir(tcx, None, "generator_pre-elab", &0, body, |_, _| Ok(()));
+        dump_mir(tcx, false, "generator_pre-elab", &0, body, |_, _| Ok(()));
 
         // Expand `drop(generator_struct)` to a drop ladder which destroys upvars.
         // If any upvars are moved out of, drop elaboration will handle upvar destruction.
         // However we need to also elaborate the code generated by `insert_clean_drop`.
         elaborate_generator_drops(tcx, body);
 
-        dump_mir(tcx, None, "generator_post-transform", &0, body, |_, _| Ok(()));
+        dump_mir(tcx, false, "generator_post-transform", &0, body, |_, _| Ok(()));
 
         // Create a copy of our MIR and use it to create the drop shim for the generator
         let drop_shim = create_generator_drop_shim(tcx, &transform, gen_ty, body, drop_clean);
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 9174f04887e..bf670c5c26a 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -363,10 +363,6 @@ impl<'tcx> Inliner<'tcx> {
             return Err("C variadic");
         }
 
-        if callee_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
-            return Err("naked");
-        }
-
         if callee_attrs.flags.contains(CodegenFnAttrFlags::COLD) {
             return Err("cold");
         }
diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs
index 27dbc3e22c9..e1b65823a5a 100644
--- a/compiler/rustc_mir_transform/src/pass_manager.rs
+++ b/compiler/rustc_mir_transform/src/pass_manager.rs
@@ -1,5 +1,3 @@
-use std::borrow::Cow;
-
 use rustc_middle::mir::{self, Body, MirPhase, RuntimePhase};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
@@ -8,13 +6,9 @@ use crate::{validate, MirPass};
 
 /// Just like `MirPass`, except it cannot mutate `Body`.
 pub trait MirLint<'tcx> {
-    fn name(&self) -> Cow<'_, str> {
+    fn name(&self) -> &str {
         let name = std::any::type_name::<Self>();
-        if let Some(tail) = name.rfind(':') {
-            Cow::from(&name[tail + 1..])
-        } else {
-            Cow::from(name)
-        }
+        if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }
     }
 
     fn is_enabled(&self, _sess: &Session) -> bool {
@@ -32,7 +26,7 @@ impl<'tcx, T> MirPass<'tcx> for Lint<T>
 where
     T: MirLint<'tcx>,
 {
-    fn name(&self) -> Cow<'_, str> {
+    fn name(&self) -> &str {
         self.0.name()
     }
 
@@ -55,7 +49,7 @@ impl<'tcx, T> MirPass<'tcx> for WithMinOptLevel<T>
 where
     T: MirPass<'tcx>,
 {
-    fn name(&self) -> Cow<'_, str> {
+    fn name(&self) -> &str {
         self.1.name()
     }
 
@@ -146,10 +140,11 @@ fn run_passes_inner<'tcx>(
         }
 
         body.phase = new_phase;
+        body.pass_count = 0;
 
         dump_mir_for_phase_change(tcx, body);
         if validate || new_phase == MirPhase::Runtime(RuntimePhase::Optimized) {
-            validate_body(tcx, body, format!("after phase change to {}", new_phase));
+            validate_body(tcx, body, format!("after phase change to {}", new_phase.name()));
         }
 
         body.pass_count = 1;
@@ -166,11 +161,9 @@ pub fn dump_mir_for_pass<'tcx>(
     pass_name: &str,
     is_after: bool,
 ) {
-    let phase_index = body.phase.phase_index();
-
     mir::dump_mir(
         tcx,
-        Some(&format_args!("{:03}-{:03}", phase_index, body.pass_count)),
+        true,
         pass_name,
         if is_after { &"after" } else { &"before" },
         body,
@@ -179,14 +172,6 @@ pub fn dump_mir_for_pass<'tcx>(
 }
 
 pub fn dump_mir_for_phase_change<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
-    let phase_index = body.phase.phase_index();
-
-    mir::dump_mir(
-        tcx,
-        Some(&format_args!("{:03}-000", phase_index)),
-        &format!("{}", body.phase),
-        &"after",
-        body,
-        |_, _| Ok(()),
-    )
+    assert_eq!(body.pass_count, 0);
+    mir::dump_mir(tcx, true, body.phase.name(), &"after", body, |_, _| Ok(()))
 }
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index 57d372fda56..475e2ec9a1d 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -35,7 +35,6 @@ use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Vis
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
 use smallvec::SmallVec;
-use std::borrow::Cow;
 use std::convert::TryInto;
 
 pub struct SimplifyCfg {
@@ -57,8 +56,8 @@ pub fn simplify_cfg<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
 }
 
 impl<'tcx> MirPass<'tcx> for SimplifyCfg {
-    fn name(&self) -> Cow<'_, str> {
-        Cow::Borrowed(&self.label)
+    fn name(&self) -> &str {
+        &self.label
     }
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs
index 3bbae5b8976..405ebce4d22 100644
--- a/compiler/rustc_mir_transform/src/simplify_branches.rs
+++ b/compiler/rustc_mir_transform/src/simplify_branches.rs
@@ -2,8 +2,6 @@ use crate::MirPass;
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
 
-use std::borrow::Cow;
-
 /// A pass that replaces a branch with a goto when its condition is known.
 pub struct SimplifyConstCondition {
     label: String,
@@ -16,8 +14,8 @@ impl SimplifyConstCondition {
 }
 
 impl<'tcx> MirPass<'tcx> for SimplifyConstCondition {
-    fn name(&self) -> Cow<'_, str> {
-        Cow::Borrowed(&self.label)
+    fn name(&self) -> &str {
+        &self.label
     }
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index e0443a697b5..fe3cfde2e63 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2060,7 +2060,7 @@ impl<'a> Parser<'a> {
         };
 
         let capture_clause = self.parse_capture_clause()?;
-        let fn_decl = self.parse_fn_block_decl()?;
+        let (fn_decl, fn_arg_span) = self.parse_fn_block_decl()?;
         let decl_hi = self.prev_token.span;
         let mut body = match fn_decl.output {
             FnRetTy::Default(_) => {
@@ -2101,6 +2101,7 @@ impl<'a> Parser<'a> {
                 fn_decl,
                 body,
                 fn_decl_span: lo.to(decl_hi),
+                fn_arg_span,
             })),
         );
 
@@ -2129,7 +2130,9 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses the `|arg, arg|` header of a closure.
-    fn parse_fn_block_decl(&mut self) -> PResult<'a, P<FnDecl>> {
+    fn parse_fn_block_decl(&mut self) -> PResult<'a, (P<FnDecl>, Span)> {
+        let arg_start = self.token.span.lo();
+
         let inputs = if self.eat(&token::OrOr) {
             Vec::new()
         } else {
@@ -2145,10 +2148,11 @@ impl<'a> Parser<'a> {
             self.expect_or()?;
             args
         };
+        let arg_span = self.prev_token.span.with_lo(arg_start);
         let output =
             self.parse_ret_ty(AllowPlus::Yes, RecoverQPath::Yes, RecoverReturnSign::Yes)?;
 
-        Ok(P(FnDecl { inputs, output }))
+        Ok((P(FnDecl { inputs, output }), arg_span))
     }
 
     /// Parses a parameter in a closure header (e.g., `|arg, arg|`).
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index ff1ddfd97df..42197e63797 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -72,14 +72,22 @@ impl<'a> Parser<'a> {
 
         Ok(Some(if self.token.is_keyword(kw::Let) {
             self.parse_local_mk(lo, attrs, capture_semi, force_collect)?
-        } else if self.is_kw_followed_by_ident(kw::Mut) {
-            self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::MissingLet)?
-        } else if self.is_kw_followed_by_ident(kw::Auto) {
+        } else if self.is_kw_followed_by_ident(kw::Mut) && self.may_recover() {
+            self.recover_stmt_local_after_let(lo, attrs, InvalidVariableDeclarationSub::MissingLet)?
+        } else if self.is_kw_followed_by_ident(kw::Auto) && self.may_recover() {
             self.bump(); // `auto`
-            self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotAuto)?
-        } else if self.is_kw_followed_by_ident(sym::var) {
+            self.recover_stmt_local_after_let(
+                lo,
+                attrs,
+                InvalidVariableDeclarationSub::UseLetNotAuto,
+            )?
+        } else if self.is_kw_followed_by_ident(sym::var) && self.may_recover() {
             self.bump(); // `var`
-            self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotVar)?
+            self.recover_stmt_local_after_let(
+                lo,
+                attrs,
+                InvalidVariableDeclarationSub::UseLetNotVar,
+            )?
         } else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() {
             // We have avoided contextual keywords like `union`, items with `crate` visibility,
             // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something
@@ -213,13 +221,21 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn recover_stmt_local(
+    fn recover_stmt_local_after_let(
         &mut self,
         lo: Span,
         attrs: AttrWrapper,
         subdiagnostic: fn(Span) -> InvalidVariableDeclarationSub,
     ) -> PResult<'a, Stmt> {
-        let stmt = self.recover_local_after_let(lo, attrs)?;
+        let stmt =
+            self.collect_tokens_trailing_token(attrs, ForceCollect::Yes, |this, attrs| {
+                let local = this.parse_local(attrs)?;
+                // FIXME - maybe capture semicolon in recovery?
+                Ok((
+                    this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Local(local)),
+                    TrailingToken::None,
+                ))
+            })?;
         self.sess.emit_err(InvalidVariableDeclaration { span: lo, sub: subdiagnostic(lo) });
         Ok(stmt)
     }
@@ -243,17 +259,6 @@ impl<'a> Parser<'a> {
         })
     }
 
-    fn recover_local_after_let(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> {
-        self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
-            let local = this.parse_local(attrs)?;
-            // FIXME - maybe capture semicolon in recovery?
-            Ok((
-                this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Local(local)),
-                TrailingToken::None,
-            ))
-        })
-    }
-
     /// Parses a local variable declaration.
     fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
         let lo = self.prev_token.span;
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index e44857a0238..30d28ff3455 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -532,7 +532,8 @@ impl<K: DepKind> DepGraph<K> {
             let mut edges = SmallVec::new();
             K::read_deps(|task_deps| match task_deps {
                 TaskDepsRef::Allow(deps) => edges.extend(deps.lock().reads.iter().copied()),
-                TaskDepsRef::Ignore | TaskDepsRef::Forbid => {
+                TaskDepsRef::Ignore => {} // During HIR lowering, we have no dependencies.
+                TaskDepsRef::Forbid => {
                     panic!("Cannot summarize when dependencies are not recorded.")
                 }
             });
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index bc3a710e84b..f6b6cf3a94c 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1840,13 +1840,16 @@ impl<'a> Resolver<'a> {
 
             (format!("use of undeclared type `{}`", ident), suggestion)
         } else {
-            let suggestion = if ident.name == sym::alloc {
-                Some((
+            let mut suggestion = None;
+            if ident.name == sym::alloc {
+                suggestion = Some((
                     vec![],
                     String::from("add `extern crate alloc` to use the `alloc` crate"),
                     Applicability::MaybeIncorrect,
                 ))
-            } else {
+            }
+
+            suggestion = suggestion.or_else(|| {
                 self.find_similarly_named_module_or_crate(ident.name, &parent_scope.module).map(
                     |sugg| {
                         (
@@ -1856,7 +1859,7 @@ impl<'a> Resolver<'a> {
                         )
                     },
                 )
-            };
+            });
             (format!("use of undeclared crate or module `{}`", ident), suggestion)
         }
     }
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index e6f4d7fcfcf..b100a8c17cf 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -4,7 +4,10 @@ use crate::diagnostics::{import_candidates, Suggestion};
 use crate::Determinacy::{self, *};
 use crate::Namespace::*;
 use crate::{module_to_string, names_to_string, ImportSuggestion};
-use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
+use crate::{
+    AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, ModuleKind, ResolutionError,
+    Resolver, Segment,
+};
 use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
 use crate::{NameBinding, NameBindingKind, PathResult};
 
@@ -791,7 +794,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 match binding {
                     Ok(binding) => {
                         // Consistency checks, analogous to `finalize_macro_resolutions`.
-                        let initial_res = source_bindings[ns].get().map(|initial_binding| {
+                        let initial_binding = source_bindings[ns].get().map(|initial_binding| {
                             all_ns_err = false;
                             if let Some(target_binding) = target_bindings[ns].get() {
                                 if target.name == kw::Underscore
@@ -805,12 +808,20 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                                     );
                                 }
                             }
-                            initial_binding.res()
+                            initial_binding
                         });
                         let res = binding.res();
-                        if let Ok(initial_res) = initial_res {
+                        if let Ok(initial_binding) = initial_binding {
+                            let initial_res = initial_binding.res();
                             if res != initial_res && this.ambiguity_errors.is_empty() {
-                                span_bug!(import.span, "inconsistent resolution for an import");
+                                this.ambiguity_errors.push(AmbiguityError {
+                                    kind: AmbiguityKind::Import,
+                                    ident,
+                                    b1: initial_binding,
+                                    b2: binding,
+                                    misc1: AmbiguityErrorMisc::None,
+                                    misc2: AmbiguityErrorMisc::None,
+                                });
                             }
                         } else if res != Res::Err
                             && this.ambiguity_errors.is_empty()
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 2d2408c061e..51a53f7b37c 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -3365,13 +3365,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             // Before we start looking for candidates, we have to get our hands
             // on the type user is trying to perform invocation on; basically:
             // we're transforming `HashMap::new` into just `HashMap`.
-            let path = match path.split_last() {
+            let prefix_path = match path.split_last() {
                 Some((_, path)) if !path.is_empty() => path,
                 _ => return Some(parent_err),
             };
 
             let (mut err, candidates) =
-                this.smart_resolve_report_errors(path, path_span, PathSource::Type, None);
+                this.smart_resolve_report_errors(prefix_path, path_span, PathSource::Type, None);
 
             // There are two different error messages user might receive at
             // this point:
@@ -3415,11 +3415,23 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
 
             if this.should_report_errs() {
                 if candidates.is_empty() {
-                    // When there is no suggested imports, we can just emit the error
-                    // and suggestions immediately. Note that we bypass the usually error
-                    // reporting routine (ie via `self.r.report_error`) because we need
-                    // to post-process the `ResolutionError` above.
-                    err.emit();
+                    if path.len() == 2 && prefix_path.len() == 1 {
+                        // Delay to check whether methond name is an associated function or not
+                        // ```
+                        // let foo = Foo {};
+                        // foo::bar(); // possibly suggest to foo.bar();
+                        //```
+                        err.stash(
+                            prefix_path[0].ident.span,
+                            rustc_errors::StashKey::CallAssocMethod,
+                        );
+                    } else {
+                        // When there is no suggested imports, we can just emit the error
+                        // and suggestions immediately. Note that we bypass the usually error
+                        // reporting routine (ie via `self.r.report_error`) because we need
+                        // to post-process the `ResolutionError` above.
+                        err.emit();
+                    }
                 } else {
                     // If there are suggested imports, the error reporting is delayed
                     this.r.use_injections.push(UseError {
@@ -3428,7 +3440,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                         def_id,
                         instead: false,
                         suggestion: None,
-                        path: path.into(),
+                        path: prefix_path.into(),
                         is_call: source.is_call(),
                     });
                 }
diff --git a/compiler/rustc_session/src/cgu_reuse_tracker.rs b/compiler/rustc_session/src/cgu_reuse_tracker.rs
index 2336d99363f..8703e575465 100644
--- a/compiler/rustc_session/src/cgu_reuse_tracker.rs
+++ b/compiler/rustc_session/src/cgu_reuse_tracker.rs
@@ -121,7 +121,7 @@ impl CguReuseTracker {
                         let at_least = if at_least { 1 } else { 0 };
                         IncorrectCguReuseType {
                             span: error_span.0,
-                            cgu_user_name: &cgu_user_name,
+                            cgu_user_name,
                             actual_reuse,
                             expected_reuse,
                             at_least,
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 927810351e9..d8c4b0845d0 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -622,7 +622,7 @@ impl OutputFilenames {
     /// should be placed on disk.
     pub fn output_path(&self, flavor: OutputType) -> PathBuf {
         let extension = flavor.extension();
-        self.with_directory_and_extension(&self.out_directory, &extension)
+        self.with_directory_and_extension(&self.out_directory, extension)
     }
 
     /// Gets the path where a compilation artifact of the given type for the
@@ -659,7 +659,7 @@ impl OutputFilenames {
 
         let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
 
-        self.with_directory_and_extension(&temps_directory, &extension)
+        self.with_directory_and_extension(temps_directory, &extension)
     }
 
     pub fn with_extension(&self, extension: &str) -> PathBuf {
@@ -1159,7 +1159,7 @@ impl CrateCheckConfig {
                 values_target_family
                     .extend(target.options.families.iter().map(|family| Symbol::intern(family)));
                 values_target_arch.insert(Symbol::intern(&target.arch));
-                values_target_endian.insert(Symbol::intern(&target.options.endian.as_str()));
+                values_target_endian.insert(Symbol::intern(target.options.endian.as_str()));
                 values_target_env.insert(Symbol::intern(&target.options.env));
                 values_target_abi.insert(Symbol::intern(&target.options.abi));
                 values_target_vendor.insert(Symbol::intern(&target.options.vendor));
@@ -1846,7 +1846,7 @@ pub fn parse_target_triple(
     match matches.opt_str("target") {
         Some(target) if target.ends_with(".json") => {
             let path = Path::new(&target);
-            TargetTriple::from_path(&path).unwrap_or_else(|_| {
+            TargetTriple::from_path(path).unwrap_or_else(|_| {
                 early_error(error_format, &format!("target file {path:?} does not exist"))
             })
         }
@@ -1992,7 +1992,7 @@ fn parse_native_lib_modifiers(
 ) -> (NativeLibKind, Option<bool>) {
     let mut verbatim = None;
     for modifier in modifiers.split(',') {
-        let (modifier, value) = match modifier.strip_prefix(&['+', '-']) {
+        let (modifier, value) = match modifier.strip_prefix(['+', '-']) {
             Some(m) => (m, modifier.starts_with('+')),
             None => early_error(
                 error_format,
@@ -2421,7 +2421,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let mut search_paths = vec![];
     for s in &matches.opt_strs("L") {
-        search_paths.push(SearchPath::from_cli_opt(&s, error_format));
+        search_paths.push(SearchPath::from_cli_opt(s, error_format));
     }
 
     let libs = parse_libs(matches, error_format);
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 9aa8a06c6d3..8cb9e1a6f1a 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -317,7 +317,7 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
         LitError::InvalidIntSuffix => {
             let suf = suffix.expect("suffix error with no suffix");
             let suf = suf.as_str();
-            if looks_like_width_suffix(&['i', 'u'], &suf) {
+            if looks_like_width_suffix(&['i', 'u'], suf) {
                 // If it looks like a width, try to be helpful.
                 sess.emit_err(InvalidIntLiteralWidth { span, width: suf[1..].into() });
             } else if let Some(fixed) = fix_base_capitalisation(suf) {
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index f9ee202466f..01a9361e786 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1414,8 +1414,6 @@ options! {
         "run all passes except codegen; no output"),
     no_generate_arange_section: bool = (false, parse_no_flag, [TRACKED],
         "omit DWARF address ranges that give faster lookups"),
-    no_interleave_lints: bool = (false, parse_no_flag, [UNTRACKED],
-        "execute lints separately; allows benchmarking individual lints"),
     no_leak_check: bool = (false, parse_no_flag, [UNTRACKED],
         "disable the 'leak check' for subtyping; unsound, but useful for tests"),
     no_link: bool = (false, parse_no_flag, [TRACKED],
diff --git a/compiler/rustc_span/src/analyze_source_file.rs b/compiler/rustc_span/src/analyze_source_file.rs
index 47aa4dfba42..d3c2c5113bc 100644
--- a/compiler/rustc_span/src/analyze_source_file.rs
+++ b/compiler/rustc_span/src/analyze_source_file.rs
@@ -247,7 +247,7 @@ fn analyze_source_file_generic(
             // The slow path:
             // This is either ASCII control character "DEL" or the beginning of
             // a multibyte char. Just decode to `char`.
-            let c = (&src[i..]).chars().next().unwrap();
+            let c = src[i..].chars().next().unwrap();
             char_len = c.len_utf8();
 
             let pos = BytePos::from_usize(i) + output_offset;
diff --git a/compiler/rustc_span/src/caching_source_map_view.rs b/compiler/rustc_span/src/caching_source_map_view.rs
index fdabf404a37..886112769a9 100644
--- a/compiler/rustc_span/src/caching_source_map_view.rs
+++ b/compiler/rustc_span/src/caching_source_map_view.rs
@@ -165,7 +165,7 @@ impl<'sm> CachingSourceMapView<'sm> {
             Some(new_file_and_idx)
         } else {
             let file = &self.line_cache[oldest].file;
-            if !file_contains(&file, span_data.hi) {
+            if !file_contains(file, span_data.hi) {
                 return None;
             }
 
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 99a8b03fa39..038699154c7 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -381,7 +381,7 @@ impl HygieneData {
     }
 
     pub fn with<T, F: FnOnce(&mut HygieneData) -> T>(f: F) -> T {
-        with_session_globals(|session_globals| f(&mut *session_globals.hygiene_data.borrow_mut()))
+        with_session_globals(|session_globals| f(&mut session_globals.hygiene_data.borrow_mut()))
     }
 
     #[inline]
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 1065cd384a9..cef4c6f79ce 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -238,7 +238,7 @@ impl RealFileName {
     pub fn remapped_path_if_available(&self) -> &Path {
         match self {
             RealFileName::LocalPath(p)
-            | RealFileName::Remapped { local_path: _, virtual_name: p } => &p,
+            | RealFileName::Remapped { local_path: _, virtual_name: p } => p,
         }
     }
 
diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs
index b3de6741594..f0e91e5a6a9 100644
--- a/compiler/rustc_span/src/span_encoding.rs
+++ b/compiler/rustc_span/src/span_encoding.rs
@@ -166,5 +166,5 @@ impl SpanInterner {
 // If an interner exists, return it. Otherwise, prepare a fresh one.
 #[inline]
 fn with_span_interner<T, F: FnOnce(&mut SpanInterner) -> T>(f: F) -> T {
-    crate::with_session_globals(|session_globals| f(&mut *session_globals.span_interner.lock()))
+    crate::with_session_globals(|session_globals| f(&mut session_globals.span_interner.lock()))
 }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 663cf65d1a5..9e446c96db3 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1877,7 +1877,7 @@ impl<S: Encoder> Encodable<S> for Symbol {
 impl<D: Decoder> Decodable<D> for Symbol {
     #[inline]
     default fn decode(d: &mut D) -> Symbol {
-        Symbol::intern(&d.read_str())
+        Symbol::intern(d.read_str())
     }
 }
 
diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs
index ec8f20fe692..c8b6ac5ae25 100644
--- a/compiler/rustc_target/src/abi/call/sparc64.rs
+++ b/compiler/rustc_target/src/abi/call/sparc64.rs
@@ -78,7 +78,7 @@ fn arg_scalar_pair<C>(
 where
     C: HasDataLayout,
 {
-    data = arg_scalar(cx, &scalar1, offset, data);
+    data = arg_scalar(cx, scalar1, offset, data);
     match (scalar1.primitive(), scalar2.primitive()) {
         (abi::F32, _) => offset += Reg::f32().size,
         (_, abi::F64) => offset += Reg::f64().size,
@@ -90,7 +90,7 @@ where
     if (offset.bytes() % 4) != 0 && scalar2.primitive().is_float() {
         offset += Size::from_bytes(4 - (offset.bytes() % 4));
     }
-    data = arg_scalar(cx, &scalar2, offset, data);
+    data = arg_scalar(cx, scalar2, offset, data);
     return data;
 }
 
diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
index 0f6bbc32317..e72cab629ff 100644
--- a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
@@ -1,4 +1,4 @@
-use super::apple_base::{macos_link_env_remove, macos_llvm_target, opts, Arch};
+use super::apple_base::{macos_llvm_target, opts, Arch};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
 pub fn target() -> Target {
@@ -10,8 +10,6 @@ pub fn target() -> Target {
     // FIXME: The leak sanitizer currently fails the tests, see #88132.
     base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;
 
-    base.link_env_remove.to_mut().extend(macos_link_env_remove());
-
     Target {
         // Clang automatically chooses a more specific target based on
         // MACOSX_DEPLOYMENT_TARGET.  To enable cross-language LTO to work
diff --git a/compiler/rustc_target/src/spec/apple/tests.rs b/compiler/rustc_target/src/spec/apple/tests.rs
index d062b36742d..3c90a5e7e93 100644
--- a/compiler/rustc_target/src/spec/apple/tests.rs
+++ b/compiler/rustc_target/src/spec/apple/tests.rs
@@ -1,6 +1,6 @@
 use crate::spec::{
-    aarch64_apple_ios_sim, aarch64_apple_watchos_sim, x86_64_apple_ios, x86_64_apple_tvos,
-    x86_64_apple_watchos_sim,
+    aarch64_apple_darwin, aarch64_apple_ios_sim, aarch64_apple_watchos_sim, i686_apple_darwin,
+    x86_64_apple_darwin, x86_64_apple_ios, x86_64_apple_tvos, x86_64_apple_watchos_sim,
 };
 
 #[test]
@@ -18,3 +18,18 @@ fn simulator_targets_set_abi() {
         assert_eq!(target.abi, "sim")
     }
 }
+
+#[test]
+fn macos_link_environment_unmodified() {
+    let all_macos_targets = [
+        aarch64_apple_darwin::target(),
+        i686_apple_darwin::target(),
+        x86_64_apple_darwin::target(),
+    ];
+
+    for target in all_macos_targets {
+        // macOS targets should only remove information for cross-compiling, but never
+        // for the host.
+        assert_eq!(target.link_env_remove, crate::spec::cvs!["IPHONEOS_DEPLOYMENT_TARGET"]);
+    }
+}
diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
index 23c826cb1bd..7f8160b5dec 100644
--- a/compiler/rustc_target/src/spec/apple_base.rs
+++ b/compiler/rustc_target/src/spec/apple_base.rs
@@ -72,16 +72,6 @@ impl Arch {
             Arm64_sim => "apple-a12",
         }
     }
-
-    fn link_env_remove(self) -> StaticCow<[StaticCow<str>]> {
-        match self {
-            Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim
-            | Arm64_sim => {
-                cvs!["MACOSX_DEPLOYMENT_TARGET"]
-            }
-            X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"],
-        }
-    }
 }
 
 fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs {
@@ -140,7 +130,7 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
         abi: abi.into(),
         os: os.into(),
         cpu: arch.target_cpu().into(),
-        link_env_remove: arch.link_env_remove(),
+        link_env_remove: link_env_remove(arch, os),
         vendor: "apple".into(),
         linker_flavor: LinkerFlavor::Darwin(Cc::Yes, Lld::No),
         // macOS has -dead_strip, which doesn't rely on function_sections
@@ -211,20 +201,38 @@ pub fn macos_llvm_target(arch: Arch) -> String {
     format!("{}-apple-macosx{}.{}.0", arch.target_name(), major, minor)
 }
 
-pub fn macos_link_env_remove() -> Vec<StaticCow<str>> {
-    let mut env_remove = Vec::with_capacity(2);
-    // Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
-    // may occur when we're linking a custom build script while targeting iOS for example.
-    if let Ok(sdkroot) = env::var("SDKROOT") {
-        if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("iPhoneSimulator.platform") {
-            env_remove.push("SDKROOT".into())
+fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow<str>]> {
+    // Apple platforms only officially support macOS as a host for any compilation.
+    //
+    // If building for macOS, we go ahead and remove any erronous environment state
+    // that's only applicable to cross-OS compilation. Always leave anything for the
+    // host OS alone though.
+    if os == "macos" {
+        let mut env_remove = Vec::with_capacity(2);
+        // Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
+        // may occur when we're linking a custom build script while targeting iOS for example.
+        if let Ok(sdkroot) = env::var("SDKROOT") {
+            if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("iPhoneSimulator.platform")
+            {
+                env_remove.push("SDKROOT".into())
+            }
+        }
+        // Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at
+        // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",
+        // although this is apparently ignored when using the linker at "/usr/bin/ld".
+        env_remove.push("IPHONEOS_DEPLOYMENT_TARGET".into());
+        env_remove.into()
+    } else {
+        // Otherwise if cross-compiling for a different OS/SDK, remove any part
+        // of the linking environment that's wrong and reversed.
+        match arch {
+            Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim
+            | Arm64_sim => {
+                cvs!["MACOSX_DEPLOYMENT_TARGET"]
+            }
+            X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"],
         }
     }
-    // Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at
-    // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",
-    // although this is apparently ignored when using the linker at "/usr/bin/ld".
-    env_remove.push("IPHONEOS_DEPLOYMENT_TARGET".into());
-    env_remove
 }
 
 fn ios_deployment_target() -> (u32, u32) {
diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs
index 8b968af5ecc..ad22467ba9c 100644
--- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs
@@ -1,4 +1,4 @@
-use super::apple_base::{macos_link_env_remove, macos_llvm_target, opts, Arch};
+use super::apple_base::{macos_llvm_target, opts, Arch};
 use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
@@ -7,7 +7,6 @@ pub fn target() -> Target {
     let mut base = opts("macos", arch);
     base.max_atomic_width = Some(64);
     base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]);
-    base.link_env_remove.to_mut().extend(macos_link_env_remove());
     base.stack_probes = StackProbeType::X86;
     base.frame_pointer = FramePointer::Always;
 
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 78315afa759..d05b8aa4200 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2658,7 +2658,7 @@ impl Target {
 
                 // Additionally look in the sysroot under `lib/rustlib/<triple>/target.json`
                 // as a fallback.
-                let rustlib_path = crate::target_rustlib_path(&sysroot, &target_triple);
+                let rustlib_path = crate::target_rustlib_path(sysroot, target_triple);
                 let p = PathBuf::from_iter([
                     Path::new(sysroot),
                     Path::new(&rustlib_path),
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
index c053031612c..9a3e7a80500 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
@@ -1,4 +1,4 @@
-use super::apple_base::{macos_link_env_remove, macos_llvm_target, opts, Arch};
+use super::apple_base::{macos_llvm_target, opts, Arch};
 use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet};
 use crate::spec::{StackProbeType, Target, TargetOptions};
 
@@ -8,7 +8,6 @@ pub fn target() -> Target {
     base.max_atomic_width = Some(128); // core2 supports cmpxchg16b
     base.frame_pointer = FramePointer::Always;
     base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
-    base.link_env_remove.to_mut().extend(macos_link_env_remove());
     base.stack_probes = StackProbeType::X86;
     base.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 99724fb28db..899e30275a0 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -11,8 +11,8 @@ use crate::traits::select::IntercrateAmbiguityCause;
 use crate::traits::util::impl_subject_and_oblig;
 use crate::traits::SkipLeakCheck;
 use crate::traits::{
-    self, Normalized, Obligation, ObligationCause, ObligationCtxt, PredicateObligation,
-    PredicateObligations, SelectionContext,
+    self, Obligation, ObligationCause, ObligationCtxt, PredicateObligation, PredicateObligations,
+    SelectionContext,
 };
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::Diagnostic;
@@ -30,6 +30,8 @@ use std::fmt::Debug;
 use std::iter;
 use std::ops::ControlFlow;
 
+use super::NormalizeExt;
+
 /// Whether we do the orphan check relative to this crate or
 /// to some remote crate.
 #[derive(Copy, Clone, Debug)]
@@ -128,8 +130,8 @@ fn with_fresh_ty_vars<'cx, 'tcx>(
         predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates,
     };
 
-    let Normalized { value: mut header, obligations } =
-        traits::normalize(selcx, param_env, ObligationCause::dummy(), header);
+    let InferOk { value: mut header, obligations } =
+        selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(header);
 
     header.predicates.extend(obligations.into_iter().map(|o| o.predicate));
     header
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index 64d01ddb09a..c028e89e4ea 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -112,6 +112,24 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
         self.register_infer_ok_obligations(infer_ok)
     }
 
+    /// Makes `expected <: actual`.
+    pub fn eq_exp<T>(
+        &self,
+        cause: &ObligationCause<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        a_is_expected: bool,
+        a: T,
+        b: T,
+    ) -> Result<(), TypeError<'tcx>>
+    where
+        T: ToTrace<'tcx>,
+    {
+        self.infcx
+            .at(cause, param_env)
+            .eq_exp(a_is_expected, a, b)
+            .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
+    }
+
     pub fn eq<T: ToTrace<'tcx>>(
         &self,
         cause: &ObligationCause<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 049b24b3997..3379279dd15 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -9,7 +9,7 @@ use super::{
 };
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use crate::infer::{self, InferCtxt, TyCtxtInferExt};
+use crate::infer::{self, InferCtxt};
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use crate::traits::query::normalize::QueryNormalizeExt as _;
 use crate::traits::specialize::to_pretty_impl_header;
@@ -71,7 +71,7 @@ pub trait InferCtxtExt<'tcx> {
     /// returns a span and `ArgKind` information that describes the
     /// arguments it expects. This can be supplied to
     /// `report_arg_count_mismatch`.
-    fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Vec<ArgKind>)>;
+    fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Option<Span>, Vec<ArgKind>)>;
 
     /// Reports an error when the number of arguments needed by a
     /// trait match doesn't match the number that the expression
@@ -83,6 +83,7 @@ pub trait InferCtxtExt<'tcx> {
         expected_args: Vec<ArgKind>,
         found_args: Vec<ArgKind>,
         is_closure: bool,
+        closure_pipe_span: Option<Span>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
 
     /// Checks if the type implements one of `Fn`, `FnMut`, or `FnOnce`
@@ -135,15 +136,16 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
     /// returns a span and `ArgKind` information that describes the
     /// arguments it expects. This can be supplied to
     /// `report_arg_count_mismatch`.
-    fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Vec<ArgKind>)> {
+    fn get_fn_like_arguments(&self, node: Node<'_>) -> Option<(Span, Option<Span>, Vec<ArgKind>)> {
         let sm = self.tcx.sess.source_map();
         let hir = self.tcx.hir();
         Some(match node {
             Node::Expr(&hir::Expr {
-                kind: hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }),
+                kind: hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, fn_arg_span, .. }),
                 ..
             }) => (
                 fn_decl_span,
+                fn_arg_span,
                 hir.body(body)
                     .params
                     .iter()
@@ -174,6 +176,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
                 kind: hir::TraitItemKind::Fn(ref sig, _), ..
             }) => (
                 sig.span,
+                None,
                 sig.decl
                     .inputs
                     .iter()
@@ -188,7 +191,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
             ),
             Node::Ctor(ref variant_data) => {
                 let span = variant_data.ctor_hir_id().map_or(DUMMY_SP, |id| hir.span(id));
-                (span, vec![ArgKind::empty(); variant_data.fields().len()])
+                (span, None, vec![ArgKind::empty(); variant_data.fields().len()])
             }
             _ => panic!("non-FnLike node found: {:?}", node),
         })
@@ -204,6 +207,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         expected_args: Vec<ArgKind>,
         found_args: Vec<ArgKind>,
         is_closure: bool,
+        closure_arg_span: Option<Span>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let kind = if is_closure { "closure" } else { "function" };
 
@@ -241,24 +245,13 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         if let Some(found_span) = found_span {
             err.span_label(found_span, format!("takes {}", found_str));
 
-            // move |_| { ... }
-            // ^^^^^^^^-- def_span
-            //
-            // move |_| { ... }
-            // ^^^^^-- prefix
-            let prefix_span = self.tcx.sess.source_map().span_until_non_whitespace(found_span);
-            // move |_| { ... }
-            //      ^^^-- pipe_span
-            let pipe_span =
-                if let Some(span) = found_span.trim_start(prefix_span) { span } else { found_span };
-
             // Suggest to take and ignore the arguments with expected_args_length `_`s if
             // found arguments is empty (assume the user just wants to ignore args in this case).
             // For example, if `expected_args_length` is 2, suggest `|_, _|`.
             if found_args.is_empty() && is_closure {
                 let underscores = vec!["_"; expected_args.len()].join(", ");
                 err.span_suggestion_verbose(
-                    pipe_span,
+                    closure_arg_span.unwrap_or(found_span),
                     &format!(
                         "consider changing the closure to take and ignore the expected argument{}",
                         pluralize!(expected_args.len())
@@ -1252,13 +1245,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         obligation.cause.code(),
                     )
                 } else {
-                    let (closure_span, found) = found_did
+                    let (closure_span, closure_arg_span, found) = found_did
                         .and_then(|did| {
                             let node = self.tcx.hir().get_if_local(did)?;
-                            let (found_span, found) = self.get_fn_like_arguments(node)?;
-                            Some((Some(found_span), found))
+                            let (found_span, closure_arg_span, found) =
+                                self.get_fn_like_arguments(node)?;
+                            Some((Some(found_span), closure_arg_span, found))
                         })
-                        .unwrap_or((found_span, found));
+                        .unwrap_or((found_span, None, found));
 
                     self.report_arg_count_mismatch(
                         span,
@@ -1266,6 +1260,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         expected,
                         found,
                         found_trait_ty.is_closure(),
+                        closure_arg_span,
                     )
                 }
             }
@@ -1577,32 +1572,26 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         }
 
         self.probe(|_| {
-            let mut err = error.err;
-            let mut values = None;
+            let ocx = ObligationCtxt::new_in_snapshot(self);
 
             // try to find the mismatched types to report the error with.
             //
             // this can fail if the problem was higher-ranked, in which
             // cause I have no idea for a good error message.
             let bound_predicate = predicate.kind();
-            if let ty::PredicateKind::Clause(ty::Clause::Projection(data)) =
+            let (values, err) = if let ty::PredicateKind::Clause(ty::Clause::Projection(data)) =
                 bound_predicate.skip_binder()
             {
-                let mut selcx = SelectionContext::new(self);
                 let data = self.replace_bound_vars_with_fresh_vars(
                     obligation.cause.span,
                     infer::LateBoundRegionConversionTime::HigherRankedType,
                     bound_predicate.rebind(data),
                 );
-                let mut obligations = vec![];
-                // FIXME(normalization): Change this to use `At::normalize`
-                let normalized_ty = super::normalize_projection_type(
-                    &mut selcx,
+                let normalized_ty = ocx.normalize(
+                    &obligation.cause,
                     obligation.param_env,
-                    data.projection_ty,
-                    obligation.cause.clone(),
-                    0,
-                    &mut obligations,
+                    self.tcx
+                        .mk_projection(data.projection_ty.item_def_id, data.projection_ty.substs),
                 );
 
                 debug!(?obligation.cause, ?obligation.param_env);
@@ -1618,19 +1607,34 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         | ObligationCauseCode::ObjectCastObligation(..)
                         | ObligationCauseCode::OpaqueType
                 );
-                if let Err(new_err) = self.at(&obligation.cause, obligation.param_env).eq_exp(
+                let expected_ty = data.term.ty().unwrap();
+
+                // constrain inference variables a bit more to nested obligations from normalize so
+                // we can have more helpful errors.
+                ocx.select_where_possible();
+
+                if let Err(new_err) = ocx.eq_exp(
+                    &obligation.cause,
+                    obligation.param_env,
                     is_normalized_ty_expected,
                     normalized_ty,
-                    data.term,
+                    expected_ty,
                 ) {
-                    values = Some((data, is_normalized_ty_expected, normalized_ty, data.term));
-                    err = new_err;
+                    (Some((data, is_normalized_ty_expected, normalized_ty, expected_ty)), new_err)
+                } else {
+                    (None, error.err)
                 }
-            }
+            } else {
+                (None, error.err)
+            };
 
             let msg = values
                 .and_then(|(predicate, _, normalized_ty, expected_ty)| {
-                    self.maybe_detailed_projection_msg(predicate, normalized_ty, expected_ty)
+                    self.maybe_detailed_projection_msg(
+                        predicate,
+                        normalized_ty.into(),
+                        expected_ty.into(),
+                    )
                 })
                 .unwrap_or_else(|| format!("type mismatch resolving `{}`", predicate));
             let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
@@ -1672,11 +1676,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 &mut diag,
                 &obligation.cause,
                 secondary_span,
-                values.map(|(_, is_normalized_ty_expected, normalized_ty, term)| {
+                values.map(|(_, is_normalized_ty_expected, normalized_ty, expected_ty)| {
                     infer::ValuePairs::Terms(ExpectedFound::new(
                         is_normalized_ty_expected,
-                        normalized_ty,
-                        term,
+                        normalized_ty.into(),
+                        expected_ty.into(),
                     ))
                 }),
                 err,
@@ -1930,14 +1934,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             return report(normalized_impl_candidates, err);
         }
 
-        let normalize = |candidate| {
-            let infcx = self.tcx.infer_ctxt().build();
-            infcx
-                .at(&ObligationCause::dummy(), ty::ParamEnv::empty())
-                .query_normalize(candidate)
-                .map_or(candidate, |normalized| normalized.value)
-        };
-
         // Sort impl candidates so that ordering is consistent for UI tests.
         // because the ordering of `impl_candidates` may not be deterministic:
         // https://github.com/rust-lang/rust/pull/57475#issuecomment-455519507
@@ -1947,7 +1943,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let mut normalized_impl_candidates_and_similarities = impl_candidates
             .into_iter()
             .map(|ImplCandidate { trait_ref, similarity }| {
-                let normalized = normalize(trait_ref);
+                // FIXME(compiler-errors): This should be using `NormalizeExt::normalize`
+                let normalized = self
+                    .at(&ObligationCause::dummy(), ty::ParamEnv::empty())
+                    .query_normalize(trait_ref)
+                    .map_or(trait_ref, |normalized| normalized.value);
                 (similarity, normalized)
             })
             .collect::<Vec<_>>();
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 371367f0deb..c6818a4e57d 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -56,7 +56,6 @@ pub use self::object_safety::astconv_object_safety_violations;
 pub use self::object_safety::is_vtable_safe_method;
 pub use self::object_safety::MethodViolationCode;
 pub use self::object_safety::ObjectSafetyViolation;
-pub(crate) use self::project::{normalize, normalize_to};
 pub use self::project::{normalize_projection_type, NormalizeExt};
 pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
 pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 113803cd179..051660be9c4 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -50,6 +50,10 @@ pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::ProjectionTy<'tcx>>
 pub(super) struct InProgress;
 
 pub trait NormalizeExt<'tcx> {
+    /// Normalize a value using the `AssocTypeNormalizer`.
+    ///
+    /// This normalization should be used when the type contains inference variables or the
+    /// projection may be fallible.
     fn normalize<T: TypeFoldable<'tcx>>(&self, t: T) -> InferOk<'tcx, T>;
 }
 
@@ -57,7 +61,7 @@ impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
     fn normalize<T: TypeFoldable<'tcx>>(&self, value: T) -> InferOk<'tcx, T> {
         let mut selcx = SelectionContext::new(self.infcx);
         let Normalized { value, obligations } =
-            normalize(&mut selcx, self.param_env, self.cause.clone(), value);
+            normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
         InferOk { value, obligations }
     }
 }
@@ -303,37 +307,6 @@ fn project_and_unify_type<'cx, 'tcx>(
     }
 }
 
-/// Normalizes any associated type projections in `value`, replacing
-/// them with a fully resolved type where possible. The return value
-/// combines the normalized result and any additional obligations that
-/// were incurred as result.
-pub(crate) fn normalize<'a, 'b, 'tcx, T>(
-    selcx: &'a mut SelectionContext<'b, 'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    cause: ObligationCause<'tcx>,
-    value: T,
-) -> Normalized<'tcx, T>
-where
-    T: TypeFoldable<'tcx>,
-{
-    let mut obligations = Vec::new();
-    let value = normalize_to(selcx, param_env, cause, value, &mut obligations);
-    Normalized { value, obligations }
-}
-
-pub(crate) fn normalize_to<'a, 'b, 'tcx, T>(
-    selcx: &'a mut SelectionContext<'b, 'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    cause: ObligationCause<'tcx>,
-    value: T,
-    obligations: &mut Vec<PredicateObligation<'tcx>>,
-) -> T
-where
-    T: TypeFoldable<'tcx>,
-{
-    normalize_with_depth_to(selcx, param_env, cause, 0, value, obligations)
-}
-
 /// As `normalize`, but with a custom depth.
 pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>(
     selcx: &'a mut SelectionContext<'b, 'tcx>,
@@ -2324,10 +2297,11 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
         },
     ));
 
-    let ty = super::normalize_to(
+    let ty = normalize_with_depth_to(
         selcx,
         obligation.param_env,
         cause.clone(),
+        obligation.recursion_depth + 1,
         tcx.bound_trait_impl_trait_tys(impl_fn_def_id)
             .map_bound(|tys| {
                 tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.item_def_id])
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 1aed6630870..f899321fc01 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -23,6 +23,13 @@ use super::NoSolution;
 pub use rustc_middle::traits::query::NormalizationResult;
 
 pub trait QueryNormalizeExt<'tcx> {
+    /// Normalize a value using the `QueryNormalizer`.
+    ///
+    /// This normalization should *only* be used when the projection does not
+    /// have possible ambiguity or may not be well-formed.
+    ///
+    /// After codegen, when lifetimes do not matter, it is preferable to instead
+    /// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure.
     fn query_normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
     where
         T: TypeFoldable<'tcx>;
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index fe5135661b5..e4b70f0d2ff 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -203,7 +203,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // type/region parameters.
         let self_ty = obligation.self_ty().skip_binder();
         match self_ty.kind() {
-            ty::Generator(..) => {
+            // async constructs get lowered to a special kind of generator that
+            // should *not* `impl Generator`.
+            ty::Generator(did, ..) if !self.tcx().generator_is_async(*did) => {
                 debug!(?self_ty, ?obligation, "assemble_generator_candidates",);
 
                 candidates.vec.push(GeneratorCandidate);
@@ -223,6 +225,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ) {
         let self_ty = obligation.self_ty().skip_binder();
         if let ty::Generator(did, ..) = self_ty.kind() {
+            // async constructs get lowered to a special kind of generator that
+            // should directly `impl Future`.
             if self.tcx().generator_is_async(*did) {
                 debug!(?self_ty, ?obligation, "assemble_future_candidates",);
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 515f3a34988..8835f2cc1b9 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -371,23 +371,28 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
                     if !candidate_set.ambiguous && no_candidates_apply {
                         let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
-                        let self_ty = trait_ref.self_ty();
-                        let (trait_desc, self_desc) = with_no_trimmed_paths!({
-                            let trait_desc = trait_ref.print_only_trait_path().to_string();
-                            let self_desc = if self_ty.has_concrete_skeleton() {
-                                Some(self_ty.to_string())
+                        if !trait_ref.references_error() {
+                            let self_ty = trait_ref.self_ty();
+                            let (trait_desc, self_desc) = with_no_trimmed_paths!({
+                                let trait_desc = trait_ref.print_only_trait_path().to_string();
+                                let self_desc = if self_ty.has_concrete_skeleton() {
+                                    Some(self_ty.to_string())
+                                } else {
+                                    None
+                                };
+                                (trait_desc, self_desc)
+                            });
+                            let cause = if let Conflict::Upstream = conflict {
+                                IntercrateAmbiguityCause::UpstreamCrateUpdate {
+                                    trait_desc,
+                                    self_desc,
+                                }
                             } else {
-                                None
+                                IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
                             };
-                            (trait_desc, self_desc)
-                        });
-                        let cause = if let Conflict::Upstream = conflict {
-                            IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc }
-                        } else {
-                            IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
-                        };
-                        debug!(?cause, "evaluate_stack: pushing cause");
-                        self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause);
+                            debug!(?cause, "evaluate_stack: pushing cause");
+                            self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause);
+                        }
                     }
                 }
             }
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index ee8032ad6f0..4866c53e7d5 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -2699,12 +2699,18 @@ impl<T, A: Allocator> IndexMut<usize> for VecDeque<T, A> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> FromIterator<T> for VecDeque<T> {
+    #[inline]
     fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> VecDeque<T> {
-        let iterator = iter.into_iter();
-        let (lower, _) = iterator.size_hint();
-        let mut deq = VecDeque::with_capacity(lower);
-        deq.extend(iterator);
-        deq
+        // Since converting is O(1) now, might as well re-use that logic
+        // (including things like the `vec::IntoIter`→`Vec` specialization)
+        // especially as that could save us some monomorphiziation work
+        // if one uses the same iterators (like slice ones) with both.
+        return from_iter_via_vec(iter.into_iter());
+
+        #[inline]
+        fn from_iter_via_vec<U>(iter: impl Iterator<Item = U>) -> VecDeque<U> {
+            Vec::from_iter(iter).into()
+        }
     }
 }
 
@@ -2791,6 +2797,7 @@ impl<T, A: Allocator> From<Vec<T, A>> for VecDeque<T, A> {
     /// In its current implementation, this is a very cheap
     /// conversion. This isn't yet a guarantee though, and
     /// shouldn't be relied on.
+    #[inline]
     fn from(other: Vec<T, A>) -> Self {
         let (ptr, len, cap, alloc) = other.into_raw_parts_with_alloc();
         Self { head: 0, len, buf: unsafe { RawVec::from_raw_parts_in(ptr, cap, alloc) } }
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index e147af2ce39..ba34ab6800f 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1070,7 +1070,8 @@ impl<T, A: Allocator> Vec<T, A> {
 
     /// Converts the vector into [`Box<[T]>`][owned slice].
     ///
-    /// Note that this will drop any excess capacity.
+    /// If the vector has excess capacity, its items will be moved into a
+    /// newly-allocated buffer with exactly the right capacity.
     ///
     /// [owned slice]: Box
     ///
@@ -3223,6 +3224,14 @@ impl<T, A: Allocator> From<Vec<T, A>> for Box<[T], A> {
     /// ```
     /// assert_eq!(Box::from(vec![1, 2, 3]), vec![1, 2, 3].into_boxed_slice());
     /// ```
+    ///
+    /// Any excess capacity is removed:
+    /// ```
+    /// let mut vec = Vec::with_capacity(10);
+    /// vec.extend([1, 2, 3]);
+    ///
+    /// assert_eq!(Box::from(vec), vec![1, 2, 3].into_boxed_slice());
+    /// ```
     fn from(v: Vec<T, A>) -> Self {
         v.into_boxed_slice()
     }
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 141cbc7669b..6a339b338d9 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -1249,12 +1249,11 @@ macro_rules! nonzero_bits {
                 /// # Examples
                 ///
                 /// ```
-                /// #![feature(nonzero_bits)]
                 #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
                 ///
                 #[doc = concat!("assert_eq!(", stringify!($Ty), "::BITS, ", stringify!($Int), "::BITS);")]
                 /// ```
-                #[unstable(feature = "nonzero_bits", issue = "94881")]
+                #[stable(feature = "nonzero_bits", since = "CURRENT_RUSTC_VERSION")]
                 pub const BITS: u32 = <$Int>::BITS;
             }
         )+
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index 4fd1eb23413..a704a00faaa 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -38,10 +38,9 @@ use crate::panic::{Location, PanicInfo};
 /// site as much as possible (so that `panic!()` has as low an impact
 /// on (e.g.) the inlining of other functions as possible), by moving
 /// the actual formatting into this shared place.
-#[cold]
 // If panic_immediate_abort, inline the abort call,
 // otherwise avoid inlining because of it is cold path.
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 #[lang = "panic_fmt"] // needed for const-evaluated panics
@@ -67,8 +66,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
 
 /// Like panic_fmt, but without unwinding and track_caller to reduce the impact on codesize.
 /// Also just works on `str`, as a `fmt::Arguments` needs more space to be passed.
-#[cold]
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[rustc_nounwind]
 pub fn panic_str_nounwind(msg: &'static str) -> ! {
@@ -96,10 +94,9 @@ pub fn panic_str_nounwind(msg: &'static str) -> ! {
 // above.
 
 /// The underlying implementation of libcore's `panic!` macro when no formatting is used.
-#[cold]
 // never inline unless panic_immediate_abort to avoid code
 // bloat at the call sites as much as possible
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 #[rustc_const_unstable(feature = "core_panic", issue = "none")]
@@ -138,8 +135,8 @@ pub const fn panic_display<T: fmt::Display>(x: &T) -> ! {
     panic_fmt(format_args!("{}", *x));
 }
 
-#[cold]
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 #[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
 fn panic_bounds_check(index: usize, len: usize) -> ! {
@@ -154,8 +151,8 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
 ///
 /// This function is called directly by the codegen backend, and must not have
 /// any extra arguments (including those synthesized by track_caller).
-#[cold]
-#[inline(never)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[lang = "panic_no_unwind"] // needed by codegen for panic in nounwind function
 #[rustc_nounwind]
 fn panic_no_unwind() -> ! {
@@ -185,7 +182,8 @@ pub enum AssertKind {
 }
 
 /// Internal function for `assert_eq!` and `assert_ne!` macros
-#[cold]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 #[doc(hidden)]
 pub fn assert_failed<T, U>(
@@ -202,7 +200,8 @@ where
 }
 
 /// Internal function for `assert_match!`
-#[cold]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 #[doc(hidden)]
 pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
@@ -221,6 +220,8 @@ pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
 }
 
 /// Non-generic version of the above functions, to avoid code bloat.
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 fn assert_failed_inner(
     kind: AssertKind,
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index 6d2f7330d5d..c295a0e0645 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -31,9 +31,8 @@ where
     }
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
-#[cold]
 #[track_caller]
 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
 const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
@@ -48,19 +47,20 @@ const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
 }
 
 // FIXME const-hack
+#[inline]
 #[track_caller]
 fn slice_start_index_len_fail_rt(index: usize, len: usize) -> ! {
     panic!("range start index {index} out of range for slice of length {len}");
 }
 
+#[inline]
 #[track_caller]
 const fn slice_start_index_len_fail_ct(_: usize, _: usize) -> ! {
     panic!("slice start index is out of range for slice");
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
-#[cold]
 #[track_caller]
 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
 const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
@@ -71,19 +71,20 @@ const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
 }
 
 // FIXME const-hack
+#[inline]
 #[track_caller]
 fn slice_end_index_len_fail_rt(index: usize, len: usize) -> ! {
     panic!("range end index {index} out of range for slice of length {len}");
 }
 
+#[inline]
 #[track_caller]
 const fn slice_end_index_len_fail_ct(_: usize, _: usize) -> ! {
     panic!("slice end index is out of range for slice");
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
-#[cold]
 #[track_caller]
 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
 const fn slice_index_order_fail(index: usize, end: usize) -> ! {
@@ -92,27 +93,27 @@ const fn slice_index_order_fail(index: usize, end: usize) -> ! {
 }
 
 // FIXME const-hack
+#[inline]
 #[track_caller]
 fn slice_index_order_fail_rt(index: usize, end: usize) -> ! {
     panic!("slice index starts at {index} but ends at {end}");
 }
 
+#[inline]
 #[track_caller]
 const fn slice_index_order_fail_ct(_: usize, _: usize) -> ! {
     panic!("slice index start is larger than end");
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
-#[cold]
 #[track_caller]
 const fn slice_start_index_overflow_fail() -> ! {
     panic!("attempted to index slice from after maximum usize");
 }
 
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
-#[cold]
 #[track_caller]
 const fn slice_end_index_overflow_fail() -> ! {
     panic!("attempted to index slice up to maximum usize");
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 0660e03c1a8..f357d505fe8 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -510,8 +510,9 @@ impl File {
     /// # Errors
     ///
     /// This function will return an error if the file is not opened for writing.
-    /// Also, std::io::ErrorKind::InvalidInput will be returned if the desired
-    /// length would cause an overflow due to the implementation specifics.
+    /// Also, [`std::io::ErrorKind::InvalidInput`](crate::io::ErrorKind::InvalidInput)
+    /// will be returned if the desired length would cause an overflow due to
+    /// the implementation specifics.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index d4976a469cc..1039835bbbd 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -594,8 +594,8 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
 // lang item for CTFE panic support
 // never inline unless panic_immediate_abort to avoid code
 // bloat at the call sites as much as possible
-#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
-#[cold]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
 #[rustc_do_not_const_check] // hooked by const-eval
 pub const fn begin_panic<M: Any + Send>(msg: M) -> ! {
diff --git a/library/test/src/cli.rs b/library/test/src/cli.rs
index 8be32183fe7..524658bce13 100644
--- a/library/test/src/cli.rs
+++ b/library/test/src/cli.rs
@@ -26,6 +26,10 @@ pub struct TestOpts {
     pub test_threads: Option<usize>,
     pub skip: Vec<String>,
     pub time_options: Option<TestTimeOptions>,
+    /// Stop at first failing test.
+    /// May run a few more tests due to threading, but will
+    /// abort as soon as possible.
+    pub fail_fast: bool,
     pub options: Options,
 }
 
@@ -296,6 +300,7 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes {
         skip,
         time_options,
         options,
+        fail_fast: false,
     };
 
     Ok(test_opts)
diff --git a/library/test/src/console.rs b/library/test/src/console.rs
index 8cb88016b23..a3c39f71f08 100644
--- a/library/test/src/console.rs
+++ b/library/test/src/console.rs
@@ -293,7 +293,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
     run_tests(opts, tests, |x| on_test_event(&x, &mut st, &mut *out))?;
     st.exec_time = start_time.map(|t| TestSuiteExecTime(t.elapsed()));
 
-    assert!(st.current_test_count() == st.total);
+    assert!(opts.fail_fast || st.current_test_count() == st.total);
 
     out.write_run_finish(&st)
 }
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index 27320e8dbc5..256c9e8d141 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -384,8 +384,17 @@ where
             let mut completed_test = rx.recv().unwrap();
             RunningTest { join_handle }.join(&mut completed_test);
 
+            let fail_fast = match completed_test.result {
+                TrIgnored | TrOk | TrBench(_) => false,
+                TrFailed | TrFailedMsg(_) | TrTimedFail => opts.fail_fast,
+            };
+
             let event = TestEvent::TeResult(completed_test);
             notify_about_test_event(event)?;
+
+            if fail_fast {
+                return Ok(());
+            }
         }
     } else {
         while pending > 0 || !remaining.is_empty() {
@@ -431,9 +440,20 @@ where
             let running_test = running_tests.remove(&completed_test.id).unwrap();
             running_test.join(&mut completed_test);
 
+            let fail_fast = match completed_test.result {
+                TrIgnored | TrOk | TrBench(_) => false,
+                TrFailed | TrFailedMsg(_) | TrTimedFail => opts.fail_fast,
+            };
+
             let event = TestEvent::TeResult(completed_test);
             notify_about_test_event(event)?;
             pending -= 1;
+
+            if fail_fast {
+                // Prevent remaining test threads from panicking
+                std::mem::forget(rx);
+                return Ok(());
+            }
         }
     }
 
diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs
index 7b2e6707f9d..3a0260f86cf 100644
--- a/library/test/src/tests.rs
+++ b/library/test/src/tests.rs
@@ -51,6 +51,7 @@ impl TestOpts {
             skip: vec![],
             time_options: None,
             options: Options::new(),
+            fail_fast: false,
         }
     }
 }
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index fe8a028dfd3..efe8ae3169f 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -12,15 +12,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "ansi_term"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
-dependencies = [
- "winapi",
-]
-
-[[package]]
 name = "autocfg"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -108,18 +99,18 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
 
 [[package]]
 name = "cpufeatures"
-version = "0.2.2"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
+checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
 dependencies = [
  "libc",
 ]
 
 [[package]]
 name = "crossbeam-channel"
-version = "0.5.4"
+version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
+checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
 dependencies = [
  "cfg-if",
  "crossbeam-utils",
@@ -127,9 +118,9 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-deque"
-version = "0.8.1"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
+checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
 dependencies = [
  "cfg-if",
  "crossbeam-epoch",
@@ -138,26 +129,24 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-epoch"
-version = "0.9.8"
+version = "0.9.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
+checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
 dependencies = [
  "autocfg",
  "cfg-if",
  "crossbeam-utils",
- "lazy_static",
  "memoffset",
  "scopeguard",
 ]
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.8"
+version = "0.8.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
+checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
 dependencies = [
  "cfg-if",
- "lazy_static",
 ]
 
 [[package]]
@@ -379,9 +368,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
 
 [[package]]
 name = "memoffset"
-version = "0.6.5"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
+checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
 dependencies = [
  "autocfg",
 ]
@@ -447,14 +436,14 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
 
 [[package]]
 name = "pretty_assertions"
-version = "0.7.2"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cab0e7c02cf376875e9335e0ba1da535775beb5450d21e1dffca068818ed98b"
+checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755"
 dependencies = [
- "ansi_term",
  "ctor",
  "diff",
  "output_vt100",
+ "yansi",
 ]
 
 [[package]]
@@ -477,11 +466,10 @@ dependencies = [
 
 [[package]]
 name = "rayon"
-version = "1.5.3"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
+checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b"
 dependencies = [
- "autocfg",
  "crossbeam-deque",
  "either",
  "rayon-core",
@@ -489,9 +477,9 @@ dependencies = [
 
 [[package]]
 name = "rayon-core"
-version = "1.9.3"
+version = "1.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
+checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
 dependencies = [
  "crossbeam-channel",
  "crossbeam-deque",
@@ -803,3 +791,9 @@ checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c"
 dependencies = [
  "lzma-sys",
 ]
+
+[[package]]
+name = "yansi"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 8751a71caf1..ccc7ec1fce9 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -72,7 +72,7 @@ features = [
 ]
 
 [dev-dependencies]
-pretty_assertions = "0.7"
+pretty_assertions = "1.2"
 
 [features]
 build-metrics = ["sysinfo"]
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index a3d1893afbb..d69bced0b28 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -647,10 +647,23 @@ impl Build {
         if !update(true).status().map_or(false, |status| status.success()) {
             self.run(&mut update(false));
         }
-        self.run(Command::new("git").args(&["stash", "push"]).current_dir(&absolute_path));
+
+        // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error).
+        let has_local_modifications = !self.try_run(
+            Command::new("git")
+                .args(&["diff-index", "--quiet", "HEAD"])
+                .current_dir(&absolute_path),
+        );
+        if has_local_modifications {
+            self.run(Command::new("git").args(&["stash", "push"]).current_dir(&absolute_path));
+        }
+
         self.run(Command::new("git").args(&["reset", "-q", "--hard"]).current_dir(&absolute_path));
         self.run(Command::new("git").args(&["clean", "-qdfx"]).current_dir(&absolute_path));
-        self.run(Command::new("git").args(&["stash", "pop"]).current_dir(absolute_path));
+
+        if has_local_modifications {
+            self.run(Command::new("git").args(&["stash", "pop"]).current_dir(absolute_path));
+        }
     }
 
     /// If any submodule has been initialized already, sync it unconditionally.
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 10de2e8d5ea..75e44fe4987 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -77,7 +77,7 @@ x--expand-yaml-anchors--remove:
     <<: *base-job
 
   - &job-macos-xl
-    os: macos-latest  # We don't have an XL builder for this
+    os: macos-12-xl
     <<: *base-job
 
   - &job-windows-xl
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 1e7b4fe15b6..0271c27b4f5 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -32,7 +32,7 @@ features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"]
 rayon = "1.5.1"
 
 [dev-dependencies]
-expect-test = "1.0"
+expect-test = "1.4.0"
 
 [features]
 jemalloc = []
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 80909919ba2..2a2a9470d25 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -12,7 +12,7 @@ pub(crate) mod utils;
 
 use rustc_ast as ast;
 use rustc_attr as attr;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
@@ -598,47 +598,105 @@ pub(crate) fn clean_generics<'tcx>(
         })
         .collect::<Vec<_>>();
 
+    let mut bound_predicates = FxIndexMap::default();
+    let mut region_predicates = FxIndexMap::default();
+    let mut eq_predicates = ThinVec::default();
+    for pred in gens.predicates.iter().filter_map(|x| clean_where_predicate(x, cx)) {
+        match pred {
+            WherePredicate::BoundPredicate { ty, bounds, bound_params } => {
+                match bound_predicates.entry(ty) {
+                    IndexEntry::Vacant(v) => {
+                        v.insert((bounds, bound_params));
+                    }
+                    IndexEntry::Occupied(mut o) => {
+                        // we merge both bounds.
+                        for bound in bounds {
+                            if !o.get().0.contains(&bound) {
+                                o.get_mut().0.push(bound);
+                            }
+                        }
+                        for bound_param in bound_params {
+                            if !o.get().1.contains(&bound_param) {
+                                o.get_mut().1.push(bound_param);
+                            }
+                        }
+                    }
+                }
+            }
+            WherePredicate::RegionPredicate { lifetime, bounds } => {
+                match region_predicates.entry(lifetime) {
+                    IndexEntry::Vacant(v) => {
+                        v.insert(bounds);
+                    }
+                    IndexEntry::Occupied(mut o) => {
+                        // we merge both bounds.
+                        for bound in bounds {
+                            if !o.get().contains(&bound) {
+                                o.get_mut().push(bound);
+                            }
+                        }
+                    }
+                }
+            }
+            WherePredicate::EqPredicate { lhs, rhs, bound_params } => {
+                eq_predicates.push(WherePredicate::EqPredicate { lhs, rhs, bound_params });
+            }
+        }
+    }
+
     let mut params = ThinVec::with_capacity(gens.params.len());
+    // In this loop, we gather the generic parameters (`<'a, B: 'a>`) and check if they have
+    // bounds in the where predicates. If so, we move their bounds into the where predicates
+    // while also preventing duplicates.
     for p in gens.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) {
-        let p = clean_generic_param(cx, Some(gens), p);
+        let mut p = clean_generic_param(cx, Some(gens), p);
+        match &mut p.kind {
+            GenericParamDefKind::Lifetime { ref mut outlives } => {
+                if let Some(region_pred) = region_predicates.get_mut(&Lifetime(p.name)) {
+                    // We merge bounds in the `where` clause.
+                    for outlive in outlives.drain(..) {
+                        let outlive = GenericBound::Outlives(outlive);
+                        if !region_pred.contains(&outlive) {
+                            region_pred.push(outlive);
+                        }
+                    }
+                }
+            }
+            GenericParamDefKind::Type { bounds, synthetic: false, .. } => {
+                if let Some(bound_pred) = bound_predicates.get_mut(&Type::Generic(p.name)) {
+                    // We merge bounds in the `where` clause.
+                    for bound in bounds.drain(..) {
+                        if !bound_pred.0.contains(&bound) {
+                            bound_pred.0.push(bound);
+                        }
+                    }
+                }
+            }
+            GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
+                // nothing to do here.
+            }
+        }
         params.push(p);
     }
     params.extend(impl_trait_params);
 
-    let mut generics = Generics {
+    Generics {
         params,
-        where_predicates: gens
-            .predicates
-            .iter()
-            .filter_map(|x| clean_where_predicate(x, cx))
+        where_predicates: bound_predicates
+            .into_iter()
+            .map(|(ty, (bounds, bound_params))| WherePredicate::BoundPredicate {
+                ty,
+                bounds,
+                bound_params,
+            })
+            .chain(
+                region_predicates
+                    .into_iter()
+                    .map(|(lifetime, bounds)| WherePredicate::RegionPredicate { lifetime, bounds }),
+            )
+            .chain(eq_predicates.into_iter())
             .collect(),
-    };
-
-    // Some duplicates are generated for ?Sized bounds between type params and where
-    // predicates. The point in here is to move the bounds definitions from type params
-    // to where predicates when such cases occur.
-    for where_pred in &mut generics.where_predicates {
-        match *where_pred {
-            WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds, .. } => {
-                if bounds.is_empty() {
-                    for param in &mut generics.params {
-                        match param.kind {
-                            GenericParamDefKind::Lifetime { .. } => {}
-                            GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => {
-                                if &param.name == name {
-                                    mem::swap(bounds, ty_bounds);
-                                    break;
-                                }
-                            }
-                            GenericParamDefKind::Const { .. } => {}
-                        }
-                    }
-                }
-            }
-            _ => continue,
-        }
     }
-    generics
 }
 
 fn clean_ty_generics<'tcx>(
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 6bff2cd2f1a..f44797fe55f 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -908,6 +908,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
 
 .popover {
 	position: absolute;
+	top: 100%;
 	right: 0;
 	z-index: 2;
 	display: block;
@@ -1357,22 +1358,24 @@ a.test-arrow:hover {
 }
 #settings-menu, #help-button {
 	margin-left: 4px;
-	outline: none;
+	display: flex;
 }
 
 #settings-menu > a, #help-button > a, #copy-path {
 	width: 33px;
-	line-height: 1.5;
 }
 
 #settings-menu > a, #help-button > a {
-	padding: 5px;
-	height: 100%;
-	display: block;
+	display: flex;
+	align-items: center;
+	justify-content: center;
 	background-color: var(--button-background-color);
 	border: 1px solid var(--border-color);
 	border-radius: 2px;
 	color: var(--settings-button-color);
+	/* Rare exception to specifying font sizes in rem. Since this is acting
+	   as an icon, it's okay to specify their sizes in pixels. */
+	font-size: 20px;
 }
 
 #settings-menu > a:hover, #settings-menu > a:focus,
@@ -1408,14 +1411,6 @@ a.test-arrow:hover {
 	animation: rotating 2s linear infinite;
 }
 
-#help-button > a {
-	text-align: center;
-	/* Rare exception to specifying font sizes in rem. Since this is acting
-	   as an icon, it's okay to specify their sizes in pixels. */
-	font-size: 20px;
-	padding-top: 2px;
-}
-
 kbd {
 	display: inline-block;
 	padding: 3px 5px;
@@ -1590,17 +1585,11 @@ details.rustdoc-toggle[open] > summary.hideme > span {
 	display: none;
 }
 
-details.rustdoc-toggle[open] > summary::before,
-details.rustdoc-toggle[open] > summary.hideme::before {
+details.rustdoc-toggle[open] > summary::before {
 	background: url("toggle-minus-31bbd6e4c77f5c96.svg") no-repeat top left;
-	width: 16px;
-	height: 16px;
-	display: inline-block;
-	content: "";
 }
 
-details.rustdoc-toggle[open] > summary::after,
-details.rustdoc-toggle[open] > summary.hideme::after {
+details.rustdoc-toggle[open] > summary::after {
 	content: "Collapse";
 }
 
@@ -1658,10 +1647,6 @@ in storage.js
 		content: "Since ";
 	}
 
-	#copy-path {
-		display: none;
-	}
-
 	/* Hide the logo and item name from the sidebar. Those are displayed
 	   in the mobile-topbar instead. */
 	.sidebar .sidebar-logo,
@@ -1795,8 +1780,8 @@ in storage.js
 		border-bottom: 1px solid;
 	}
 
-	/* We don't display the help button on mobile devices. */
-	#help-button {
+	/* We don't display these buttons on mobile devices. */
+	#copy-path, #help-button {
 		display: none;
 	}
 
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 83be1a16eb2..1196f944faa 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -99,53 +99,6 @@ impl<'tcx> JsonRenderer<'tcx> {
             })
             .unwrap_or_default()
     }
-
-    fn get_trait_items(&mut self) -> Vec<(types::Id, types::Item)> {
-        debug!("Adding foreign trait items");
-        Rc::clone(&self.cache)
-            .traits
-            .iter()
-            .filter_map(|(&id, trait_item)| {
-                // only need to synthesize items for external traits
-                if !id.is_local() {
-                    for item in &trait_item.items {
-                        trace!("Adding subitem to {id:?}: {:?}", item.item_id);
-                        self.item(item.clone()).unwrap();
-                    }
-                    let item_id = from_item_id(id.into(), self.tcx);
-                    Some((
-                        item_id.clone(),
-                        types::Item {
-                            id: item_id,
-                            crate_id: id.krate.as_u32(),
-                            name: self
-                                .cache
-                                .paths
-                                .get(&id)
-                                .unwrap_or_else(|| {
-                                    self.cache
-                                        .external_paths
-                                        .get(&id)
-                                        .expect("Trait should either be in local or external paths")
-                                })
-                                .0
-                                .last()
-                                .map(|s| s.to_string()),
-                            visibility: types::Visibility::Public,
-                            inner: types::ItemEnum::Trait(trait_item.clone().into_tcx(self.tcx)),
-                            span: None,
-                            docs: Default::default(),
-                            links: Default::default(),
-                            attrs: Default::default(),
-                            deprecation: Default::default(),
-                        },
-                    ))
-                } else {
-                    None
-                }
-            })
-            .collect()
-    }
 }
 
 impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
@@ -276,11 +229,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
 
         let e = ExternalCrate { crate_num: LOCAL_CRATE };
 
-        // FIXME(adotinthevoid): Remove this, as it's not consistent with not
-        // inlining foreign items.
-        let foreign_trait_items = self.get_trait_items();
-        let mut index = (*self.index).clone().into_inner();
-        index.extend(foreign_trait_items);
+        let index = (*self.index).clone().into_inner();
 
         debug!("Constructing Output");
         // This needs to be the default HashMap for compatibility with the public interface for
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 1a84ec65047..6d34f484754 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -781,10 +781,7 @@ fn main_args(at_args: &[String]) -> MainResult {
         let sess = compiler.session();
 
         if sess.opts.describe_lints {
-            let mut lint_store = rustc_lint::new_lint_store(
-                sess.opts.unstable_opts.no_interleave_lints,
-                sess.enable_internal_lints(),
-            );
+            let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
             let registered_lints = if let Some(register_lints) = compiler.register_lints() {
                 register_lints(sess, &mut lint_store);
                 true
diff --git a/src/librustdoc/passes/bare_urls.rs b/src/librustdoc/passes/bare_urls.rs
deleted file mode 100644
index 7ff3ccef945..00000000000
--- a/src/librustdoc/passes/bare_urls.rs
+++ /dev/null
@@ -1,110 +0,0 @@
-//! Detects links that are not linkified, e.g., in Markdown such as `Go to https://example.com/.`
-//! Suggests wrapping the link with angle brackets: `Go to <https://example.com/>.` to linkify it.
-use super::Pass;
-use crate::clean::*;
-use crate::core::DocContext;
-use crate::html::markdown::main_body_opts;
-use crate::visit::DocVisitor;
-use core::ops::Range;
-use pulldown_cmark::{Event, Parser, Tag};
-use regex::Regex;
-use rustc_errors::Applicability;
-use std::mem;
-use std::sync::LazyLock;
-
-pub(crate) const CHECK_BARE_URLS: Pass = Pass {
-    name: "check-bare-urls",
-    run: check_bare_urls,
-    description: "detects URLs that are not hyperlinks",
-};
-
-static URL_REGEX: LazyLock<Regex> = LazyLock::new(|| {
-    Regex::new(concat!(
-        r"https?://",                          // url scheme
-        r"([-a-zA-Z0-9@:%._\+~#=]{2,256}\.)+", // one or more subdomains
-        r"[a-zA-Z]{2,63}",                     // root domain
-        r"\b([-a-zA-Z0-9@:%_\+.~#?&/=]*)"      // optional query or url fragments
-    ))
-    .expect("failed to build regex")
-});
-
-struct BareUrlsLinter<'a, 'tcx> {
-    cx: &'a mut DocContext<'tcx>,
-}
-
-impl<'a, 'tcx> BareUrlsLinter<'a, 'tcx> {
-    fn find_raw_urls(
-        &self,
-        text: &str,
-        range: Range<usize>,
-        f: &impl Fn(&DocContext<'_>, &str, &str, Range<usize>),
-    ) {
-        trace!("looking for raw urls in {}", text);
-        // For now, we only check "full" URLs (meaning, starting with "http://" or "https://").
-        for match_ in URL_REGEX.find_iter(text) {
-            let url = match_.as_str();
-            let url_range = match_.range();
-            f(
-                self.cx,
-                "this URL is not a hyperlink",
-                url,
-                Range { start: range.start + url_range.start, end: range.start + url_range.end },
-            );
-        }
-    }
-}
-
-pub(crate) fn check_bare_urls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
-    BareUrlsLinter { cx }.visit_crate(&krate);
-    krate
-}
-
-impl<'a, 'tcx> DocVisitor for BareUrlsLinter<'a, 'tcx> {
-    fn visit_item(&mut self, item: &Item) {
-        let Some(hir_id) = DocContext::as_local_hir_id(self.cx.tcx, item.item_id)
-        else {
-            // If non-local, no need to check anything.
-            return;
-        };
-        let dox = item.attrs.collapsed_doc_value().unwrap_or_default();
-        if !dox.is_empty() {
-            let report_diag = |cx: &DocContext<'_>, msg: &str, url: &str, range: Range<usize>| {
-                let sp = super::source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs)
-                    .unwrap_or_else(|| item.attr_span(cx.tcx));
-                cx.tcx.struct_span_lint_hir(crate::lint::BARE_URLS, hir_id, sp, msg, |lint| {
-                    lint.note("bare URLs are not automatically turned into clickable links")
-                        .span_suggestion(
-                            sp,
-                            "use an automatic link instead",
-                            format!("<{}>", url),
-                            Applicability::MachineApplicable,
-                        )
-                });
-            };
-
-            let mut p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter();
-
-            while let Some((event, range)) = p.next() {
-                match event {
-                    Event::Text(s) => self.find_raw_urls(&s, range, &report_diag),
-                    // We don't want to check the text inside code blocks or links.
-                    Event::Start(tag @ (Tag::CodeBlock(_) | Tag::Link(..))) => {
-                        while let Some((event, _)) = p.next() {
-                            match event {
-                                Event::End(end)
-                                    if mem::discriminant(&end) == mem::discriminant(&tag) =>
-                                {
-                                    break;
-                                }
-                                _ => {}
-                            }
-                        }
-                    }
-                    _ => {}
-                }
-            }
-        }
-
-        self.visit_item_recur(item)
-    }
-}
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
deleted file mode 100644
index 2e651b53874..00000000000
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ /dev/null
@@ -1,209 +0,0 @@
-//! Validates syntax inside Rust code blocks (\`\`\`rust).
-use rustc_data_structures::sync::{Lock, Lrc};
-use rustc_errors::{
-    emitter::Emitter,
-    translation::{to_fluent_args, Translate},
-    Applicability, Diagnostic, Handler, LazyFallbackBundle,
-};
-use rustc_parse::parse_stream_from_source_str;
-use rustc_session::parse::ParseSess;
-use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId};
-use rustc_span::source_map::{FilePathMapping, SourceMap};
-use rustc_span::{FileName, InnerSpan, DUMMY_SP};
-
-use crate::clean;
-use crate::core::DocContext;
-use crate::html::markdown::{self, RustCodeBlock};
-use crate::passes::Pass;
-use crate::visit::DocVisitor;
-
-pub(crate) const CHECK_CODE_BLOCK_SYNTAX: Pass = Pass {
-    name: "check-code-block-syntax",
-    run: check_code_block_syntax,
-    description: "validates syntax inside Rust code blocks",
-};
-
-pub(crate) fn check_code_block_syntax(
-    krate: clean::Crate,
-    cx: &mut DocContext<'_>,
-) -> clean::Crate {
-    SyntaxChecker { cx }.visit_crate(&krate);
-    krate
-}
-
-struct SyntaxChecker<'a, 'tcx> {
-    cx: &'a DocContext<'tcx>,
-}
-
-impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
-    fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeBlock) {
-        let buffer = Lrc::new(Lock::new(Buffer::default()));
-        let fallback_bundle =
-            rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
-        let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle };
-
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let handler = Handler::with_emitter(false, None, Box::new(emitter));
-        let source = dox[code_block.code].to_owned();
-        let sess = ParseSess::with_span_handler(handler, sm);
-
-        let edition = code_block.lang_string.edition.unwrap_or_else(|| self.cx.tcx.sess.edition());
-        let expn_data = ExpnData::default(
-            ExpnKind::AstPass(AstPass::TestHarness),
-            DUMMY_SP,
-            edition,
-            None,
-            None,
-        );
-        let expn_id =
-            self.cx.tcx.with_stable_hashing_context(|hcx| LocalExpnId::fresh(expn_data, hcx));
-        let span = DUMMY_SP.fresh_expansion(expn_id);
-
-        let is_empty = rustc_driver::catch_fatal_errors(|| {
-            parse_stream_from_source_str(
-                FileName::Custom(String::from("doctest")),
-                source,
-                &sess,
-                Some(span),
-            )
-            .is_empty()
-        })
-        .unwrap_or(false);
-        let buffer = buffer.borrow();
-
-        if !buffer.has_errors && !is_empty {
-            // No errors in a non-empty program.
-            return;
-        }
-
-        let Some(local_id) = item.item_id.as_def_id().and_then(|x| x.as_local())
-        else {
-            // We don't need to check the syntax for other crates so returning
-            // without doing anything should not be a problem.
-            return;
-        };
-
-        let hir_id = self.cx.tcx.hir().local_def_id_to_hir_id(local_id);
-        let empty_block = code_block.lang_string == Default::default() && code_block.is_fenced;
-        let is_ignore = code_block.lang_string.ignore != markdown::Ignore::None;
-
-        // The span and whether it is precise or not.
-        let (sp, precise_span) = match super::source_span_for_markdown_range(
-            self.cx.tcx,
-            dox,
-            &code_block.range,
-            &item.attrs,
-        ) {
-            Some(sp) => (sp, true),
-            None => (item.attr_span(self.cx.tcx), false),
-        };
-
-        let msg = if buffer.has_errors {
-            "could not parse code block as Rust code"
-        } else {
-            "Rust code block is empty"
-        };
-
-        // Finally build and emit the completed diagnostic.
-        // All points of divergence have been handled earlier so this can be
-        // done the same way whether the span is precise or not.
-        self.cx.tcx.struct_span_lint_hir(
-            crate::lint::INVALID_RUST_CODEBLOCKS,
-            hir_id,
-            sp,
-            msg,
-            |lint| {
-                let explanation = if is_ignore {
-                    "`ignore` code blocks require valid Rust code for syntax highlighting; \
-                    mark blocks that do not contain Rust code as text"
-                } else {
-                    "mark blocks that do not contain Rust code as text"
-                };
-
-                if precise_span {
-                    if is_ignore {
-                        // giving an accurate suggestion is hard because `ignore` might not have come first in the list.
-                        // just give a `help` instead.
-                        lint.span_help(
-                            sp.from_inner(InnerSpan::new(0, 3)),
-                            &format!("{}: ```text", explanation),
-                        );
-                    } else if empty_block {
-                        lint.span_suggestion(
-                            sp.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(),
-                            explanation,
-                            "text",
-                            Applicability::MachineApplicable,
-                        );
-                    }
-                } else if empty_block || is_ignore {
-                    lint.help(&format!("{}: ```text", explanation));
-                }
-
-                // FIXME(#67563): Provide more context for these errors by displaying the spans inline.
-                for message in buffer.messages.iter() {
-                    lint.note(message);
-                }
-
-                lint
-            },
-        );
-    }
-}
-
-impl<'a, 'tcx> DocVisitor for SyntaxChecker<'a, 'tcx> {
-    fn visit_item(&mut self, item: &clean::Item) {
-        if let Some(dox) = &item.attrs.collapsed_doc_value() {
-            let sp = item.attr_span(self.cx.tcx);
-            let extra = crate::html::markdown::ExtraInfo::new_did(
-                self.cx.tcx,
-                item.item_id.expect_def_id(),
-                sp,
-            );
-            for code_block in markdown::rust_code_blocks(dox, &extra) {
-                self.check_rust_syntax(item, dox, code_block);
-            }
-        }
-
-        self.visit_item_recur(item)
-    }
-}
-
-#[derive(Default)]
-struct Buffer {
-    messages: Vec<String>,
-    has_errors: bool,
-}
-
-struct BufferEmitter {
-    buffer: Lrc<Lock<Buffer>>,
-    fallback_bundle: LazyFallbackBundle,
-}
-
-impl Translate for BufferEmitter {
-    fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
-        None
-    }
-
-    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
-        &**self.fallback_bundle
-    }
-}
-
-impl Emitter for BufferEmitter {
-    fn emit_diagnostic(&mut self, diag: &Diagnostic) {
-        let mut buffer = self.buffer.borrow_mut();
-
-        let fluent_args = to_fluent_args(diag.args());
-        let translated_main_message = self.translate_message(&diag.message[0].0, &fluent_args);
-
-        buffer.messages.push(format!("error from rustc: {}", translated_main_message));
-        if diag.is_error() {
-            buffer.has_errors = true;
-        }
-    }
-
-    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
-        None
-    }
-}
diff --git a/src/librustdoc/passes/lint.rs b/src/librustdoc/passes/lint.rs
new file mode 100644
index 00000000000..97031c4f028
--- /dev/null
+++ b/src/librustdoc/passes/lint.rs
@@ -0,0 +1,33 @@
+//! Runs several rustdoc lints, consolidating them into a single pass for
+//! efficiency and simplicity.
+
+mod bare_urls;
+mod check_code_block_syntax;
+mod html_tags;
+
+use super::Pass;
+use crate::clean::*;
+use crate::core::DocContext;
+use crate::visit::DocVisitor;
+
+pub(crate) const RUN_LINTS: Pass =
+    Pass { name: "run-lints", run: run_lints, description: "runs some of rustdoc's lints" };
+
+struct Linter<'a, 'tcx> {
+    cx: &'a mut DocContext<'tcx>,
+}
+
+pub(crate) fn run_lints(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
+    Linter { cx }.visit_crate(&krate);
+    krate
+}
+
+impl<'a, 'tcx> DocVisitor for Linter<'a, 'tcx> {
+    fn visit_item(&mut self, item: &Item) {
+        bare_urls::visit_item(self.cx, item);
+        check_code_block_syntax::visit_item(self.cx, item);
+        html_tags::visit_item(self.cx, item);
+
+        self.visit_item_recur(item)
+    }
+}
diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs
new file mode 100644
index 00000000000..423230cfe38
--- /dev/null
+++ b/src/librustdoc/passes/lint/bare_urls.rs
@@ -0,0 +1,89 @@
+//! Detects links that are not linkified, e.g., in Markdown such as `Go to https://example.com/.`
+//! Suggests wrapping the link with angle brackets: `Go to <https://example.com/>.` to linkify it.
+
+use crate::clean::*;
+use crate::core::DocContext;
+use crate::html::markdown::main_body_opts;
+use crate::passes::source_span_for_markdown_range;
+use core::ops::Range;
+use pulldown_cmark::{Event, Parser, Tag};
+use regex::Regex;
+use rustc_errors::Applicability;
+use std::mem;
+use std::sync::LazyLock;
+
+pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) {
+    let Some(hir_id) = DocContext::as_local_hir_id(cx.tcx, item.item_id)
+        else {
+            // If non-local, no need to check anything.
+            return;
+        };
+    let dox = item.attrs.collapsed_doc_value().unwrap_or_default();
+    if !dox.is_empty() {
+        let report_diag = |cx: &DocContext<'_>, msg: &str, url: &str, range: Range<usize>| {
+            let sp = source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs)
+                .unwrap_or_else(|| item.attr_span(cx.tcx));
+            cx.tcx.struct_span_lint_hir(crate::lint::BARE_URLS, hir_id, sp, msg, |lint| {
+                lint.note("bare URLs are not automatically turned into clickable links")
+                    .span_suggestion(
+                        sp,
+                        "use an automatic link instead",
+                        format!("<{}>", url),
+                        Applicability::MachineApplicable,
+                    )
+            });
+        };
+
+        let mut p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter();
+
+        while let Some((event, range)) = p.next() {
+            match event {
+                Event::Text(s) => find_raw_urls(cx, &s, range, &report_diag),
+                // We don't want to check the text inside code blocks or links.
+                Event::Start(tag @ (Tag::CodeBlock(_) | Tag::Link(..))) => {
+                    while let Some((event, _)) = p.next() {
+                        match event {
+                            Event::End(end)
+                                if mem::discriminant(&end) == mem::discriminant(&tag) =>
+                            {
+                                break;
+                            }
+                            _ => {}
+                        }
+                    }
+                }
+                _ => {}
+            }
+        }
+    }
+}
+
+static URL_REGEX: LazyLock<Regex> = LazyLock::new(|| {
+    Regex::new(concat!(
+        r"https?://",                          // url scheme
+        r"([-a-zA-Z0-9@:%._\+~#=]{2,256}\.)+", // one or more subdomains
+        r"[a-zA-Z]{2,63}",                     // root domain
+        r"\b([-a-zA-Z0-9@:%_\+.~#?&/=]*)"      // optional query or url fragments
+    ))
+    .expect("failed to build regex")
+});
+
+fn find_raw_urls(
+    cx: &DocContext<'_>,
+    text: &str,
+    range: Range<usize>,
+    f: &impl Fn(&DocContext<'_>, &str, &str, Range<usize>),
+) {
+    trace!("looking for raw urls in {}", text);
+    // For now, we only check "full" URLs (meaning, starting with "http://" or "https://").
+    for match_ in URL_REGEX.find_iter(text) {
+        let url = match_.as_str();
+        let url_range = match_.range();
+        f(
+            cx,
+            "this URL is not a hyperlink",
+            url,
+            Range { start: range.start + url_range.start, end: range.start + url_range.end },
+        );
+    }
+}
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
new file mode 100644
index 00000000000..5aa4f238b2d
--- /dev/null
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -0,0 +1,170 @@
+//! Validates syntax inside Rust code blocks (\`\`\`rust).
+use rustc_data_structures::sync::{Lock, Lrc};
+use rustc_errors::{
+    emitter::Emitter,
+    translation::{to_fluent_args, Translate},
+    Applicability, Diagnostic, Handler, LazyFallbackBundle,
+};
+use rustc_parse::parse_stream_from_source_str;
+use rustc_session::parse::ParseSess;
+use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId};
+use rustc_span::source_map::{FilePathMapping, SourceMap};
+use rustc_span::{FileName, InnerSpan, DUMMY_SP};
+
+use crate::clean;
+use crate::core::DocContext;
+use crate::html::markdown::{self, RustCodeBlock};
+use crate::passes::source_span_for_markdown_range;
+
+pub(crate) fn visit_item(cx: &DocContext<'_>, item: &clean::Item) {
+    if let Some(dox) = &item.attrs.collapsed_doc_value() {
+        let sp = item.attr_span(cx.tcx);
+        let extra =
+            crate::html::markdown::ExtraInfo::new_did(cx.tcx, item.item_id.expect_def_id(), sp);
+        for code_block in markdown::rust_code_blocks(dox, &extra) {
+            check_rust_syntax(cx, item, dox, code_block);
+        }
+    }
+}
+
+fn check_rust_syntax(
+    cx: &DocContext<'_>,
+    item: &clean::Item,
+    dox: &str,
+    code_block: RustCodeBlock,
+) {
+    let buffer = Lrc::new(Lock::new(Buffer::default()));
+    let fallback_bundle =
+        rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+    let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle };
+
+    let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+    let handler = Handler::with_emitter(false, None, Box::new(emitter));
+    let source = dox[code_block.code].to_owned();
+    let sess = ParseSess::with_span_handler(handler, sm);
+
+    let edition = code_block.lang_string.edition.unwrap_or_else(|| cx.tcx.sess.edition());
+    let expn_data =
+        ExpnData::default(ExpnKind::AstPass(AstPass::TestHarness), DUMMY_SP, edition, None, None);
+    let expn_id = cx.tcx.with_stable_hashing_context(|hcx| LocalExpnId::fresh(expn_data, hcx));
+    let span = DUMMY_SP.fresh_expansion(expn_id);
+
+    let is_empty = rustc_driver::catch_fatal_errors(|| {
+        parse_stream_from_source_str(
+            FileName::Custom(String::from("doctest")),
+            source,
+            &sess,
+            Some(span),
+        )
+        .is_empty()
+    })
+    .unwrap_or(false);
+    let buffer = buffer.borrow();
+
+    if !buffer.has_errors && !is_empty {
+        // No errors in a non-empty program.
+        return;
+    }
+
+    let Some(local_id) = item.item_id.as_def_id().and_then(|x| x.as_local())
+        else {
+            // We don't need to check the syntax for other crates so returning
+            // without doing anything should not be a problem.
+            return;
+        };
+
+    let hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_id);
+    let empty_block = code_block.lang_string == Default::default() && code_block.is_fenced;
+    let is_ignore = code_block.lang_string.ignore != markdown::Ignore::None;
+
+    // The span and whether it is precise or not.
+    let (sp, precise_span) =
+        match source_span_for_markdown_range(cx.tcx, dox, &code_block.range, &item.attrs) {
+            Some(sp) => (sp, true),
+            None => (item.attr_span(cx.tcx), false),
+        };
+
+    let msg = if buffer.has_errors {
+        "could not parse code block as Rust code"
+    } else {
+        "Rust code block is empty"
+    };
+
+    // Finally build and emit the completed diagnostic.
+    // All points of divergence have been handled earlier so this can be
+    // done the same way whether the span is precise or not.
+    cx.tcx.struct_span_lint_hir(crate::lint::INVALID_RUST_CODEBLOCKS, hir_id, sp, msg, |lint| {
+        let explanation = if is_ignore {
+            "`ignore` code blocks require valid Rust code for syntax highlighting; \
+                    mark blocks that do not contain Rust code as text"
+        } else {
+            "mark blocks that do not contain Rust code as text"
+        };
+
+        if precise_span {
+            if is_ignore {
+                // giving an accurate suggestion is hard because `ignore` might not have come first in the list.
+                // just give a `help` instead.
+                lint.span_help(
+                    sp.from_inner(InnerSpan::new(0, 3)),
+                    &format!("{}: ```text", explanation),
+                );
+            } else if empty_block {
+                lint.span_suggestion(
+                    sp.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(),
+                    explanation,
+                    "text",
+                    Applicability::MachineApplicable,
+                );
+            }
+        } else if empty_block || is_ignore {
+            lint.help(&format!("{}: ```text", explanation));
+        }
+
+        // FIXME(#67563): Provide more context for these errors by displaying the spans inline.
+        for message in buffer.messages.iter() {
+            lint.note(message);
+        }
+
+        lint
+    });
+}
+
+#[derive(Default)]
+struct Buffer {
+    messages: Vec<String>,
+    has_errors: bool,
+}
+
+struct BufferEmitter {
+    buffer: Lrc<Lock<Buffer>>,
+    fallback_bundle: LazyFallbackBundle,
+}
+
+impl Translate for BufferEmitter {
+    fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
+        None
+    }
+
+    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+        &**self.fallback_bundle
+    }
+}
+
+impl Emitter for BufferEmitter {
+    fn emit_diagnostic(&mut self, diag: &Diagnostic) {
+        let mut buffer = self.buffer.borrow_mut();
+
+        let fluent_args = to_fluent_args(diag.args());
+        let translated_main_message = self.translate_message(&diag.message[0].0, &fluent_args);
+
+        buffer.messages.push(format!("error from rustc: {}", translated_main_message));
+        if diag.is_error() {
+            buffer.has_errors = true;
+        }
+    }
+
+    fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+        None
+    }
+}
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs
index a89ed7c7ed4..070c0aab586 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/lint/html_tags.rs
@@ -1,9 +1,8 @@
 //! Detects invalid HTML (like an unclosed `<span>`) in doc comments.
-use super::Pass;
 use crate::clean::*;
 use crate::core::DocContext;
 use crate::html::markdown::main_body_opts;
-use crate::visit::DocVisitor;
+use crate::passes::source_span_for_markdown_range;
 
 use pulldown_cmark::{BrokenLink, Event, LinkType, Parser, Tag};
 
@@ -11,20 +10,150 @@ use std::iter::Peekable;
 use std::ops::Range;
 use std::str::CharIndices;
 
-pub(crate) const CHECK_INVALID_HTML_TAGS: Pass = Pass {
-    name: "check-invalid-html-tags",
-    run: check_invalid_html_tags,
-    description: "detects invalid HTML tags in doc comments",
-};
+pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
+    let tcx = cx.tcx;
+    let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id)
+    // If non-local, no need to check anything.
+    else { return };
+    let dox = item.attrs.collapsed_doc_value().unwrap_or_default();
+    if !dox.is_empty() {
+        let report_diag = |msg: &str, range: &Range<usize>, is_open_tag: bool| {
+            let sp = match source_span_for_markdown_range(tcx, &dox, range, &item.attrs) {
+                Some(sp) => sp,
+                None => item.attr_span(tcx),
+            };
+            tcx.struct_span_lint_hir(crate::lint::INVALID_HTML_TAGS, hir_id, sp, msg, |lint| {
+                use rustc_lint_defs::Applicability;
+                // If a tag looks like `<this>`, it might actually be a generic.
+                // We don't try to detect stuff `<like, this>` because that's not valid HTML,
+                // and we don't try to detect stuff `<like this>` because that's not valid Rust.
+                let mut generics_end = range.end;
+                if let Some(Some(mut generics_start)) = (is_open_tag
+                    && dox[..generics_end].ends_with('>'))
+                .then(|| extract_path_backwards(&dox, range.start))
+                {
+                    while generics_start != 0
+                        && generics_end < dox.len()
+                        && dox.as_bytes()[generics_start - 1] == b'<'
+                        && dox.as_bytes()[generics_end] == b'>'
+                    {
+                        generics_end += 1;
+                        generics_start -= 1;
+                        if let Some(new_start) = extract_path_backwards(&dox, generics_start) {
+                            generics_start = new_start;
+                        }
+                        if let Some(new_end) = extract_path_forward(&dox, generics_end) {
+                            generics_end = new_end;
+                        }
+                    }
+                    if let Some(new_end) = extract_path_forward(&dox, generics_end) {
+                        generics_end = new_end;
+                    }
+                    let generics_sp = match source_span_for_markdown_range(
+                        tcx,
+                        &dox,
+                        &(generics_start..generics_end),
+                        &item.attrs,
+                    ) {
+                        Some(sp) => sp,
+                        None => item.attr_span(tcx),
+                    };
+                    // Sometimes, we only extract part of a path. For example, consider this:
+                    //
+                    //     <[u32] as IntoIter<u32>>::Item
+                    //                       ^^^^^ unclosed HTML tag `u32`
+                    //
+                    // We don't have any code for parsing fully-qualified trait paths.
+                    // In theory, we could add it, but doing it correctly would require
+                    // parsing the entire path grammar, which is problematic because of
+                    // overlap between the path grammar and Markdown.
+                    //
+                    // The example above shows that ambiguity. Is `[u32]` intended to be an
+                    // intra-doc link to the u32 primitive, or is it intended to be a slice?
+                    //
+                    // If the below conditional were removed, we would suggest this, which is
+                    // not what the user probably wants.
+                    //
+                    //     <[u32] as `IntoIter<u32>`>::Item
+                    //
+                    // We know that the user actually wants to wrap the whole thing in a code
+                    // block, but the only reason we know that is because `u32` does not, in
+                    // fact, implement IntoIter. If the example looks like this:
+                    //
+                    //     <[Vec<i32>] as IntoIter<i32>::Item
+                    //
+                    // The ideal fix would be significantly different.
+                    if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<')
+                        || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>')
+                    {
+                        return lint;
+                    }
+                    // multipart form is chosen here because ``Vec<i32>`` would be confusing.
+                    lint.multipart_suggestion(
+                        "try marking as source code",
+                        vec![
+                            (generics_sp.shrink_to_lo(), String::from("`")),
+                            (generics_sp.shrink_to_hi(), String::from("`")),
+                        ],
+                        Applicability::MaybeIncorrect,
+                    );
+                }
 
-struct InvalidHtmlTagsLinter<'a, 'tcx> {
-    cx: &'a mut DocContext<'tcx>,
-}
+                lint
+            });
+        };
+
+        let mut tags = Vec::new();
+        let mut is_in_comment = None;
+        let mut in_code_block = false;
+
+        let link_names = item.link_names(&cx.cache);
 
-pub(crate) fn check_invalid_html_tags(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
-    let mut coll = InvalidHtmlTagsLinter { cx };
-    coll.visit_crate(&krate);
-    krate
+        let mut replacer = |broken_link: BrokenLink<'_>| {
+            if let Some(link) =
+                link_names.iter().find(|link| *link.original_text == *broken_link.reference)
+            {
+                Some((link.href.as_str().into(), link.new_text.as_str().into()))
+            } else if matches!(
+                &broken_link.link_type,
+                LinkType::Reference | LinkType::ReferenceUnknown
+            ) {
+                // If the link is shaped [like][this], suppress any broken HTML in the [this] part.
+                // The `broken_intra_doc_links` will report typos in there anyway.
+                Some((
+                    broken_link.reference.to_string().into(),
+                    broken_link.reference.to_string().into(),
+                ))
+            } else {
+                None
+            }
+        };
+
+        let p = Parser::new_with_broken_link_callback(&dox, main_body_opts(), Some(&mut replacer))
+            .into_offset_iter();
+
+        for (event, range) in p {
+            match event {
+                Event::Start(Tag::CodeBlock(_)) => in_code_block = true,
+                Event::Html(text) if !in_code_block => {
+                    extract_tags(&mut tags, &text, range, &mut is_in_comment, &report_diag)
+                }
+                Event::End(Tag::CodeBlock(_)) => in_code_block = false,
+                _ => {}
+            }
+        }
+
+        for (tag, range) in tags.iter().filter(|(t, _)| {
+            let t = t.to_lowercase();
+            !ALLOWED_UNCLOSED.contains(&t.as_str())
+        }) {
+            report_diag(&format!("unclosed HTML tag `{}`", tag), range, true);
+        }
+
+        if let Some(range) = is_in_comment {
+            report_diag("Unclosed HTML comment", &range, false);
+        }
+    }
 }
 
 const ALLOWED_UNCLOSED: &[&str] = &[
@@ -276,155 +405,3 @@ fn extract_tags(
         }
     }
 }
-
-impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
-    fn visit_item(&mut self, item: &Item) {
-        let tcx = self.cx.tcx;
-        let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id)
-        // If non-local, no need to check anything.
-        else { return };
-        let dox = item.attrs.collapsed_doc_value().unwrap_or_default();
-        if !dox.is_empty() {
-            let report_diag = |msg: &str, range: &Range<usize>, is_open_tag: bool| {
-                let sp = match super::source_span_for_markdown_range(tcx, &dox, range, &item.attrs)
-                {
-                    Some(sp) => sp,
-                    None => item.attr_span(tcx),
-                };
-                tcx.struct_span_lint_hir(crate::lint::INVALID_HTML_TAGS, hir_id, sp, msg, |lint| {
-                    use rustc_lint_defs::Applicability;
-                    // If a tag looks like `<this>`, it might actually be a generic.
-                    // We don't try to detect stuff `<like, this>` because that's not valid HTML,
-                    // and we don't try to detect stuff `<like this>` because that's not valid Rust.
-                    let mut generics_end = range.end;
-                    if let Some(Some(mut generics_start)) = (is_open_tag
-                        && dox[..generics_end].ends_with('>'))
-                    .then(|| extract_path_backwards(&dox, range.start))
-                    {
-                        while generics_start != 0
-                            && generics_end < dox.len()
-                            && dox.as_bytes()[generics_start - 1] == b'<'
-                            && dox.as_bytes()[generics_end] == b'>'
-                        {
-                            generics_end += 1;
-                            generics_start -= 1;
-                            if let Some(new_start) = extract_path_backwards(&dox, generics_start) {
-                                generics_start = new_start;
-                            }
-                            if let Some(new_end) = extract_path_forward(&dox, generics_end) {
-                                generics_end = new_end;
-                            }
-                        }
-                        if let Some(new_end) = extract_path_forward(&dox, generics_end) {
-                            generics_end = new_end;
-                        }
-                        let generics_sp = match super::source_span_for_markdown_range(
-                            tcx,
-                            &dox,
-                            &(generics_start..generics_end),
-                            &item.attrs,
-                        ) {
-                            Some(sp) => sp,
-                            None => item.attr_span(tcx),
-                        };
-                        // Sometimes, we only extract part of a path. For example, consider this:
-                        //
-                        //     <[u32] as IntoIter<u32>>::Item
-                        //                       ^^^^^ unclosed HTML tag `u32`
-                        //
-                        // We don't have any code for parsing fully-qualified trait paths.
-                        // In theory, we could add it, but doing it correctly would require
-                        // parsing the entire path grammar, which is problematic because of
-                        // overlap between the path grammar and Markdown.
-                        //
-                        // The example above shows that ambiguity. Is `[u32]` intended to be an
-                        // intra-doc link to the u32 primitive, or is it intended to be a slice?
-                        //
-                        // If the below conditional were removed, we would suggest this, which is
-                        // not what the user probably wants.
-                        //
-                        //     <[u32] as `IntoIter<u32>`>::Item
-                        //
-                        // We know that the user actually wants to wrap the whole thing in a code
-                        // block, but the only reason we know that is because `u32` does not, in
-                        // fact, implement IntoIter. If the example looks like this:
-                        //
-                        //     <[Vec<i32>] as IntoIter<i32>::Item
-                        //
-                        // The ideal fix would be significantly different.
-                        if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<')
-                            || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>')
-                        {
-                            return lint;
-                        }
-                        // multipart form is chosen here because ``Vec<i32>`` would be confusing.
-                        lint.multipart_suggestion(
-                            "try marking as source code",
-                            vec![
-                                (generics_sp.shrink_to_lo(), String::from("`")),
-                                (generics_sp.shrink_to_hi(), String::from("`")),
-                            ],
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
-
-                    lint
-                });
-            };
-
-            let mut tags = Vec::new();
-            let mut is_in_comment = None;
-            let mut in_code_block = false;
-
-            let link_names = item.link_names(&self.cx.cache);
-
-            let mut replacer = |broken_link: BrokenLink<'_>| {
-                if let Some(link) =
-                    link_names.iter().find(|link| *link.original_text == *broken_link.reference)
-                {
-                    Some((link.href.as_str().into(), link.new_text.as_str().into()))
-                } else if matches!(
-                    &broken_link.link_type,
-                    LinkType::Reference | LinkType::ReferenceUnknown
-                ) {
-                    // If the link is shaped [like][this], suppress any broken HTML in the [this] part.
-                    // The `broken_intra_doc_links` will report typos in there anyway.
-                    Some((
-                        broken_link.reference.to_string().into(),
-                        broken_link.reference.to_string().into(),
-                    ))
-                } else {
-                    None
-                }
-            };
-
-            let p =
-                Parser::new_with_broken_link_callback(&dox, main_body_opts(), Some(&mut replacer))
-                    .into_offset_iter();
-
-            for (event, range) in p {
-                match event {
-                    Event::Start(Tag::CodeBlock(_)) => in_code_block = true,
-                    Event::Html(text) if !in_code_block => {
-                        extract_tags(&mut tags, &text, range, &mut is_in_comment, &report_diag)
-                    }
-                    Event::End(Tag::CodeBlock(_)) => in_code_block = false,
-                    _ => {}
-                }
-            }
-
-            for (tag, range) in tags.iter().filter(|(t, _)| {
-                let t = t.to_lowercase();
-                !ALLOWED_UNCLOSED.contains(&t.as_str())
-            }) {
-                report_diag(&format!("unclosed HTML tag `{}`", tag), range, true);
-            }
-
-            if let Some(range) = is_in_comment {
-                report_diag("Unclosed HTML comment", &range, false);
-            }
-        }
-
-        self.visit_item_recur(item)
-    }
-}
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index f81b38ea395..634e70ec97a 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -12,9 +12,6 @@ use crate::core::DocContext;
 mod stripper;
 pub(crate) use stripper::*;
 
-mod bare_urls;
-pub(crate) use self::bare_urls::CHECK_BARE_URLS;
-
 mod strip_hidden;
 pub(crate) use self::strip_hidden::STRIP_HIDDEN;
 
@@ -36,14 +33,11 @@ pub(crate) use self::check_doc_test_visibility::CHECK_DOC_TEST_VISIBILITY;
 mod collect_trait_impls;
 pub(crate) use self::collect_trait_impls::COLLECT_TRAIT_IMPLS;
 
-mod check_code_block_syntax;
-pub(crate) use self::check_code_block_syntax::CHECK_CODE_BLOCK_SYNTAX;
-
 mod calculate_doc_coverage;
 pub(crate) use self::calculate_doc_coverage::CALCULATE_DOC_COVERAGE;
 
-mod html_tags;
-pub(crate) use self::html_tags::CHECK_INVALID_HTML_TAGS;
+mod lint;
+pub(crate) use self::lint::RUN_LINTS;
 
 /// A single pass over the cleaned documentation.
 ///
@@ -82,11 +76,9 @@ pub(crate) const PASSES: &[Pass] = &[
     STRIP_PRIV_IMPORTS,
     PROPAGATE_DOC_CFG,
     COLLECT_INTRA_DOC_LINKS,
-    CHECK_CODE_BLOCK_SYNTAX,
     COLLECT_TRAIT_IMPLS,
     CALCULATE_DOC_COVERAGE,
-    CHECK_INVALID_HTML_TAGS,
-    CHECK_BARE_URLS,
+    RUN_LINTS,
 ];
 
 /// The list of passes run by default.
@@ -97,10 +89,8 @@ pub(crate) const DEFAULT_PASSES: &[ConditionalPass] = &[
     ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate),
     ConditionalPass::new(STRIP_PRIV_IMPORTS, WhenDocumentPrivate),
     ConditionalPass::always(COLLECT_INTRA_DOC_LINKS),
-    ConditionalPass::always(CHECK_CODE_BLOCK_SYNTAX),
-    ConditionalPass::always(CHECK_INVALID_HTML_TAGS),
     ConditionalPass::always(PROPAGATE_DOC_CFG),
-    ConditionalPass::always(CHECK_BARE_URLS),
+    ConditionalPass::always(RUN_LINTS),
 ];
 
 /// The list of default passes run when `--doc-coverage` is passed to rustdoc.
diff --git a/src/test/assembly/asm/aarch64-el2vmsa.rs b/src/test/assembly/asm/aarch64-el2vmsa.rs
new file mode 100644
index 00000000000..1908ffb8ff3
--- /dev/null
+++ b/src/test/assembly/asm/aarch64-el2vmsa.rs
@@ -0,0 +1,37 @@
+// assembly-output: emit-asm
+// compile-flags: --target aarch64-unknown-linux-gnu
+// needs-llvm-components: aarch64
+
+#![feature(no_core, lang_items, rustc_attrs)]
+#![crate_type = "rlib"]
+#![no_core]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+// CHECK-LABEL: ttbr0_el2:
+#[no_mangle]
+pub fn ttbr0_el2() {
+    // CHECK: //APP
+    // CHECK-NEXT: msr TTBR0_EL2, x0
+    // CHECK-NEXT: //NO_APP
+    unsafe {
+        asm!("msr ttbr0_el2, x0");
+    }
+}
+
+// CHECK-LABEL: vttbr_el2:
+#[no_mangle]
+pub fn vttbr_el2() {
+    // CHECK: //APP
+    // CHECK-NEXT: msr VTTBR_EL2, x0
+    // CHECK-NEXT: //NO_APP
+    unsafe {
+        asm!("msr vttbr_el2, x0");
+    }
+}
diff --git a/src/test/assembly/sparc-struct-abi.rs b/src/test/assembly/sparc-struct-abi.rs
index 6a898b2974a..6309dd420ff 100644
--- a/src/test/assembly/sparc-struct-abi.rs
+++ b/src/test/assembly/sparc-struct-abi.rs
@@ -44,12 +44,16 @@ pub unsafe extern "C" fn callee(arg: Franta) {
     tst_use(arg.b);
     tst_use(arg.c);
     tst_use(arg.d);
+    tail_call_avoidance_fn();
 }
 
 extern "C" {
     fn opaque_callee(arg: Franta, intarg: i32);
     fn tst_use(arg: f32);
     fn clobber();
+    // This exists so that post-https://reviews.llvm.org/D138741 LLVM doesn't
+    // tail-call away some of our assertions.
+    fn tail_call_avoidance_fn();
 }
 
 #[no_mangle]
@@ -62,4 +66,5 @@ pub unsafe extern "C" fn caller() {
     // CHECK: call opaque_callee
     // CHECK: mov     3, %o2
     opaque_callee(Franta { a: 1.0, b: 2.0, c: 3.0, d: 4.0 }, 3);
+    tail_call_avoidance_fn();
 }
diff --git a/src/test/codegen/enum-match.rs b/src/test/codegen/enum-match.rs
index efab189fd7b..44f1b408d21 100644
--- a/src/test/codegen/enum-match.rs
+++ b/src/test/codegen/enum-match.rs
@@ -34,11 +34,8 @@ pub enum Enum1 {
 
 // CHECK: define i8 @match1{{.*}}
 // CHECK-NEXT: start:
-// CHECK-NEXT: %1 = icmp ugt i8 %0, 1
-// CHECK-NEXT: %2 = zext i8 %0 to i64
-// CHECK-NEXT: %3 = add nsw i64 %2, -1
-// CHECK-NEXT: %_2 = select i1 %1, i64 %3, i64 0
-// CHECK-NEXT: switch i64 %_2, label {{.*}} [
+// CHECK-NEXT: %1 = {{.*}}call i8 @llvm.usub.sat.i8(i8 %0, i8 1)
+// CHECK-NEXT: switch i8 %1, label {{.*}} [
 #[no_mangle]
 pub fn match1(e: Enum1) -> u8 {
     use Enum1::*;
diff --git a/src/test/codegen/naked-nocoverage.rs b/src/test/codegen/naked-nocoverage.rs
new file mode 100644
index 00000000000..91a6260bf2a
--- /dev/null
+++ b/src/test/codegen/naked-nocoverage.rs
@@ -0,0 +1,19 @@
+// Checks that naked functions are not instrumented by -Cinstrument-coverage.
+// Regression test for issue #105170.
+//
+// needs-asm-support
+// needs-profiler-support
+// compile-flags: -Cinstrument-coverage
+#![crate_type = "lib"]
+#![feature(naked_functions)]
+use std::arch::asm;
+
+#[naked]
+#[no_mangle]
+pub unsafe extern "C" fn f() {
+    // CHECK:       define void @f()
+    // CHECK-NEXT:  start:
+    // CHECK-NEXT:    call void asm
+    // CHECK-NEXT:    unreachable
+    asm!("", options(noreturn));
+}
diff --git a/src/test/run-make/macos-deployment-target/Makefile b/src/test/run-make/macos-deployment-target/Makefile
new file mode 100644
index 00000000000..70fca043653
--- /dev/null
+++ b/src/test/run-make/macos-deployment-target/Makefile
@@ -0,0 +1,21 @@
+# only-macos
+#
+# Check that a set deployment target actually makes it to the linker.
+# This is important since its a compatibility hazard. The linker will
+# generate load commands differently based on what minimum OS it can assume.
+
+include ../../run-make-fulldeps/tools.mk
+
+ifeq ($(strip $(shell uname -m)),arm64)
+	GREP_PATTERN = "minos 11.0"
+else
+ 	GREP_PATTERN = "version 10.9"
+endif
+
+OUT_FILE=$(TMPDIR)/with_deployment_target.dylib
+all:
+	env MACOSX_DEPLOYMENT_TARGET=10.9 $(RUSTC) with_deployment_target.rs -o $(OUT_FILE)
+# XXX: The check is for either the x86_64 minimum OR the aarch64 minimum (M1 starts at macOS 11).
+# They also use different load commands, so we let that change with each too. The aarch64 check
+# isn't as robust as the x86 one, but testing both seems unneeded.
+	vtool -show-build $(OUT_FILE) | $(CGREP) -e $(GREP_PATTERN)
diff --git a/src/test/run-make/macos-deployment-target/with_deployment_target.rs b/src/test/run-make/macos-deployment-target/with_deployment_target.rs
new file mode 100644
index 00000000000..342fe0ecbcf
--- /dev/null
+++ b/src/test/run-make/macos-deployment-target/with_deployment_target.rs
@@ -0,0 +1,4 @@
+#![crate_type = "cdylib"]
+
+#[allow(dead_code)]
+fn something_and_nothing() {}
diff --git a/src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs b/src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs
new file mode 100644
index 00000000000..bfe85f59e81
--- /dev/null
+++ b/src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs
@@ -0,0 +1,8 @@
+pub trait Trait {
+    /// [`Enum::Variant`]
+    fn method() {}
+}
+
+pub enum Enum {
+    Variant,
+}
diff --git a/src/test/rustdoc-json/intra-doc-links/foreign_variant.rs b/src/test/rustdoc-json/intra-doc-links/foreign_variant.rs
new file mode 100644
index 00000000000..e2968231338
--- /dev/null
+++ b/src/test/rustdoc-json/intra-doc-links/foreign_variant.rs
@@ -0,0 +1,13 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/105025>
+// aux-build: enum_variant_in_trait_method.rs
+
+extern crate enum_variant_in_trait_method;
+
+pub struct Local;
+
+/// local impl
+impl enum_variant_in_trait_method::Trait for Local {}
+
+// @!has "$.index[*][?(@.name == 'Trait')]"
+// @!has "$.index[*][?(@.name == 'method')]"
+// @count "$.index[*][?(@.docs == 'local impl')].inner.items[*]" 0
diff --git a/src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs b/src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs
new file mode 100644
index 00000000000..1e87966b28a
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs
@@ -0,0 +1,2 @@
+/// The Docs
+pub trait HasDocs {}
diff --git a/src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs b/src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs
new file mode 100644
index 00000000000..25a7c08d689
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs
@@ -0,0 +1,10 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/105022>
+// aux-build: trait_with_docs.rs
+
+extern crate trait_with_docs;
+
+pub struct Local;
+
+impl trait_with_docs::HasDocs for Local {}
+
+// @!has "$.index[*][?(@.name == 'HasDocs')]"
diff --git a/src/test/rustdoc-json/traits/uses_extern_trait.rs b/src/test/rustdoc-json/traits/uses_extern_trait.rs
index a4add43c6a1..55a51f739ab 100644
--- a/src/test/rustdoc-json/traits/uses_extern_trait.rs
+++ b/src/test/rustdoc-json/traits/uses_extern_trait.rs
@@ -1,12 +1,5 @@
 #![no_std]
 pub fn drop_default<T: core::default::Default>(_x: T) {}
 
-// FIXME(adotinthevoid): Theses shouldn't be here
-// @has "$.index[*][?(@.name=='Debug')]"
-
-// Debug may have several items. All we depend on here the that `fmt` is first. See
-// https://github.com/rust-lang/rust/pull/104525#issuecomment-1331087852 for why we
-// can't use [*].
-
-// @set Debug_fmt = "$.index[*][?(@.name=='Debug')].inner.items[0]"
-// @has "$.index[*][?(@.name=='fmt')].id" $Debug_fmt
+// @!has "$.index[*][?(@.name=='Debug')]"
+// @!has "$.index[*][?(@.name=='Default')]"
diff --git a/src/test/rustdoc-ui/issue-91713.stdout b/src/test/rustdoc-ui/issue-91713.stdout
index a19e452b459..16783524363 100644
--- a/src/test/rustdoc-ui/issue-91713.stdout
+++ b/src/test/rustdoc-ui/issue-91713.stdout
@@ -5,11 +5,9 @@ check_doc_test_visibility - run various visibility-related lints on doctests
   strip-priv-imports - strips all private import statements (`use`, `extern crate`) from a crate
    propagate-doc-cfg - propagates `#[doc(cfg(...))]` to child items
 collect-intra-doc-links - resolves intra-doc links
-check-code-block-syntax - validates syntax inside Rust code blocks
  collect-trait-impls - retrieves trait impls for items in the crate
 calculate-doc-coverage - counts the number of items with and without documentation
-check-invalid-html-tags - detects invalid HTML tags in doc comments
-     check-bare-urls - detects URLs that are not hyperlinks
+           run-lints - runs some of rustdoc's lints
 
 Default passes for rustdoc:
  collect-trait-impls
@@ -18,10 +16,8 @@ check_doc_test_visibility
        strip-private  (when not --document-private-items)
   strip-priv-imports  (when --document-private-items)
 collect-intra-doc-links
-check-code-block-syntax
-check-invalid-html-tags
    propagate-doc-cfg
-     check-bare-urls
+           run-lints
 
 Passes run with `--show-coverage`:
         strip-hidden  (when not --document-hidden-items)
diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout
index 22e37821322..55154803098 100644
--- a/src/test/rustdoc-ui/z-help.stdout
+++ b/src/test/rustdoc-ui/z-help.stdout
@@ -90,7 +90,6 @@
     -Z                             no-analysis=val -- parse and expand the source, but run no analysis
     -Z                              no-codegen=val -- run all passes except codegen; no output
     -Z              no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups
-    -Z                     no-interleave-lints=val -- execute lints separately; allows benchmarking individual lints
     -Z                           no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests
     -Z                                 no-link=val -- compile without linking
     -Z                        no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)
diff --git a/src/test/rustdoc/bounds-in-multiple-parts.rs b/src/test/rustdoc/bounds-in-multiple-parts.rs
new file mode 100644
index 00000000000..279e3c14888
--- /dev/null
+++ b/src/test/rustdoc/bounds-in-multiple-parts.rs
@@ -0,0 +1,20 @@
+#![crate_name = "foo"]
+
+pub trait Eq {}
+pub trait Eq2 {}
+
+// Checking that "where predicates" and "generics params" are merged.
+// @has 'foo/trait.T.html'
+// @has - "//*[@id='tymethod.f']/h4" "fn f<'a, 'b, 'c, T>()where Self: Eq, T: Eq + 'a, 'c: 'b + 'a,"
+pub trait T {
+    fn f<'a, 'b, 'c: 'a, T: Eq + 'a>()
+        where Self: Eq, Self: Eq, T: Eq, 'c: 'b;
+}
+
+// Checking that a duplicated "where predicate" is removed.
+// @has 'foo/trait.T2.html'
+// @has - "//*[@id='tymethod.f']/h4" "fn f<T>()where Self: Eq + Eq2, T: Eq2 + Eq,"
+pub trait T2 {
+    fn f<T: Eq>()
+        where Self: Eq, Self: Eq2, T: Eq2;
+}
diff --git a/src/test/rustdoc/impl-parts.rs b/src/test/rustdoc/impl-parts.rs
index 7b931727e44..90cbb77cb6b 100644
--- a/src/test/rustdoc/impl-parts.rs
+++ b/src/test/rustdoc/impl-parts.rs
@@ -6,7 +6,7 @@ pub auto trait AnAutoTrait {}
 pub struct Foo<T> { field: T }
 
 // @has impl_parts/struct.Foo.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
-//     "impl<T: Clone> !AnAutoTrait for Foo<T>where T: Sync,"
+//     "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"
 // @has impl_parts/trait.AnAutoTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
-//     "impl<T: Clone> !AnAutoTrait for Foo<T>where T: Sync,"
+//     "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"
 impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync {}
diff --git a/src/test/rustdoc/rfc-2632-const-trait-impl.rs b/src/test/rustdoc/rfc-2632-const-trait-impl.rs
index 602ee1b1b1f..7ed9d6729b6 100644
--- a/src/test/rustdoc/rfc-2632-const-trait-impl.rs
+++ b/src/test/rustdoc/rfc-2632-const-trait-impl.rs
@@ -61,7 +61,7 @@ impl<T> S<T> {
     // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone'
     // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const'
     // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone'
-    pub const fn foo<B: ~const Clone + ~const Destruct>()
+    pub const fn foo<B, C: ~const Clone + ~const Destruct>()
     where
         B: ~const Clone + ~const Destruct,
     {
diff --git a/src/test/rustdoc/whitespace-after-where-clause.enum.html b/src/test/rustdoc/whitespace-after-where-clause.enum.html
index c74866f4a10..f7663e4616a 100644
--- a/src/test/rustdoc/whitespace-after-where-clause.enum.html
+++ b/src/test/rustdoc/whitespace-after-where-clause.enum.html
@@ -1,4 +1,4 @@
-<div class="item-decl"><pre class="rust enum"><code>pub enum Cow&lt;'a, B:&#160;?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt;,</span>{
+<div class="item-decl"><pre class="rust enum"><code>pub enum Cow&lt;'a, B&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
     Borrowed(<a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a </a>B),
     Whatever(<a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>),
 }</code></pre></div>
\ No newline at end of file
diff --git a/src/test/rustdoc/whitespace-after-where-clause.struct.html b/src/test/rustdoc/whitespace-after-where-clause.struct.html
index 1ba1367d20f..fa3f224e7ad 100644
--- a/src/test/rustdoc/whitespace-after-where-clause.struct.html
+++ b/src/test/rustdoc/whitespace-after-where-clause.struct.html
@@ -1,4 +1,4 @@
-<div class="item-decl"><pre class="rust struct"><code>pub struct Struct&lt;'a, B:&#160;?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt;,</span>{
+<div class="item-decl"><pre class="rust struct"><code>pub struct Struct&lt;'a, B&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
     pub a: <a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a </a>B,
     pub b: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>,
 }</code></pre></div>
\ No newline at end of file
diff --git a/src/test/rustdoc/whitespace-after-where-clause.union.html b/src/test/rustdoc/whitespace-after-where-clause.union.html
index 0dfb6407d45..7bb177debc3 100644
--- a/src/test/rustdoc/whitespace-after-where-clause.union.html
+++ b/src/test/rustdoc/whitespace-after-where-clause.union.html
@@ -1,3 +1,3 @@
-<div class="item-decl"><pre class="rust union"><code>pub union Union&lt;'a, B:&#160;?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt;,</span>{
+<div class="item-decl"><pre class="rust union"><code>pub union Union&lt;'a, B&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
     /* private fields */
 }</code></pre></div>
\ No newline at end of file
diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr b/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr
index 981631494fa..82679c9e10a 100644
--- a/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr
@@ -1,11 +1,3 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> <crate attribute>:1:1
-   |
-LL | plugin(lint_plugin_test)
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
 warning: item is named 'lintme'
   --> $DIR/lint-plugin-cmdline-load.rs:8:1
    |
@@ -14,5 +6,13 @@ LL | fn lintme() { }
    |
    = note: `#[warn(test_lint)]` on by default
 
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+  --> <crate attribute>:1:1
+   |
+LL | plugin(lint_plugin_test)
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+   |
+   = note: `#[warn(deprecated)]` on by default
+
 warning: 2 warnings emitted
 
diff --git a/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr b/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr
index b9774c04462..5e8891bf1f1 100644
--- a/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr
@@ -1,11 +1,3 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/lint-plugin-deny-attr.rs:5:1
-   |
-LL | #![plugin(lint_plugin_test)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
 error: item is named 'lintme'
   --> $DIR/lint-plugin-deny-attr.rs:9:1
    |
@@ -18,5 +10,13 @@ note: the lint level is defined here
 LL | #![deny(test_lint)]
    |         ^^^^^^^^^
 
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+  --> $DIR/lint-plugin-deny-attr.rs:5:1
+   |
+LL | #![plugin(lint_plugin_test)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+   |
+   = note: `#[warn(deprecated)]` on by default
+
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr
index cbabb09f6a5..d5d6b535214 100644
--- a/src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr
@@ -1,11 +1,3 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/lint-plugin-deny-cmdline.rs:6:1
-   |
-LL | #![plugin(lint_plugin_test)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
 error: item is named 'lintme'
   --> $DIR/lint-plugin-deny-cmdline.rs:9:1
    |
@@ -14,5 +6,13 @@ LL | fn lintme() { }
    |
    = note: requested on the command line with `-D test-lint`
 
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+  --> $DIR/lint-plugin-deny-cmdline.rs:6:1
+   |
+LL | #![plugin(lint_plugin_test)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+   |
+   = note: `#[warn(deprecated)]` on by default
+
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs
index 4833f6971c1..cf31b3ec158 100644
--- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs
+++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs
@@ -11,7 +11,6 @@ fn lintme() {} //~ ERROR item is named 'lintme'
 #[allow(test_lint)]
 //~^ ERROR allow(test_lint) incompatible
 //~| ERROR allow(test_lint) incompatible
-//~| ERROR allow(test_lint) incompatible
 pub fn main() {
     lintme();
 }
diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr
index e11a4f84493..ae34b25cc2f 100644
--- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr
@@ -7,23 +7,6 @@ LL | #![forbid(test_lint)]
 LL | #[allow(test_lint)]
    |         ^^^^^^^^^ overruled by previous forbid
 
-error[E0453]: allow(test_lint) incompatible with previous forbid
-  --> $DIR/lint-plugin-forbid-attrs.rs:11:9
-   |
-LL | #![forbid(test_lint)]
-   |           --------- `forbid` level set here
-...
-LL | #[allow(test_lint)]
-   |         ^^^^^^^^^ overruled by previous forbid
-
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/lint-plugin-forbid-attrs.rs:5:1
-   |
-LL | #![plugin(lint_plugin_test)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
 error: item is named 'lintme'
   --> $DIR/lint-plugin-forbid-attrs.rs:9:1
    |
@@ -45,6 +28,14 @@ LL | #![forbid(test_lint)]
 LL | #[allow(test_lint)]
    |         ^^^^^^^^^ overruled by previous forbid
 
-error: aborting due to 4 previous errors; 1 warning emitted
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+  --> $DIR/lint-plugin-forbid-attrs.rs:5:1
+   |
+LL | #![plugin(lint_plugin_test)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+   |
+   = note: `#[warn(deprecated)]` on by default
+
+error: aborting due to 3 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs
index ce034ee38d7..b9d1aa85a69 100644
--- a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs
+++ b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs
@@ -9,7 +9,7 @@ fn lintme() { } //~ ERROR item is named 'lintme'
 
 #[allow(test_lint)] //~ ERROR allow(test_lint) incompatible
                     //~| ERROR allow(test_lint) incompatible
-                    //~| ERROR allow(test_lint)
+
 pub fn main() {
     lintme();
 }
diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr
index 09c19af617a..491c4d20646 100644
--- a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr
@@ -6,22 +6,6 @@ LL | #[allow(test_lint)]
    |
    = note: `forbid` lint level was set on command line
 
-error[E0453]: allow(test_lint) incompatible with previous forbid
-  --> $DIR/lint-plugin-forbid-cmdline.rs:10:9
-   |
-LL | #[allow(test_lint)]
-   |         ^^^^^^^^^ overruled by previous forbid
-   |
-   = note: `forbid` lint level was set on command line
-
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/lint-plugin-forbid-cmdline.rs:6:1
-   |
-LL | #![plugin(lint_plugin_test)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
 error: item is named 'lintme'
   --> $DIR/lint-plugin-forbid-cmdline.rs:8:1
    |
@@ -38,6 +22,14 @@ LL | #[allow(test_lint)]
    |
    = note: `forbid` lint level was set on command line
 
-error: aborting due to 4 previous errors; 1 warning emitted
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+  --> $DIR/lint-plugin-forbid-cmdline.rs:6:1
+   |
+LL | #![plugin(lint_plugin_test)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+   |
+   = note: `#[warn(deprecated)]` on by default
+
+error: aborting due to 3 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/ui-fulldeps/lint-plugin.stderr b/src/test/ui-fulldeps/lint-plugin.stderr
index 765832071cb..dd5d3d72ecf 100644
--- a/src/test/ui-fulldeps/lint-plugin.stderr
+++ b/src/test/ui-fulldeps/lint-plugin.stderr
@@ -1,11 +1,3 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/lint-plugin.rs:5:1
-   |
-LL | #![plugin(lint_plugin_test)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
 warning: item is named 'lintme'
   --> $DIR/lint-plugin.rs:8:1
    |
@@ -14,5 +6,13 @@ LL | fn lintme() { }
    |
    = note: `#[warn(test_lint)]` on by default
 
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+  --> $DIR/lint-plugin.rs:5:1
+   |
+LL | #![plugin(lint_plugin_test)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+   |
+   = note: `#[warn(deprecated)]` on by default
+
 warning: 2 warnings emitted
 
diff --git a/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
index b4fb9e22da4..b060e3a3e38 100644
--- a/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
+++ b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
@@ -6,18 +6,6 @@ warning: lint name `test_lint` is deprecated and does not have an effect anymore
    |
    = note: requested on the command line with `-A test_lint`
 
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/lint-tool-cmdline-allow.rs:7:1
-   |
-LL | #![plugin(lint_tool_test)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
-warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint
-   |
-   = note: requested on the command line with `-A test_lint`
-
 warning: item is named 'lintme'
   --> $DIR/lint-tool-cmdline-allow.rs:9:1
    |
@@ -26,9 +14,17 @@ LL | fn lintme() {}
    |
    = note: `#[warn(clippy::test_lint)]` on by default
 
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+  --> $DIR/lint-tool-cmdline-allow.rs:7:1
+   |
+LL | #![plugin(lint_tool_test)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+   |
+   = note: `#[warn(deprecated)]` on by default
+
 warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint
    |
    = note: requested on the command line with `-A test_lint`
 
-warning: 6 warnings emitted
+warning: 5 warnings emitted
 
diff --git a/src/test/ui-fulldeps/lint-tool-test.rs b/src/test/ui-fulldeps/lint-tool-test.rs
index 0d04eb6fcfa..f92bcd213b8 100644
--- a/src/test/ui-fulldeps/lint-tool-test.rs
+++ b/src/test/ui-fulldeps/lint-tool-test.rs
@@ -10,12 +10,10 @@
 //~^ WARNING lint name `test_lint` is deprecated and may not have an effect in the future
 //~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future
 //~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future
-//~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future
 #![deny(clippy_group)]
 //~^ WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
 //~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
 //~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
-//~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
 
 fn lintme() { } //~ ERROR item is named 'lintme'
 
@@ -32,7 +30,6 @@ pub fn main() {
 //~^ WARNING lint name `test_group` is deprecated and may not have an effect in the future
 //~| WARNING lint name `test_group` is deprecated and may not have an effect in the future
 //~| WARNING lint name `test_group` is deprecated and may not have an effect in the future
-//~| WARNING lint name `test_group` is deprecated and may not have an effect in the future
 #[deny(this_lint_does_not_exist)] //~ WARNING unknown lint: `this_lint_does_not_exist`
 fn hello() {
     fn lintmetoo() { }
diff --git a/src/test/ui-fulldeps/lint-tool-test.stderr b/src/test/ui-fulldeps/lint-tool-test.stderr
index af9b8dedc73..027cf8f80cf 100644
--- a/src/test/ui-fulldeps/lint-tool-test.stderr
+++ b/src/test/ui-fulldeps/lint-tool-test.stderr
@@ -7,13 +7,13 @@ LL | #![cfg_attr(foo, warn(test_lint))]
    = note: `#[warn(renamed_and_removed_lints)]` on by default
 
 warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
-  --> $DIR/lint-tool-test.rs:14:9
+  --> $DIR/lint-tool-test.rs:13:9
    |
 LL | #![deny(clippy_group)]
    |         ^^^^^^^^^^^^ help: change it to: `clippy::group`
 
 warning: lint name `test_group` is deprecated and may not have an effect in the future.
-  --> $DIR/lint-tool-test.rs:31:9
+  --> $DIR/lint-tool-test.rs:29:9
    |
 LL | #[allow(test_group)]
    |         ^^^^^^^^^^ help: change it to: `clippy::test_group`
@@ -25,60 +25,26 @@ LL | #![cfg_attr(foo, warn(test_lint))]
    |                       ^^^^^^^^^ help: change it to: `clippy::test_lint`
 
 warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
-  --> $DIR/lint-tool-test.rs:14:9
-   |
-LL | #![deny(clippy_group)]
-   |         ^^^^^^^^^^^^ help: change it to: `clippy::group`
-
-warning: lint name `test_group` is deprecated and may not have an effect in the future.
-  --> $DIR/lint-tool-test.rs:31:9
-   |
-LL | #[allow(test_group)]
-   |         ^^^^^^^^^^ help: change it to: `clippy::test_group`
-
-warning: unknown lint: `this_lint_does_not_exist`
-  --> $DIR/lint-tool-test.rs:36:8
-   |
-LL | #[deny(this_lint_does_not_exist)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(unknown_lints)]` on by default
-
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/lint-tool-test.rs:6:1
-   |
-LL | #![plugin(lint_tool_test)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
-   |
-   = note: `#[warn(deprecated)]` on by default
-
-warning: lint name `test_lint` is deprecated and may not have an effect in the future.
-  --> $DIR/lint-tool-test.rs:9:23
-   |
-LL | #![cfg_attr(foo, warn(test_lint))]
-   |                       ^^^^^^^^^ help: change it to: `clippy::test_lint`
-
-warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
-  --> $DIR/lint-tool-test.rs:14:9
+  --> $DIR/lint-tool-test.rs:13:9
    |
 LL | #![deny(clippy_group)]
    |         ^^^^^^^^^^^^ help: change it to: `clippy::group`
 
 error: item is named 'lintme'
-  --> $DIR/lint-tool-test.rs:20:1
+  --> $DIR/lint-tool-test.rs:18:1
    |
 LL | fn lintme() { }
    | ^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/lint-tool-test.rs:14:9
+  --> $DIR/lint-tool-test.rs:13:9
    |
 LL | #![deny(clippy_group)]
    |         ^^^^^^^^^^^^
    = note: `#[deny(clippy::test_lint)]` implied by `#[deny(clippy::group)]`
 
 error: item is named 'lintmetoo'
-  --> $DIR/lint-tool-test.rs:28:5
+  --> $DIR/lint-tool-test.rs:26:5
    |
 LL |     fn lintmetoo() { }
    |     ^^^^^^^^^^^^^^^^^^
@@ -86,11 +52,27 @@ LL |     fn lintmetoo() { }
    = note: `#[deny(clippy::test_group)]` implied by `#[deny(clippy::group)]`
 
 warning: lint name `test_group` is deprecated and may not have an effect in the future.
-  --> $DIR/lint-tool-test.rs:31:9
+  --> $DIR/lint-tool-test.rs:29:9
    |
 LL | #[allow(test_group)]
    |         ^^^^^^^^^^ help: change it to: `clippy::test_group`
 
+warning: unknown lint: `this_lint_does_not_exist`
+  --> $DIR/lint-tool-test.rs:33:8
+   |
+LL | #[deny(this_lint_does_not_exist)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(unknown_lints)]` on by default
+
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+  --> $DIR/lint-tool-test.rs:6:1
+   |
+LL | #![plugin(lint_tool_test)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+   |
+   = note: `#[warn(deprecated)]` on by default
+
 warning: lint name `test_lint` is deprecated and may not have an effect in the future.
   --> $DIR/lint-tool-test.rs:9:23
    |
@@ -98,16 +80,16 @@ LL | #![cfg_attr(foo, warn(test_lint))]
    |                       ^^^^^^^^^ help: change it to: `clippy::test_lint`
 
 warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
-  --> $DIR/lint-tool-test.rs:14:9
+  --> $DIR/lint-tool-test.rs:13:9
    |
 LL | #![deny(clippy_group)]
    |         ^^^^^^^^^^^^ help: change it to: `clippy::group`
 
 warning: lint name `test_group` is deprecated and may not have an effect in the future.
-  --> $DIR/lint-tool-test.rs:31:9
+  --> $DIR/lint-tool-test.rs:29:9
    |
 LL | #[allow(test_group)]
    |         ^^^^^^^^^^ help: change it to: `clippy::test_group`
 
-error: aborting due to 2 previous errors; 14 warnings emitted
+error: aborting due to 2 previous errors; 11 warnings emitted
 
diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index d6dc179da7f..a93ba87470a 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -126,6 +126,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
                         fn_decl: decl.clone(),
                         body: e,
                         fn_decl_span: DUMMY_SP,
+                        fn_arg_span: DUMMY_SP,
                     })))
                 });
             }
diff --git a/src/test/ui/associated-consts/issue-47814.rs b/src/test/ui/associated-consts/issue-47814.rs
new file mode 100644
index 00000000000..a28b1c00113
--- /dev/null
+++ b/src/test/ui/associated-consts/issue-47814.rs
@@ -0,0 +1,14 @@
+struct ArpIPv4<'a> {
+    s: &'a u8
+}
+
+impl<'a> ArpIPv4<'a> {
+    const LENGTH: usize = 20;
+
+    pub fn to_buffer() -> [u8; Self::LENGTH] {
+        //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants
+        unimplemented!()
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-consts/issue-47814.stderr b/src/test/ui/associated-consts/issue-47814.stderr
new file mode 100644
index 00000000000..2e4ddb81166
--- /dev/null
+++ b/src/test/ui/associated-consts/issue-47814.stderr
@@ -0,0 +1,14 @@
+error: generic `Self` types are currently not permitted in anonymous constants
+  --> $DIR/issue-47814.rs:8:32
+   |
+LL |     pub fn to_buffer() -> [u8; Self::LENGTH] {
+   |                                ^^^^
+   |
+note: not a concrete type
+  --> $DIR/issue-47814.rs:5:10
+   |
+LL | impl<'a> ArpIPv4<'a> {
+   |          ^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-inherent-types/struct-generics.rs b/src/test/ui/associated-inherent-types/struct-generics.rs
new file mode 100644
index 00000000000..8952b379173
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/struct-generics.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct S<T>(T);
+
+impl<T> S<T> {
+    type P = T;
+}
+
+fn main() {
+    type A = S<()>::P;
+    let _: A = ();
+}
diff --git a/src/test/ui/async-await/generator-not-future.rs b/src/test/ui/async-await/generator-not-future.rs
new file mode 100644
index 00000000000..37d7cfa6fb7
--- /dev/null
+++ b/src/test/ui/async-await/generator-not-future.rs
@@ -0,0 +1,45 @@
+// edition:2018
+#![feature(generators, generator_trait)]
+
+use std::future::Future;
+use std::ops::Generator;
+
+async fn async_fn() {}
+fn returns_async_block() -> impl Future<Output = ()> {
+    async {}
+}
+fn returns_generator() -> impl Generator<(), Yield = (), Return = ()> {
+    || {
+        let _: () = yield ();
+    }
+}
+
+fn takes_future(_f: impl Future<Output = ()>) {}
+fn takes_generator<ResumeTy>(_g: impl Generator<ResumeTy, Yield = (), Return = ()>) {}
+
+fn main() {
+    // okay:
+    takes_future(async_fn());
+    takes_future(returns_async_block());
+    takes_future(async {});
+    takes_generator(returns_generator());
+    takes_generator(|| {
+        let _: () = yield ();
+    });
+
+    // async futures are not generators:
+    takes_generator(async_fn());
+    //~^ ERROR the trait bound
+    takes_generator(returns_async_block());
+    //~^ ERROR the trait bound
+    takes_generator(async {});
+    //~^ ERROR the trait bound
+
+    // generators are not futures:
+    takes_future(returns_generator());
+    //~^ ERROR is not a future
+    takes_future(|ctx| {
+        //~^ ERROR is not a future
+        ctx = yield ();
+    });
+}
diff --git a/src/test/ui/async-await/generator-not-future.stderr b/src/test/ui/async-await/generator-not-future.stderr
new file mode 100644
index 00000000000..1b81b461f0a
--- /dev/null
+++ b/src/test/ui/async-await/generator-not-future.stderr
@@ -0,0 +1,81 @@
+error[E0277]: the trait bound `impl Future<Output = ()>: Generator<_>` is not satisfied
+  --> $DIR/generator-not-future.rs:31:21
+   |
+LL |     takes_generator(async_fn());
+   |     --------------- ^^^^^^^^^^ the trait `Generator<_>` is not implemented for `impl Future<Output = ()>`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `takes_generator`
+  --> $DIR/generator-not-future.rs:18:39
+   |
+LL | fn takes_generator<ResumeTy>(_g: impl Generator<ResumeTy, Yield = (), Return = ()>) {}
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_generator`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Generator<_>` is not satisfied
+  --> $DIR/generator-not-future.rs:33:21
+   |
+LL |     takes_generator(returns_async_block());
+   |     --------------- ^^^^^^^^^^^^^^^^^^^^^ the trait `Generator<_>` is not implemented for `impl Future<Output = ()>`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `takes_generator`
+  --> $DIR/generator-not-future.rs:18:39
+   |
+LL | fn takes_generator<ResumeTy>(_g: impl Generator<ResumeTy, Yield = (), Return = ()>) {}
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_generator`
+
+error[E0277]: the trait bound `[async block@$DIR/generator-not-future.rs:35:21: 35:29]: Generator<_>` is not satisfied
+  --> $DIR/generator-not-future.rs:35:21
+   |
+LL |     takes_generator(async {});
+   |     --------------- ^^^^^^^^ the trait `Generator<_>` is not implemented for `[async block@$DIR/generator-not-future.rs:35:21: 35:29]`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `takes_generator`
+  --> $DIR/generator-not-future.rs:18:39
+   |
+LL | fn takes_generator<ResumeTy>(_g: impl Generator<ResumeTy, Yield = (), Return = ()>) {}
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_generator`
+
+error[E0277]: `impl Generator<Yield = (), Return = ()>` is not a future
+  --> $DIR/generator-not-future.rs:39:18
+   |
+LL |     takes_future(returns_generator());
+   |     ------------ ^^^^^^^^^^^^^^^^^^^ `impl Generator<Yield = (), Return = ()>` is not a future
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Future` is not implemented for `impl Generator<Yield = (), Return = ()>`
+   = note: impl Generator<Yield = (), Return = ()> must be a future or must implement `IntoFuture` to be awaited
+note: required by a bound in `takes_future`
+  --> $DIR/generator-not-future.rs:17:26
+   |
+LL | fn takes_future(_f: impl Future<Output = ()>) {}
+   |                          ^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_future`
+
+error[E0277]: `[generator@$DIR/generator-not-future.rs:41:18: 41:23]` is not a future
+  --> $DIR/generator-not-future.rs:41:18
+   |
+LL |       takes_future(|ctx| {
+   |  _____------------_^
+   | |     |
+   | |     required by a bound introduced by this call
+LL | |
+LL | |         ctx = yield ();
+LL | |     });
+   | |_____^ `[generator@$DIR/generator-not-future.rs:41:18: 41:23]` is not a future
+   |
+   = help: the trait `Future` is not implemented for `[generator@$DIR/generator-not-future.rs:41:18: 41:23]`
+   = note: [generator@$DIR/generator-not-future.rs:41:18: 41:23] must be a future or must implement `IntoFuture` to be awaited
+note: required by a bound in `takes_future`
+  --> $DIR/generator-not-future.rs:17:26
+   |
+LL | fn takes_future(_f: impl Future<Output = ()>) {}
+   |                          ^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_future`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr
index 5c8d64fc6cb..f1f0d7e5907 100644
--- a/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr
+++ b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr
@@ -4,11 +4,11 @@ error[E0311]: the parameter type `U` may not live long enough
 LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
    |                            ^^^^^^^
    |
-note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
+note: the parameter type `U` must be valid for the anonymous lifetime defined here...
   --> $DIR/async-generics-and-bounds.rs:12:18
    |
 LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                  ^
+   |                  ^^^^^
 note: ...so that the reference type `&(T, U)` does not outlive the data it points at
   --> $DIR/async-generics-and-bounds.rs:12:28
    |
@@ -21,11 +21,11 @@ error[E0311]: the parameter type `T` may not live long enough
 LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
    |                            ^^^^^^^
    |
-note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
   --> $DIR/async-generics-and-bounds.rs:12:18
    |
 LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                  ^
+   |                  ^^^^^
 note: ...so that the reference type `&(T, U)` does not outlive the data it points at
   --> $DIR/async-generics-and-bounds.rs:12:28
    |
diff --git a/src/test/ui/async-await/in-trait/async-generics.stderr b/src/test/ui/async-await/in-trait/async-generics.stderr
index 6ae73d9e3a6..2f05564564c 100644
--- a/src/test/ui/async-await/in-trait/async-generics.stderr
+++ b/src/test/ui/async-await/in-trait/async-generics.stderr
@@ -4,11 +4,11 @@ error[E0311]: the parameter type `U` may not live long enough
 LL |     async fn foo(&self) -> &(T, U);
    |                            ^^^^^^^
    |
-note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
+note: the parameter type `U` must be valid for the anonymous lifetime defined here...
   --> $DIR/async-generics.rs:9:18
    |
 LL |     async fn foo(&self) -> &(T, U);
-   |                  ^
+   |                  ^^^^^
 note: ...so that the reference type `&(T, U)` does not outlive the data it points at
   --> $DIR/async-generics.rs:9:28
    |
@@ -21,11 +21,11 @@ error[E0311]: the parameter type `T` may not live long enough
 LL |     async fn foo(&self) -> &(T, U);
    |                            ^^^^^^^
    |
-note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
   --> $DIR/async-generics.rs:9:18
    |
 LL |     async fn foo(&self) -> &(T, U);
-   |                  ^
+   |                  ^^^^^
 note: ...so that the reference type `&(T, U)` does not outlive the data it points at
   --> $DIR/async-generics.rs:9:28
    |
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs
index 3f7448cecd1..d5481d277e4 100644
--- a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs
+++ b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs
@@ -1,5 +1,4 @@
-// check-fail
-// known-bug: #102682
+// check-pass
 // edition: 2021
 
 #![feature(async_fn_in_trait)]
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr
deleted file mode 100644
index 0f024202743..00000000000
--- a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0309]: the parameter type `Self` may not live long enough
-  --> $DIR/async-lifetimes-and-bounds.rs:11:43
-   |
-LL |     async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized;
-   |                                           ^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `Self: 'a`...
-   = note: ...so that the reference type `&'a Self` does not outlive the data it points at
-
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/async-lifetimes-and-bounds.rs:11:43
-   |
-LL |     async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized;
-   |                                           ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at
-   |
-help: consider adding an explicit lifetime bound...
-   |
-LL | trait MyTrait<'a, 'b, T: 'b> {
-   |                        ++++
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.rs b/src/test/ui/async-await/in-trait/async-lifetimes.rs
index acbac471cf7..f298e45d239 100644
--- a/src/test/ui/async-await/in-trait/async-lifetimes.rs
+++ b/src/test/ui/async-await/in-trait/async-lifetimes.rs
@@ -1,5 +1,4 @@
-// check-fail
-// known-bug: #102682
+// check-pass
 // edition: 2021
 
 #![feature(async_fn_in_trait)]
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.stderr b/src/test/ui/async-await/in-trait/async-lifetimes.stderr
deleted file mode 100644
index 9a7d294bb17..00000000000
--- a/src/test/ui/async-await/in-trait/async-lifetimes.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0309]: the parameter type `Self` may not live long enough
-  --> $DIR/async-lifetimes.rs:9:43
-   |
-LL |     async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
-   |                                           ^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `Self: 'a`...
-   = note: ...so that the reference type `&'a Self` does not outlive the data it points at
-
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/async-lifetimes.rs:9:43
-   |
-LL |     async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
-   |                                           ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at
-   |
-help: consider adding an explicit lifetime bound...
-   |
-LL | trait MyTrait<'a, 'b, T: 'b> {
-   |                        ++++
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/async-await/in-trait/implied-bounds.rs b/src/test/ui/async-await/in-trait/implied-bounds.rs
new file mode 100644
index 00000000000..52bceb3cc5c
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/implied-bounds.rs
@@ -0,0 +1,13 @@
+// check-pass
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait TcpStack {
+    type Connection<'a>: Sized where Self: 'a;
+    fn connect<'a>(&'a self) -> Self::Connection<'a>;
+    async fn async_connect<'a>(&'a self) -> Self::Connection<'a>;
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/lifetime-mismatch.rs b/src/test/ui/async-await/in-trait/lifetime-mismatch.rs
new file mode 100644
index 00000000000..45ede193c0f
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/lifetime-mismatch.rs
@@ -0,0 +1,20 @@
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+
+trait MyTrait {
+    async fn foo<'a>(&self);
+    async fn bar(&self);
+}
+
+impl MyTrait for i32 {
+    async fn foo(&self) {}
+    //~^ ERROR lifetime parameters or bounds on method `foo` do not match the trait declaration
+
+    async fn bar(&self) {
+        self.foo();
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/lifetime-mismatch.stderr b/src/test/ui/async-await/in-trait/lifetime-mismatch.stderr
new file mode 100644
index 00000000000..d87adcc78b6
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/lifetime-mismatch.stderr
@@ -0,0 +1,21 @@
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/lifetime-mismatch.rs:3:12
+   |
+LL | #![feature(async_fn_in_trait)]
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
+  --> $DIR/lifetime-mismatch.rs:12:17
+   |
+LL |     async fn foo<'a>(&self);
+   |                 ---- lifetimes in impl do not match this method in trait
+...
+LL |     async fn foo(&self) {}
+   |                 ^ lifetimes do not match method in trait
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0195`.
diff --git a/src/test/ui/attributes/unused-item-in-attr.rs b/src/test/ui/attributes/unused-item-in-attr.rs
new file mode 100644
index 00000000000..70dcd5413f1
--- /dev/null
+++ b/src/test/ui/attributes/unused-item-in-attr.rs
@@ -0,0 +1,6 @@
+#[w = { extern crate alloc; }]
+//~^ ERROR unexpected expression: `{
+//~| ERROR cannot find attribute `w` in this scope
+fn f() {}
+
+fn main() {}
diff --git a/src/test/ui/attributes/unused-item-in-attr.stderr b/src/test/ui/attributes/unused-item-in-attr.stderr
new file mode 100644
index 00000000000..92a8f585821
--- /dev/null
+++ b/src/test/ui/attributes/unused-item-in-attr.stderr
@@ -0,0 +1,16 @@
+error: unexpected expression: `{
+           extern crate alloc;
+       }`
+  --> $DIR/unused-item-in-attr.rs:1:7
+   |
+LL | #[w = { extern crate alloc; }]
+   |       ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot find attribute `w` in this scope
+  --> $DIR/unused-item-in-attr.rs:1:3
+   |
+LL | #[w = { extern crate alloc; }]
+   |   ^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/drop/drop_order.rs b/src/test/ui/drop/drop_order.rs
index 42385216ae7..5ce1fd54a9e 100644
--- a/src/test/ui/drop/drop_order.rs
+++ b/src/test/ui/drop/drop_order.rs
@@ -43,7 +43,7 @@ impl DropOrderCollector {
         }
 
         if {
-            if self.option_loud_drop(7).is_some() && self.option_loud_drop(6).is_some() {
+            if self.option_loud_drop(6).is_some() && self.option_loud_drop(7).is_some() {
                 self.loud_drop(8);
                 true
             } else {
@@ -118,17 +118,85 @@ impl DropOrderCollector {
         }
     }
 
+    fn and_chain(&self) {
+        // issue-103107
+        if self.option_loud_drop(1).is_some() // 1
+            && self.option_loud_drop(2).is_some() // 2
+            && self.option_loud_drop(3).is_some() // 3
+            && self.option_loud_drop(4).is_some() // 4
+            && self.option_loud_drop(5).is_some() // 5
+        {
+            self.print(6); // 6
+        }
+
+        let _ = self.option_loud_drop(7).is_some() // 1
+            && self.option_loud_drop(8).is_some() // 2
+            && self.option_loud_drop(9).is_some(); // 3
+        self.print(10); // 4
+
+        // Test associativity
+        if self.option_loud_drop(11).is_some() // 1
+            && (self.option_loud_drop(12).is_some() // 2
+            && self.option_loud_drop(13).is_some() // 3
+            && self.option_loud_drop(14).is_some()) // 4
+            && self.option_loud_drop(15).is_some() // 5
+        {
+            self.print(16); // 6
+        }
+    }
+
+    fn or_chain(&self) {
+        // issue-103107
+        if self.option_loud_drop(1).is_none() // 1
+            || self.option_loud_drop(2).is_none() // 2
+            || self.option_loud_drop(3).is_none() // 3
+            || self.option_loud_drop(4).is_none() // 4
+            || self.option_loud_drop(5).is_some() // 5
+        {
+            self.print(6); // 6
+        }
+
+        let _ = self.option_loud_drop(7).is_none() // 1
+            || self.option_loud_drop(8).is_none() // 2
+            || self.option_loud_drop(9).is_none(); // 3
+        self.print(10); // 4
+
+        // Test associativity
+        if self.option_loud_drop(11).is_none() // 1
+            || (self.option_loud_drop(12).is_none() // 2
+            || self.option_loud_drop(13).is_none() // 3
+            || self.option_loud_drop(14).is_none()) // 4
+            || self.option_loud_drop(15).is_some() // 5
+        {
+            self.print(16); // 6
+        }
+    }
+
+    fn mixed_and_or_chain(&self) {
+        // issue-103107
+        if self.option_loud_drop(1).is_none() // 1
+            || self.option_loud_drop(2).is_none() // 2
+            || self.option_loud_drop(3).is_some() // 3
+            && self.option_loud_drop(4).is_some() // 4
+            && self.option_loud_drop(5).is_none() // 5
+            || self.option_loud_drop(6).is_none() // 6
+            || self.option_loud_drop(7).is_some() // 7
+        {
+            self.print(8); // 8
+        }
+    }
+
     fn let_chain(&self) {
         // take the "then" branch
-        if self.option_loud_drop(2).is_some() // 2
-            && self.option_loud_drop(1).is_some() // 1
+        if self.option_loud_drop(1).is_some() // 1
+            && self.option_loud_drop(2).is_some() // 2
             && let Some(_d) = self.option_loud_drop(4) { // 4
             self.print(3); // 3
         }
 
         // take the "else" branch
-        if self.option_loud_drop(6).is_some() // 2
-            && self.option_loud_drop(5).is_some() // 1
+        if self.option_loud_drop(5).is_some() // 1
+            && self.option_loud_drop(6).is_some() // 2
             && let None = self.option_loud_drop(8) { // 4
             unreachable!();
         } else {
@@ -152,8 +220,8 @@ impl DropOrderCollector {
             }
 
         // let exprs last
-        if self.option_loud_drop(20).is_some() // 2
-            && self.option_loud_drop(19).is_some() // 1
+        if self.option_loud_drop(19).is_some() // 1
+            && self.option_loud_drop(20).is_some() // 2
             && let Some(_d) = self.option_loud_drop(23) // 5
             && let Some(_e) = self.option_loud_drop(22) { // 4
                 self.print(21); // 3
@@ -187,6 +255,21 @@ fn main() {
     collector.if_();
     collector.assert_sorted();
 
+    println!("-- and chain --");
+    let collector = DropOrderCollector::default();
+    collector.and_chain();
+    collector.assert_sorted();
+
+    println!("-- or chain --");
+    let collector = DropOrderCollector::default();
+    collector.or_chain();
+    collector.assert_sorted();
+
+    println!("-- mixed and/or chain --");
+    let collector = DropOrderCollector::default();
+    collector.mixed_and_or_chain();
+    collector.assert_sorted();
+
     println!("-- if let --");
     let collector = DropOrderCollector::default();
     collector.if_let();
diff --git a/src/test/ui/drop/issue-103107.rs b/src/test/ui/drop/issue-103107.rs
new file mode 100644
index 00000000000..5f447595662
--- /dev/null
+++ b/src/test/ui/drop/issue-103107.rs
@@ -0,0 +1,37 @@
+// check-pass
+// compile-flags: -Z validate-mir
+
+struct Foo<'a>(&'a mut u32);
+
+impl<'a> Drop for Foo<'a> {
+    fn drop(&mut self) {
+        *self.0 = 0;
+    }
+}
+
+fn and() {
+    let mut foo = 0;
+    // This used to compile also before the fix
+    if true && *Foo(&mut foo).0 == 0 && ({ foo = 0; true}) {}
+
+    // This used to fail before the fix
+    if *Foo(&mut foo).0 == 0 && ({ foo = 0; true}) {}
+
+    println!("{foo}");
+}
+
+fn or() {
+    let mut foo = 0;
+    // This used to compile also before the fix
+    if false || *Foo(&mut foo).0 == 1 || ({ foo = 0; true}) {}
+
+    // This used to fail before the fix
+    if *Foo(&mut foo).0 == 1 || ({ foo = 0; true}) {}
+
+    println!("{foo}");
+}
+
+fn main() {
+    and();
+    or();
+}
diff --git a/src/test/ui/enum-discriminant/issue-104519.rs b/src/test/ui/enum-discriminant/issue-104519.rs
new file mode 100644
index 00000000000..c4630f76b3a
--- /dev/null
+++ b/src/test/ui/enum-discriminant/issue-104519.rs
@@ -0,0 +1,36 @@
+// run-pass
+#![allow(dead_code)]
+
+enum OpenResult {
+    Ok(()),
+    Err(()),
+    TransportErr(TransportErr),
+}
+
+#[repr(i32)]
+enum TransportErr {
+    UnknownMethod = -2,
+}
+
+#[inline(never)]
+fn some_match(result: OpenResult) -> u8 {
+    match result {
+        OpenResult::Ok(()) => 0,
+        _ => 1,
+    }
+}
+
+fn main() {
+    let result = OpenResult::Ok(());
+    assert_eq!(some_match(result), 0);
+
+    let result = OpenResult::Ok(());
+    match result {
+        OpenResult::Ok(()) => (),
+        _ => unreachable!("message a"),
+    }
+    match result {
+        OpenResult::Ok(()) => (),
+        _ => unreachable!("message b"),
+    }
+}
diff --git a/src/test/ui/fn/signature-error-reporting-under-verbose.rs b/src/test/ui/fn/signature-error-reporting-under-verbose.rs
new file mode 100644
index 00000000000..d7a8c95e8b2
--- /dev/null
+++ b/src/test/ui/fn/signature-error-reporting-under-verbose.rs
@@ -0,0 +1,15 @@
+// compile-flags: -Zverbose
+
+fn foo(_: i32, _: i32) {}
+
+fn needs_ptr(_: fn(i32, u32)) {}
+//~^ NOTE function defined here
+//~| NOTE
+
+fn main() {
+    needs_ptr(foo);
+    //~^ ERROR mismatched types
+    //~| NOTE expected `u32`, found `i32`
+    //~| NOTE expected fn pointer `fn(i32, u32)`
+    //~| NOTE arguments to this function are incorrect
+}
diff --git a/src/test/ui/fn/signature-error-reporting-under-verbose.stderr b/src/test/ui/fn/signature-error-reporting-under-verbose.stderr
new file mode 100644
index 00000000000..6260fc8dcec
--- /dev/null
+++ b/src/test/ui/fn/signature-error-reporting-under-verbose.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+  --> $DIR/signature-error-reporting-under-verbose.rs:10:15
+   |
+LL |     needs_ptr(foo);
+   |     --------- ^^^ expected `u32`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected fn pointer `fn(i32, u32)`
+                 found fn item `fn(i32, i32) {foo}`
+note: function defined here
+  --> $DIR/signature-error-reporting-under-verbose.rs:5:4
+   |
+LL | fn needs_ptr(_: fn(i32, u32)) {}
+   |    ^^^^^^^^^ ---------------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/impl-trait/in-trait/where-clause.rs b/src/test/ui/impl-trait/in-trait/where-clause.rs
new file mode 100644
index 00000000000..87bac519cf3
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/where-clause.rs
@@ -0,0 +1,24 @@
+// check-pass
+// edition: 2021
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait Foo<Item> {
+    fn foo<'a>(&'a self) -> impl Debug
+    where
+        Item: 'a;
+}
+
+impl<Item, D: Debug + Clone> Foo<Item> for D {
+    fn foo<'a>(&'a self) -> impl Debug
+    where
+        Item: 'a,
+    {
+        self.clone()
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/inline-const/expr-with-block-err.rs b/src/test/ui/inline-const/expr-with-block-err.rs
new file mode 100644
index 00000000000..f7547742ddc
--- /dev/null
+++ b/src/test/ui/inline-const/expr-with-block-err.rs
@@ -0,0 +1,6 @@
+#![feature(inline_const)]
+
+fn main() {
+    const { 2 } - const { 1 };
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/inline-const/expr-with-block-err.stderr b/src/test/ui/inline-const/expr-with-block-err.stderr
new file mode 100644
index 00000000000..6f7408f4e2a
--- /dev/null
+++ b/src/test/ui/inline-const/expr-with-block-err.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+  --> $DIR/expr-with-block-err.rs:4:13
+   |
+LL |     const { 2 } - const { 1 };
+   |             ^ expected `()`, found integer
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/inline-const/expr-with-block.rs b/src/test/ui/inline-const/expr-with-block.rs
new file mode 100644
index 00000000000..391872476fc
--- /dev/null
+++ b/src/test/ui/inline-const/expr-with-block.rs
@@ -0,0 +1,10 @@
+// check-pass
+#![feature(inline_const)]
+fn main() {
+    match true {
+        true => const {}
+        false => ()
+    }
+    const {}
+    ()
+}
diff --git a/src/test/ui/issues/issue-35976.rs b/src/test/ui/issues/issue-35976.rs
index d075794d994..aa6f74cb5d4 100644
--- a/src/test/ui/issues/issue-35976.rs
+++ b/src/test/ui/issues/issue-35976.rs
@@ -1,5 +1,9 @@
+// revisions: imported unimported
+//[imported] check-pass
+
 mod private {
     pub trait Future {
+        //[unimported]~^^ HELP perhaps add a `use` for it
         fn wait(&self) where Self: Sized;
     }
 
@@ -8,13 +12,13 @@ mod private {
     }
 }
 
-//use private::Future;
+#[cfg(imported)]
+use private::Future;
 
 fn bar(arg: Box<dyn private::Future>) {
+    // Importing the trait means that we don't autoderef `Box<dyn Future>`
     arg.wait();
-    //~^ ERROR the `wait` method cannot be invoked on a trait object
+    //[unimported]~^ ERROR the `wait` method cannot be invoked on a trait object
 }
 
-fn main() {
-
-}
+fn main() {}
diff --git a/src/test/ui/issues/issue-35976.stderr b/src/test/ui/issues/issue-35976.unimported.stderr
index fe16f97b9d0..5d61bb8ea37 100644
--- a/src/test/ui/issues/issue-35976.stderr
+++ b/src/test/ui/issues/issue-35976.unimported.stderr
@@ -1,11 +1,16 @@
 error: the `wait` method cannot be invoked on a trait object
-  --> $DIR/issue-35976.rs:14:9
+  --> $DIR/issue-35976.rs:20:9
    |
 LL |         fn wait(&self) where Self: Sized;
    |                                    ----- this has a `Sized` requirement
 ...
 LL |     arg.wait();
    |         ^^^^
+   |
+help: another candidate was found in the following trait, perhaps add a `use` for it:
+   |
+LL | use private::Future;
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/issue-97094.nointerleaved.stderr b/src/test/ui/lint/issue-97094.nointerleaved.stderr
deleted file mode 100644
index a2581658920..00000000000
--- a/src/test/ui/lint/issue-97094.nointerleaved.stderr
+++ /dev/null
@@ -1,53 +0,0 @@
-error: unknown lint: `nonex_lint_top_level`
-  --> $DIR/issue-97094.rs:14:26
-   |
-LL | #![cfg_attr(all(), allow(nonex_lint_top_level))]
-   |                          ^^^^^^^^^^^^^^^^^^^^
-   |
-note: the lint level is defined here
-  --> $DIR/issue-97094.rs:10:9
-   |
-LL | #![deny(warnings)]
-   |         ^^^^^^^^
-   = note: `#[deny(unknown_lints)]` implied by `#[deny(warnings)]`
-
-error: lint `bare_trait_object` has been renamed to `bare_trait_objects`
-  --> $DIR/issue-97094.rs:16:26
-   |
-LL | #![cfg_attr(all(), allow(bare_trait_object))]
-   |                          ^^^^^^^^^^^^^^^^^ help: use the new name: `bare_trait_objects`
-   |
-   = note: `#[deny(renamed_and_removed_lints)]` implied by `#[deny(warnings)]`
-
-error: unknown lint: `nonex_lint_mod`
-  --> $DIR/issue-97094.rs:19:25
-   |
-LL | #[cfg_attr(all(), allow(nonex_lint_mod))]
-   |                         ^^^^^^^^^^^^^^
-
-error: unknown lint: `nonex_lint_mod_inner`
-  --> $DIR/issue-97094.rs:22:30
-   |
-LL |     #![cfg_attr(all(), allow(nonex_lint_mod_inner))]
-   |                              ^^^^^^^^^^^^^^^^^^^^
-
-error: unknown lint: `nonex_lint_fn`
-  --> $DIR/issue-97094.rs:26:25
-   |
-LL | #[cfg_attr(all(), allow(nonex_lint_fn))]
-   |                         ^^^^^^^^^^^^^
-
-error: unknown lint: `nonex_lint_in_macro`
-  --> $DIR/issue-97094.rs:37:29
-   |
-LL |     #[cfg_attr(all(), allow(nonex_lint_in_macro))]
-   |                             ^^^^^^^^^^^^^^^^^^^
-
-error: unknown lint: `nonex_lint_fn`
-  --> $DIR/issue-97094.rs:56:13
-   |
-LL |     #[allow(nonex_lint_fn)]
-   |             ^^^^^^^^^^^^^
-
-error: aborting due to 7 previous errors
-
diff --git a/src/test/ui/lint/issue-97094.rs b/src/test/ui/lint/issue-97094.rs
index aeaead1bd11..22525ca11ae 100644
--- a/src/test/ui/lint/issue-97094.rs
+++ b/src/test/ui/lint/issue-97094.rs
@@ -1,12 +1,3 @@
-// revisions: interleaved nointerleaved
-// [nointerleaved]compile-flags: -Z no-interleave-lints
-
-// This test has two revisions because the logic change
-// needed to make this test pass had to be adjusted
-// for no-interleave-lints. Should the debug option
-// be removed one day, please don't remove this
-// test entirely, just remove the revision from it.
-
 #![deny(warnings)]
 
 // Ensure that unknown lints inside cfg-attr's are linted for
diff --git a/src/test/ui/lint/issue-97094.interleaved.stderr b/src/test/ui/lint/issue-97094.stderr
index a2581658920..1a0a3eaf250 100644
--- a/src/test/ui/lint/issue-97094.interleaved.stderr
+++ b/src/test/ui/lint/issue-97094.stderr
@@ -1,18 +1,18 @@
 error: unknown lint: `nonex_lint_top_level`
-  --> $DIR/issue-97094.rs:14:26
+  --> $DIR/issue-97094.rs:5:26
    |
 LL | #![cfg_attr(all(), allow(nonex_lint_top_level))]
    |                          ^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/issue-97094.rs:10:9
+  --> $DIR/issue-97094.rs:1:9
    |
 LL | #![deny(warnings)]
    |         ^^^^^^^^
    = note: `#[deny(unknown_lints)]` implied by `#[deny(warnings)]`
 
 error: lint `bare_trait_object` has been renamed to `bare_trait_objects`
-  --> $DIR/issue-97094.rs:16:26
+  --> $DIR/issue-97094.rs:7:26
    |
 LL | #![cfg_attr(all(), allow(bare_trait_object))]
    |                          ^^^^^^^^^^^^^^^^^ help: use the new name: `bare_trait_objects`
@@ -20,31 +20,31 @@ LL | #![cfg_attr(all(), allow(bare_trait_object))]
    = note: `#[deny(renamed_and_removed_lints)]` implied by `#[deny(warnings)]`
 
 error: unknown lint: `nonex_lint_mod`
-  --> $DIR/issue-97094.rs:19:25
+  --> $DIR/issue-97094.rs:10:25
    |
 LL | #[cfg_attr(all(), allow(nonex_lint_mod))]
    |                         ^^^^^^^^^^^^^^
 
 error: unknown lint: `nonex_lint_mod_inner`
-  --> $DIR/issue-97094.rs:22:30
+  --> $DIR/issue-97094.rs:13:30
    |
 LL |     #![cfg_attr(all(), allow(nonex_lint_mod_inner))]
    |                              ^^^^^^^^^^^^^^^^^^^^
 
 error: unknown lint: `nonex_lint_fn`
-  --> $DIR/issue-97094.rs:26:25
+  --> $DIR/issue-97094.rs:17:25
    |
 LL | #[cfg_attr(all(), allow(nonex_lint_fn))]
    |                         ^^^^^^^^^^^^^
 
 error: unknown lint: `nonex_lint_in_macro`
-  --> $DIR/issue-97094.rs:37:29
+  --> $DIR/issue-97094.rs:28:29
    |
 LL |     #[cfg_attr(all(), allow(nonex_lint_in_macro))]
    |                             ^^^^^^^^^^^^^^^^^^^
 
 error: unknown lint: `nonex_lint_fn`
-  --> $DIR/issue-97094.rs:56:13
+  --> $DIR/issue-97094.rs:47:13
    |
 LL |     #[allow(nonex_lint_fn)]
    |             ^^^^^^^^^^^^^
diff --git a/src/test/ui/macros/issue-103529.rs b/src/test/ui/macros/issue-103529.rs
new file mode 100644
index 00000000000..fa05baed7fc
--- /dev/null
+++ b/src/test/ui/macros/issue-103529.rs
@@ -0,0 +1,13 @@
+macro_rules! m {
+    ($s:stmt) => {}
+}
+
+m! { mut x }
+//~^ ERROR expected expression, found keyword `mut`
+//~| ERROR expected a statement
+m! { auto x }
+//~^ ERROR invalid variable declaration
+m! { var x }
+//~^ ERROR invalid variable declaration
+
+fn main() {}
diff --git a/src/test/ui/macros/issue-103529.stderr b/src/test/ui/macros/issue-103529.stderr
new file mode 100644
index 00000000000..61e322afc77
--- /dev/null
+++ b/src/test/ui/macros/issue-103529.stderr
@@ -0,0 +1,39 @@
+error: expected expression, found keyword `mut`
+  --> $DIR/issue-103529.rs:5:6
+   |
+LL | m! { mut x }
+   |      ^^^ expected expression
+
+error: expected a statement
+  --> $DIR/issue-103529.rs:5:10
+   |
+LL |     ($s:stmt) => {}
+   |      ------- while parsing argument for this `stmt` macro fragment
+...
+LL | m! { mut x }
+   |          ^
+
+error: invalid variable declaration
+  --> $DIR/issue-103529.rs:8:6
+   |
+LL | m! { auto x }
+   |      ^^^^
+   |
+help: write `let` instead of `auto` to introduce a new variable
+   |
+LL | m! { let x }
+   |      ~~~
+
+error: invalid variable declaration
+  --> $DIR/issue-103529.rs:10:6
+   |
+LL | m! { var x }
+   |      ^^^
+   |
+help: write `let` instead of `var` to introduce a new variable
+   |
+LL | m! { let x }
+   |      ~~~
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/query-system/fn-sig-cycle-arity.rs b/src/test/ui/query-system/fn-sig-cycle-arity.rs
new file mode 100644
index 00000000000..7a9b8469c9e
--- /dev/null
+++ b/src/test/ui/query-system/fn-sig-cycle-arity.rs
@@ -0,0 +1,8 @@
+trait Dancer {
+    fn dance(&self) -> _ {
+        //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
+        self.dance()
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/query-system/fn-sig-cycle-arity.stderr b/src/test/ui/query-system/fn-sig-cycle-arity.stderr
new file mode 100644
index 00000000000..67e0c254551
--- /dev/null
+++ b/src/test/ui/query-system/fn-sig-cycle-arity.stderr
@@ -0,0 +1,9 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+  --> $DIR/fn-sig-cycle-arity.rs:2:24
+   |
+LL |     fn dance(&self) -> _ {
+   |                        ^ not allowed in type signatures
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/resolve/bad-module.stderr b/src/test/ui/resolve/bad-module.stderr
index 581a6619814..558760c6793 100644
--- a/src/test/ui/resolve/bad-module.stderr
+++ b/src/test/ui/resolve/bad-module.stderr
@@ -1,15 +1,15 @@
-error[E0433]: failed to resolve: use of undeclared crate or module `thing`
-  --> $DIR/bad-module.rs:2:15
-   |
-LL |     let foo = thing::len(Vec::new());
-   |               ^^^^^ use of undeclared crate or module `thing`
-
 error[E0433]: failed to resolve: use of undeclared crate or module `foo`
   --> $DIR/bad-module.rs:5:15
    |
 LL |     let foo = foo::bar::baz();
    |               ^^^ use of undeclared crate or module `foo`
 
+error[E0433]: failed to resolve: use of undeclared crate or module `thing`
+  --> $DIR/bad-module.rs:2:15
+   |
+LL |     let foo = thing::len(Vec::new());
+   |               ^^^^^ use of undeclared crate or module `thing`
+
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/resolve/issue-101749-2.rs b/src/test/ui/resolve/issue-101749-2.rs
new file mode 100644
index 00000000000..4d3d469447c
--- /dev/null
+++ b/src/test/ui/resolve/issue-101749-2.rs
@@ -0,0 +1,16 @@
+struct Rectangle {
+    width: i32,
+    height: i32,
+}
+impl Rectangle {
+    fn new(width: i32, height: i32) -> Self {
+        Self { width, height }
+    }
+}
+
+fn main() {
+    let rect = Rectangle::new(3, 4);
+    // `area` is not implemented for `Rectangle`, so this should not suggest
+    let _ = rect::area();
+    //~^ ERROR failed to resolve: use of undeclared crate or module `rect`
+}
diff --git a/src/test/ui/resolve/issue-101749-2.stderr b/src/test/ui/resolve/issue-101749-2.stderr
new file mode 100644
index 00000000000..370d4b14540
--- /dev/null
+++ b/src/test/ui/resolve/issue-101749-2.stderr
@@ -0,0 +1,9 @@
+error[E0433]: failed to resolve: use of undeclared crate or module `rect`
+  --> $DIR/issue-101749-2.rs:14:13
+   |
+LL |     let _ = rect::area();
+   |             ^^^^ use of undeclared crate or module `rect`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/resolve/issue-101749.fixed b/src/test/ui/resolve/issue-101749.fixed
new file mode 100644
index 00000000000..3e5544296e4
--- /dev/null
+++ b/src/test/ui/resolve/issue-101749.fixed
@@ -0,0 +1,19 @@
+// run-rustfix
+struct Rectangle {
+    width: i32,
+    height: i32,
+}
+impl Rectangle {
+    fn new(width: i32, height: i32) -> Self {
+        Self { width, height }
+    }
+    fn area(&self) -> i32 {
+        self.height * self.width
+    }
+}
+
+fn main() {
+    let rect = Rectangle::new(3, 4);
+    let _ = rect.area();
+    //~^ ERROR failed to resolve: use of undeclared crate or module `rect`
+}
diff --git a/src/test/ui/resolve/issue-101749.rs b/src/test/ui/resolve/issue-101749.rs
new file mode 100644
index 00000000000..fd67ccab6fa
--- /dev/null
+++ b/src/test/ui/resolve/issue-101749.rs
@@ -0,0 +1,19 @@
+// run-rustfix
+struct Rectangle {
+    width: i32,
+    height: i32,
+}
+impl Rectangle {
+    fn new(width: i32, height: i32) -> Self {
+        Self { width, height }
+    }
+    fn area(&self) -> i32 {
+        self.height * self.width
+    }
+}
+
+fn main() {
+    let rect = Rectangle::new(3, 4);
+    let _ = rect::area();
+    //~^ ERROR failed to resolve: use of undeclared crate or module `rect`
+}
diff --git a/src/test/ui/resolve/issue-101749.stderr b/src/test/ui/resolve/issue-101749.stderr
new file mode 100644
index 00000000000..dd29d7fc051
--- /dev/null
+++ b/src/test/ui/resolve/issue-101749.stderr
@@ -0,0 +1,14 @@
+error[E0433]: failed to resolve: use of undeclared crate or module `rect`
+  --> $DIR/issue-101749.rs:17:13
+   |
+LL |     let _ = rect::area();
+   |             ^^^^ use of undeclared crate or module `rect`
+   |
+help: you may have meant to call an instance method
+   |
+LL |     let _ = rect.area();
+   |                 ~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/resolve/issue-105069.rs b/src/test/ui/resolve/issue-105069.rs
new file mode 100644
index 00000000000..73455cf7711
--- /dev/null
+++ b/src/test/ui/resolve/issue-105069.rs
@@ -0,0 +1,11 @@
+use self::A::*;
+use V; //~ ERROR `V` is ambiguous
+use self::B::*;
+enum A {
+    V
+}
+enum B {
+    V
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/issue-105069.stderr b/src/test/ui/resolve/issue-105069.stderr
new file mode 100644
index 00000000000..1e6c9c6e2dc
--- /dev/null
+++ b/src/test/ui/resolve/issue-105069.stderr
@@ -0,0 +1,21 @@
+error[E0659]: `V` is ambiguous
+  --> $DIR/issue-105069.rs:2:5
+   |
+LL | use V;
+   |     ^ ambiguous name
+   |
+   = note: ambiguous because of multiple potential import sources
+note: `V` could refer to the variant imported here
+  --> $DIR/issue-105069.rs:1:5
+   |
+LL | use self::A::*;
+   |     ^^^^^^^^^^
+note: `V` could also refer to the variant imported here
+  --> $DIR/issue-105069.rs:3:5
+   |
+LL | use self::B::*;
+   |     ^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui/resolve/issue-24968.stderr b/src/test/ui/resolve/issue-24968.stderr
index 7e539d25804..82f5a1d5b57 100644
--- a/src/test/ui/resolve/issue-24968.stderr
+++ b/src/test/ui/resolve/issue-24968.stderr
@@ -1,15 +1,3 @@
-error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
-  --> $DIR/issue-24968.rs:21:19
-   |
-LL | const FOO2: u32 = Self::bar();
-   |                   ^^^^ `Self` is only available in impls, traits, and type definitions
-
-error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
-  --> $DIR/issue-24968.rs:27:22
-   |
-LL | static FOO_S2: u32 = Self::bar();
-   |                      ^^^^ `Self` is only available in impls, traits, and type definitions
-
 error[E0411]: cannot find type `Self` in this scope
   --> $DIR/issue-24968.rs:3:11
    |
@@ -51,6 +39,18 @@ LL | static FOO_S: Self = 0;
    |        |
    |        `Self` not allowed in a static item
 
+error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
+  --> $DIR/issue-24968.rs:21:19
+   |
+LL | const FOO2: u32 = Self::bar();
+   |                   ^^^^ `Self` is only available in impls, traits, and type definitions
+
+error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
+  --> $DIR/issue-24968.rs:27:22
+   |
+LL | static FOO_S2: u32 = Self::bar();
+   |                      ^^^^ `Self` is only available in impls, traits, and type definitions
+
 error: aborting due to 7 previous errors
 
 Some errors have detailed explanations: E0411, E0433.
diff --git a/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr b/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr
index ff7cf531c06..89b69e14099 100644
--- a/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr
+++ b/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr
@@ -1,3 +1,24 @@
+error[E0433]: failed to resolve: could not find `Struc` in `module`
+  --> $DIR/typo-suggestion-mistyped-in-path.rs:35:13
+   |
+LL |     module::Struc::foo();
+   |             ^^^^^
+   |             |
+   |             could not find `Struc` in `module`
+   |             help: a struct with a similar name exists: `Struct`
+
+error[E0599]: no function or associated item named `fob` found for struct `Struct` in the current scope
+  --> $DIR/typo-suggestion-mistyped-in-path.rs:23:13
+   |
+LL | struct Struct;
+   | ------------- function or associated item `fob` not found for this struct
+...
+LL |     Struct::fob();
+   |             ^^^
+   |             |
+   |             function or associated item not found in `Struct`
+   |             help: there is an associated function with a similar name: `foo`
+
 error[E0433]: failed to resolve: use of undeclared type `Struc`
   --> $DIR/typo-suggestion-mistyped-in-path.rs:27:5
    |
@@ -18,15 +39,6 @@ help: there is a crate or module with a similar name
 LL |     module::foo();
    |     ~~~~~~
 
-error[E0433]: failed to resolve: could not find `Struc` in `module`
-  --> $DIR/typo-suggestion-mistyped-in-path.rs:35:13
-   |
-LL |     module::Struc::foo();
-   |             ^^^^^
-   |             |
-   |             could not find `Struc` in `module`
-   |             help: a struct with a similar name exists: `Struct`
-
 error[E0433]: failed to resolve: use of undeclared type `Trai`
   --> $DIR/typo-suggestion-mistyped-in-path.rs:39:5
    |
@@ -36,18 +48,6 @@ LL |     Trai::foo();
    |     use of undeclared type `Trai`
    |     help: a trait with a similar name exists: `Trait`
 
-error[E0599]: no function or associated item named `fob` found for struct `Struct` in the current scope
-  --> $DIR/typo-suggestion-mistyped-in-path.rs:23:13
-   |
-LL | struct Struct;
-   | ------------- function or associated item `fob` not found for this struct
-...
-LL |     Struct::fob();
-   |             ^^^
-   |             |
-   |             function or associated item not found in `Struct`
-   |             help: there is an associated function with a similar name: `foo`
-
 error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0433, E0599.
diff --git a/src/test/ui/resolve/use_suggestion.stderr b/src/test/ui/resolve/use_suggestion.stderr
index 58cb659e822..54ad853831f 100644
--- a/src/test/ui/resolve/use_suggestion.stderr
+++ b/src/test/ui/resolve/use_suggestion.stderr
@@ -1,9 +1,3 @@
-error[E0433]: failed to resolve: use of undeclared type `GooMap`
-  --> $DIR/use_suggestion.rs:3:14
-   |
-LL |     let x2 = GooMap::new();
-   |              ^^^^^^ use of undeclared type `GooMap`
-
 error[E0433]: failed to resolve: use of undeclared type `HashMap`
   --> $DIR/use_suggestion.rs:2:14
    |
@@ -32,6 +26,12 @@ error[E0412]: cannot find type `GooMap` in this scope
 LL |     let y2: GooMap;
    |             ^^^^^^ not found in this scope
 
+error[E0433]: failed to resolve: use of undeclared type `GooMap`
+  --> $DIR/use_suggestion.rs:3:14
+   |
+LL |     let x2 = GooMap::new();
+   |              ^^^^^^ use of undeclared type `GooMap`
+
 error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0412, E0433.
diff --git a/src/test/ui/return/tail-expr-as-potential-return.rs b/src/test/ui/return/tail-expr-as-potential-return.rs
index 2c3610fb24d..f46e088b85f 100644
--- a/src/test/ui/return/tail-expr-as-potential-return.rs
+++ b/src/test/ui/return/tail-expr-as-potential-return.rs
@@ -12,7 +12,6 @@
 // edition:2018
 
 fn main() {
-    let _ = foo(true);
 }
 
 fn foo(x: bool) -> Result<f64, i32> {
@@ -30,3 +29,19 @@ async fn bar(x: bool) -> Result<f64, i32> {
     }
     Ok(42.0)
 }
+
+trait Identity {
+    type Out;
+}
+
+impl<T> Identity for T {
+    type Out = T;
+}
+
+async fn foo2() -> i32 {
+    if true {
+        1i32 //~ ERROR mismatched types
+            //| HELP you might have meant to return this value
+    }
+    0
+}
diff --git a/src/test/ui/return/tail-expr-as-potential-return.stderr b/src/test/ui/return/tail-expr-as-potential-return.stderr
index dec1cbc4624..9183b4599ba 100644
--- a/src/test/ui/return/tail-expr-as-potential-return.stderr
+++ b/src/test/ui/return/tail-expr-as-potential-return.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/tail-expr-as-potential-return.rs:28:9
+  --> $DIR/tail-expr-as-potential-return.rs:27:9
    |
 LL | /     if x {
 LL | |         Err(42)
@@ -16,7 +16,22 @@ LL |         return Err(42);
    |         ++++++        +
 
 error[E0308]: mismatched types
-  --> $DIR/tail-expr-as-potential-return.rs:20:9
+  --> $DIR/tail-expr-as-potential-return.rs:43:9
+   |
+LL | /     if true {
+LL | |         1i32
+   | |         ^^^^ expected `()`, found `i32`
+LL | |             //| HELP you might have meant to return this value
+LL | |     }
+   | |_____- expected this to be `()`
+   |
+help: you might have meant to return this value
+   |
+LL |         return 1i32;
+   |         ++++++     +
+
+error[E0308]: mismatched types
+  --> $DIR/tail-expr-as-potential-return.rs:19:9
    |
 LL | /     if x {
 LL | |         Err(42)
@@ -32,6 +47,6 @@ help: you might have meant to return this value
 LL |         return Err(42);
    |         ++++++        +
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-79450.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-79450.rs
new file mode 100644
index 00000000000..b604c65d751
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-79450.rs
@@ -0,0 +1,20 @@
+#![feature(const_fmt_arguments_new)]
+#![feature(const_trait_impl)]
+
+#[const_trait]
+trait Tr {
+    fn req(&self);
+
+    fn prov(&self) {
+        println!("lul"); //~ ERROR: cannot call non-const fn `_print` in constant functions
+        self.req();
+    }
+}
+
+struct S;
+
+impl const Tr for S {
+    fn req(&self) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-79450.stderr b/src/test/ui/rfc-2632-const-trait-impl/issue-79450.stderr
new file mode 100644
index 00000000000..082c0333fbf
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-79450.stderr
@@ -0,0 +1,12 @@
+error[E0015]: cannot call non-const fn `_print` in constant functions
+  --> $DIR/issue-79450.rs:9:9
+   |
+LL |         println!("lul");
+   |         ^^^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/suggestions/assoc-const-as-fn.rs b/src/test/ui/suggestions/assoc-const-as-fn.rs
new file mode 100644
index 00000000000..4b4595dd5e6
--- /dev/null
+++ b/src/test/ui/suggestions/assoc-const-as-fn.rs
@@ -0,0 +1,18 @@
+unsafe fn pointer(v: usize, w: u32) {}
+
+pub trait UniformScalar {}
+impl UniformScalar for u32 {}
+
+pub trait GlUniformScalar: UniformScalar {
+    const FACTORY: unsafe fn(usize, Self) -> ();
+}
+impl GlUniformScalar for u32 {
+    const FACTORY: unsafe fn(usize, Self) -> () = pointer;
+}
+
+pub fn foo<T: UniformScalar>(value: T) {
+    <T as GlUniformScalar>::FACTORY(1, value);
+    //~^ ERROR the trait bound `T: GlUniformScalar` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/assoc-const-as-fn.stderr b/src/test/ui/suggestions/assoc-const-as-fn.stderr
new file mode 100644
index 00000000000..fa740687858
--- /dev/null
+++ b/src/test/ui/suggestions/assoc-const-as-fn.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `T: GlUniformScalar` is not satisfied
+  --> $DIR/assoc-const-as-fn.rs:14:5
+   |
+LL |     <T as GlUniformScalar>::FACTORY(1, value);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `GlUniformScalar` is not implemented for `T`
+   |
+help: consider further restricting this bound
+   |
+LL | pub fn foo<T: UniformScalar + GlUniformScalar>(value: T) {
+   |                             +++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/crate-or-module-typo.stderr b/src/test/ui/suggestions/crate-or-module-typo.stderr
index e8250c9fa5f..98b88b4fb92 100644
--- a/src/test/ui/suggestions/crate-or-module-typo.stderr
+++ b/src/test/ui/suggestions/crate-or-module-typo.stderr
@@ -20,12 +20,6 @@ help: there is a crate or module with a similar name
 LL | use bar::bar;
    |     ~~~
 
-error[E0433]: failed to resolve: use of undeclared crate or module `bar`
-  --> $DIR/crate-or-module-typo.rs:6:20
-   |
-LL |     pub fn bar() { bar::baz(); }
-   |                    ^^^ use of undeclared crate or module `bar`
-
 error[E0433]: failed to resolve: use of undeclared crate or module `st`
   --> $DIR/crate-or-module-typo.rs:14:10
    |
@@ -37,6 +31,12 @@ help: there is a crate or module with a similar name
 LL |     bar: std::cell::Cell<bool>
    |          ~~~
 
+error[E0433]: failed to resolve: use of undeclared crate or module `bar`
+  --> $DIR/crate-or-module-typo.rs:6:20
+   |
+LL |     pub fn bar() { bar::baz(); }
+   |                    ^^^ use of undeclared crate or module `bar`
+
 error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0432, E0433.
diff --git a/src/test/ui/suggestions/dont-suggest-ufcs-for-const.stderr b/src/test/ui/suggestions/dont-suggest-ufcs-for-const.stderr
index 04e0511d788..0d9543e0b8f 100644
--- a/src/test/ui/suggestions/dont-suggest-ufcs-for-const.stderr
+++ b/src/test/ui/suggestions/dont-suggest-ufcs-for-const.stderr
@@ -2,13 +2,7 @@ error[E0599]: no method named `MAX` found for type `u32` in the current scope
   --> $DIR/dont-suggest-ufcs-for-const.rs:2:11
    |
 LL |     1_u32.MAX();
-   |     ------^^^--
-   |     |     |
-   |     |     this is an associated function, not a method
-   |     help: use associated function syntax instead: `u32::MAX()`
-   |
-   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
-   = note: the candidate is defined in an impl for the type `u32`
+   |           ^^^ method not found in `u32`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/trait-bounds/impl-bound-with-references-error.rs b/src/test/ui/trait-bounds/impl-bound-with-references-error.rs
new file mode 100644
index 00000000000..e5d0a1aaed0
--- /dev/null
+++ b/src/test/ui/trait-bounds/impl-bound-with-references-error.rs
@@ -0,0 +1,20 @@
+// Regression test for #105138.
+// This test ensures that the compiler does not add note
+// for implementation of trait whose inner type is erroneous.
+
+pub enum LabelText {
+    Plain,
+}
+
+impl<T> From<T> for LabelText
+//~^ ERROR conflicting implementations of trait `From<LabelText>` for type `LabelText` [E0119]
+where
+    T: Into<Cow<'static, str>>,
+    //~^ ERROR cannot find type `Cow` in this scope [E0412]
+{
+    fn from(text: T) -> Self {
+        LabelText::Plain(text.into())
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/trait-bounds/impl-bound-with-references-error.stderr b/src/test/ui/trait-bounds/impl-bound-with-references-error.stderr
new file mode 100644
index 00000000000..95fd6bd504c
--- /dev/null
+++ b/src/test/ui/trait-bounds/impl-bound-with-references-error.stderr
@@ -0,0 +1,24 @@
+error[E0412]: cannot find type `Cow` in this scope
+  --> $DIR/impl-bound-with-references-error.rs:12:13
+   |
+LL |     T: Into<Cow<'static, str>>,
+   |             ^^^ not found in this scope
+   |
+help: consider importing this enum
+   |
+LL | use std::borrow::Cow;
+   |
+
+error[E0119]: conflicting implementations of trait `From<LabelText>` for type `LabelText`
+  --> $DIR/impl-bound-with-references-error.rs:9:1
+   |
+LL | impl<T> From<T> for LabelText
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<T> From<T> for T;
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0119, E0412.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject e027c4b5d25af2119b1956fac42863b9b324274
+Subproject f6e737b1e3386adb89333bf06a01f68a91ac530
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 519da685f94..91c701a5ddd 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -514,6 +514,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
         options: test::Options::new(),
         time_options: None,
         force_run_in_process: false,
+        fail_fast: std::env::var_os("RUSTC_TEST_FAIL_FAST").is_some(),
     }
 }
 
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
index 5046ab9c7cb..e15f5fe3ccc 100644
--- a/src/tools/jsondoclint/src/validator.rs
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -60,6 +60,8 @@ impl<'a> Validator<'a> {
 
     fn check_item(&mut self, id: &'a Id) {
         if let Some(item) = &self.krate.index.get(id) {
+            item.links.values().for_each(|id| self.add_any_id(id));
+
             match &item.inner {
                 ItemEnum::Import(x) => self.check_import(x),
                 ItemEnum::Union(x) => self.check_union(x),
@@ -376,6 +378,10 @@ impl<'a> Validator<'a> {
         }
     }
 
+    fn add_any_id(&mut self, id: &'a Id) {
+        self.add_id_checked(id, |_| true, "any kind of item");
+    }
+
     fn add_field_id(&mut self, id: &'a Id) {
         self.add_id_checked(id, Kind::is_struct_field, "StructField");
     }
@@ -446,3 +452,6 @@ fn set_remove<T: Hash + Eq + Clone>(set: &mut HashSet<T>) -> Option<T> {
         None
     }
 }
+
+#[cfg(test)]
+mod tests;
diff --git a/src/tools/jsondoclint/src/validator/tests.rs b/src/tools/jsondoclint/src/validator/tests.rs
new file mode 100644
index 00000000000..c4aeee9c53b
--- /dev/null
+++ b/src/tools/jsondoclint/src/validator/tests.rs
@@ -0,0 +1,50 @@
+use std::collections::HashMap;
+
+use rustdoc_json_types::{Crate, Item, Visibility};
+
+use super::*;
+
+#[track_caller]
+fn check(krate: &Crate, errs: &[Error]) {
+    let mut validator = Validator::new(krate);
+    validator.check_crate();
+
+    assert_eq!(errs, &validator.errs[..]);
+}
+
+fn id(s: &str) -> Id {
+    Id(s.to_owned())
+}
+
+#[test]
+fn errors_on_missing_links() {
+    let k = Crate {
+        root: id("0"),
+        crate_version: None,
+        includes_private: false,
+        index: HashMap::from_iter([(
+            id("0"),
+            Item {
+                name: Some("root".to_owned()),
+                id: id(""),
+                crate_id: 0,
+                span: None,
+                visibility: Visibility::Public,
+                docs: None,
+                links: HashMap::from_iter([("Not Found".to_owned(), id("1"))]),
+                attrs: vec![],
+                deprecation: None,
+                inner: ItemEnum::Module(Module {
+                    is_crate: true,
+                    items: vec![],
+                    is_stripped: false,
+                }),
+            },
+        )]),
+        paths: HashMap::new(),
+        external_crates: HashMap::new(),
+        format_version: rustdoc_json_types::FORMAT_VERSION,
+    };
+
+    check(&k, &[Error { kind: ErrorKind::NotFound, id: id("1") }]);
+}
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 0a6b9417cc2..8dd18ae98e6 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-cef44f53034eac46be3a0e3eec7b2b3d4ef5140b
+203c8765ea33c65d888febe0e8219c4bb11b0d89
diff --git a/src/tools/rustfmt/src/closures.rs b/src/tools/rustfmt/src/closures.rs
index 423c3a997f5..244d4427c56 100644
--- a/src/tools/rustfmt/src/closures.rs
+++ b/src/tools/rustfmt/src/closures.rs
@@ -335,6 +335,7 @@ pub(crate) fn rewrite_last_closure(
             ref fn_decl,
             ref body,
             fn_decl_span: _,
+            fn_arg_span: _,
         } = **closure;
         let body = match body.kind {
             ast::ExprKind::Block(ref block, _)
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index a7f40167284..ff7a219d9bd 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -31,23 +31,25 @@ const LICENSES: &[&str] = &[
 /// tooling. It is _crucial_ that no exception crates be dependencies
 /// of the Rust runtime (std/test).
 const EXCEPTIONS: &[(&str, &str)] = &[
-    ("mdbook", "MPL-2.0"),            // mdbook
-    ("openssl", "Apache-2.0"),        // cargo, mdbook
-    ("colored", "MPL-2.0"),           // rustfmt
-    ("ryu", "Apache-2.0 OR BSL-1.0"), // cargo/... (because of serde)
-    ("bytesize", "Apache-2.0"),       // cargo
-    ("im-rc", "MPL-2.0+"),            // cargo
-    ("sized-chunks", "MPL-2.0+"),     // cargo via im-rc
-    ("bitmaps", "MPL-2.0+"),          // cargo via im-rc
-    ("instant", "BSD-3-Clause"),      // rustc_driver/tracing-subscriber/parking_lot
-    ("snap", "BSD-3-Clause"),         // rustc
+    ("ar_archive_writer", "Apache-2.0 WITH LLVM-exception"), // rustc
+    ("mdbook", "MPL-2.0"),                                   // mdbook
+    ("openssl", "Apache-2.0"),                               // cargo, mdbook
+    ("colored", "MPL-2.0"),                                  // rustfmt
+    ("ryu", "Apache-2.0 OR BSL-1.0"),                        // cargo/... (because of serde)
+    ("bytesize", "Apache-2.0"),                              // cargo
+    ("im-rc", "MPL-2.0+"),                                   // cargo
+    ("sized-chunks", "MPL-2.0+"),                            // cargo via im-rc
+    ("bitmaps", "MPL-2.0+"),                                 // cargo via im-rc
+    ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot
+    ("snap", "BSD-3-Clause"),    // rustc
     ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations)
-    ("self_cell", "Apache-2.0"),      // rustc (fluent translations)
+    ("self_cell", "Apache-2.0"), // rustc (fluent translations)
     // FIXME: this dependency violates the documentation comment above:
     ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target
     ("dunce", "CC0-1.0"),            // cargo (dev dependency)
     ("similar", "Apache-2.0"),       // cargo (dev dependency)
     ("normalize-line-endings", "Apache-2.0"), // cargo (dev dependency)
+    ("dissimilar", "Apache-2.0"),    // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps)
 ];
 
 const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[
@@ -86,6 +88,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "aho-corasick",
     "annotate-snippets",
     "ansi_term",
+    "ar_archive_writer",
     "arrayvec",
     "atty",
     "autocfg",
@@ -110,9 +113,9 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "cstr",
     "datafrog",
     "derive_more",
-    "difference",
     "digest",
     "displaydoc",
+    "dissimilar",
     "dlmalloc",
     "either",
     "ena",
@@ -276,7 +279,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
 const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
     "ahash",
     "anyhow",
-    "ar",
     "arrayvec",
     "autocfg",
     "bumpalo",