about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs11
-rw-r--r--compiler/rustc_ast_lowering/src/block.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs26
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs148
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs197
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs16
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs2
-rw-r--r--compiler/rustc_attr/src/builtin.rs31
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs6
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs7
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs6
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs22
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs18
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs22
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs13
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/utils.rs13
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/type_of.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs21
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs2
-rw-r--r--compiler/rustc_driver/src/lib.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0760.md6
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs2
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/active.rs10
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs1
-rw-r--r--compiler/rustc_index/src/bit_set.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs36
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs52
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs17
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs4
-rw-r--r--compiler/rustc_infer/src/infer/type_variable.rs2
-rw-r--r--compiler/rustc_interface/src/interface.rs91
-rw-r--r--compiler/rustc_interface/src/passes.rs12
-rw-r--r--compiler/rustc_interface/src/util.rs8
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs38
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h1
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs12
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs7
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs2
-rw-r--r--compiler/rustc_middle/src/dep_graph/mod.rs2
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs2
-rw-r--r--compiler/rustc_middle/src/mir/query.rs4
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs6
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs171
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs31
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs2
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs19
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs24
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs2
-rw-r--r--compiler/rustc_middle/src/ty/util.rs33
-rw-r--r--compiler/rustc_mir_transform/src/coverage/query.rs3
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs4
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs13
-rw-r--r--compiler/rustc_mir_transform/src/normalize_array_len.rs7
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs4
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/mod.rs22
-rw-r--r--compiler/rustc_monomorphize/src/util.rs6
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs8
-rw-r--r--compiler/rustc_parse/src/lib.rs1
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs8
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs2
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs7
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs14
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs34
-rw-r--r--compiler/rustc_session/src/config.rs89
-rw-r--r--compiler/rustc_session/src/options.rs3
-rw-r--r--compiler/rustc_session/src/parse.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_target/src/asm/aarch64.rs1
-rw-r--r--compiler/rustc_target/src/asm/arm.rs17
-rw-r--r--compiler/rustc_target/src/asm/bpf.rs1
-rw-r--r--compiler/rustc_target/src/asm/mod.rs108
-rw-r--r--compiler/rustc_target/src/asm/riscv.rs1
-rw-r--r--compiler/rustc_target/src/asm/x86.rs4
-rw-r--r--compiler/rustc_target/src/spec/aarch64_linux_android.rs4
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs1
-rw-r--r--compiler/rustc_target/src/spec/mips64_openwrt_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/codegen.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs13
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs60
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs38
-rw-r--r--compiler/rustc_typeck/src/astconv/errors.rs3
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs15
-rw-r--r--compiler/rustc_typeck/src/check/check.rs17
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs9
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs6
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs5
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs116
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs2
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs4
-rw-r--r--compiler/rustc_typeck/src/collect.rs9
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs42
-rw-r--r--library/alloc/src/boxed.rs6
-rw-r--r--library/alloc/src/collections/binary_heap.rs16
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs20
-rw-r--r--library/alloc/src/lib.rs2
-rw-r--r--library/alloc/src/string.rs17
-rw-r--r--library/alloc/src/vec/mod.rs19
-rw-r--r--library/core/src/async_iter/async_iter.rs (renamed from library/core/src/stream/stream.rs)56
-rw-r--r--library/core/src/async_iter/from_iter.rs (renamed from library/core/src/stream/from_iter.rs)18
-rw-r--r--library/core/src/async_iter/mod.rs (renamed from library/core/src/stream/mod.rs)69
-rw-r--r--library/core/src/iter/traits/iterator.rs82
-rw-r--r--library/core/src/lib.rs4
-rw-r--r--library/core/src/panic/unwind_safe.rs6
-rw-r--r--library/core/tests/iter/traits/iterator.rs46
-rw-r--r--library/core/tests/lib.rs3
-rw-r--r--library/std/src/collections/hash/map.rs4
-rw-r--r--library/std/src/collections/hash/set.rs7
-rw-r--r--library/std/src/ffi/c_str.rs41
-rw-r--r--library/std/src/ffi/c_str/tests.rs8
-rw-r--r--library/std/src/lib.rs6
-rw-r--r--library/std/src/path.rs6
-rw-r--r--library/std/src/sys/solid/fs.rs21
m---------library/stdarch0
-rw-r--r--src/bootstrap/dist.rs6
-rw-r--r--src/doc/rustdoc/src/unstable-features.md3
-rw-r--r--src/doc/unstable-book/src/compiler-flags/sanitizer.md20
-rw-r--r--src/doc/unstable-book/src/language-features/asm-const.md4
-rw-r--r--src/doc/unstable-book/src/language-features/asm-experimental-arch.md4
-rw-r--r--src/doc/unstable-book/src/language-features/asm-sym.md4
-rw-r--r--src/doc/unstable-book/src/language-features/asm-unwind.md4
-rw-r--r--src/doc/unstable-book/src/language-features/cfg-panic.md38
-rw-r--r--src/librustdoc/clean/mod.rs7
-rw-r--r--src/librustdoc/clean/simplify.rs4
-rw-r--r--src/librustdoc/core.rs4
-rw-r--r--src/librustdoc/doctest.rs1
-rw-r--r--src/librustdoc/html/markdown.rs4
-rw-r--r--src/librustdoc/html/render/mod.rs225
-rw-r--r--src/librustdoc/html/render/print_item.rs4
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css11
-rw-r--r--src/librustdoc/json/mod.rs9
-rw-r--r--src/librustdoc/lib.rs3
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs8
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links/early.rs4
-rw-r--r--src/librustdoc/scrape_examples.rs19
-rw-r--r--src/librustdoc/visit_ast.rs4
-rw-r--r--src/test/codegen/sanitizer_memtag_attr_check.rs12
-rw-r--r--src/test/debuginfo/unsized.rs23
-rw-r--r--src/test/run-make-fulldeps/issue-19371/foo.rs1
-rw-r--r--src/test/run-make-fulldeps/libs-and-bins/Makefile6
-rw-r--r--src/test/run-make-fulldeps/libs-and-bins/foo.rs4
-rw-r--r--src/test/run-make-fulldeps/output-with-hyphens/Makefile3
-rw-r--r--src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs3
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk3
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-test/Makefile6
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-test/examples/ex.rs6
-rw-r--r--src/test/run-make/rustdoc-scrape-examples-test/src/lib.rs3
-rw-r--r--src/test/rustdoc-gui/hash-item-expansion.goml4
-rw-r--r--src/test/rustdoc-gui/sidebar-mobile.goml2
-rw-r--r--src/test/rustdoc-gui/sidebar.goml34
-rw-r--r--src/test/rustdoc-gui/trait-sidebar-item-order.goml12
-rw-r--r--src/test/rustdoc/associated-consts.rs4
-rw-r--r--src/test/rustdoc/deref-mut-methods.rs2
-rw-r--r--src/test/rustdoc/deref-recursive-pathbuf.rs4
-rw-r--r--src/test/rustdoc/deref-recursive.rs4
-rw-r--r--src/test/rustdoc/deref-typedef.rs8
-rw-r--r--src/test/rustdoc/double-quote-escape.rs2
-rw-r--r--src/test/rustdoc/generic-impl.rs2
-rw-r--r--src/test/rustdoc/intra-doc/auxiliary/extern-lang-item-impl-dep.rs29
-rw-r--r--src/test/rustdoc/intra-doc/extern-lang-item-impl.rs11
-rw-r--r--src/test/rustdoc/method-list.rs4
-rw-r--r--src/test/rustdoc/negative-impl-sidebar.rs2
-rw-r--r--src/test/rustdoc/recursive-deref-sidebar.rs4
-rw-r--r--src/test/rustdoc/sidebar-items.rs24
-rw-r--r--src/test/rustdoc/sidebar-link-generation.rs2
-rw-r--r--src/test/rustdoc/sidebar-links-to-foreign-impl.rs4
-rw-r--r--src/test/ui/async-await/issue-61949-self-return-type.rs2
-rw-r--r--src/test/ui/async-await/issue-61949-self-return-type.stderr16
-rw-r--r--src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr4
-rw-r--r--src/test/ui/async-await/issue-75785-confusing-named-region.stderr4
-rw-r--r--src/test/ui/async-await/issues/issue-63388-1.stderr8
-rw-r--r--src/test/ui/async-await/issues/issue-78600.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-78600.stderr11
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr18
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr7
-rw-r--r--src/test/ui/async-await/unused-lifetime.rs3
-rw-r--r--src/test/ui/async-await/unused-lifetime.stderr34
-rw-r--r--src/test/ui/box/issue-78459-ice.rs6
-rw-r--r--src/test/ui/cfg/cfg-panic-abort.rs2
-rw-r--r--src/test/ui/cfg/cfg-panic.rs2
-rw-r--r--src/test/ui/check-cfg/empty-names.rs10
-rw-r--r--src/test/ui/check-cfg/empty-names.stderr10
-rw-r--r--src/test/ui/check-cfg/empty-values.rs6
-rw-r--r--src/test/ui/check-cfg/empty-values.stderr2
-rw-r--r--src/test/ui/check-cfg/invalid-arguments.anything_else.stderr2
-rw-r--r--src/test/ui/check-cfg/invalid-arguments.names_simple_ident.stderr2
-rw-r--r--src/test/ui/check-cfg/invalid-arguments.rs10
-rw-r--r--src/test/ui/check-cfg/invalid-arguments.values_simple_ident.stderr2
-rw-r--r--src/test/ui/check-cfg/invalid-arguments.values_string_literals.stderr2
-rw-r--r--src/test/ui/check-cfg/invalid-cfg-name.rs14
-rw-r--r--src/test/ui/check-cfg/invalid-cfg-name.stderr10
-rw-r--r--src/test/ui/check-cfg/invalid-cfg-value.rs17
-rw-r--r--src/test/ui/check-cfg/invalid-cfg-value.stderr10
-rw-r--r--src/test/ui/const-generics/defaults/doesnt_infer.rs2
-rw-r--r--src/test/ui/const-generics/defaults/doesnt_infer.stderr2
-rw-r--r--src/test/ui/const-generics/generic_arg_infer/issue-91614.rs2
-rw-r--r--src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr2
-rw-r--r--src/test/ui/dropck/drop-with-active-borrows-2.stderr5
-rw-r--r--src/test/ui/feature-gates/feature-gate-asm_const.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-asm_experimental_arch.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-asm_sym.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-asm_unwind.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs6
-rw-r--r--src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr6
-rw-r--r--src/test/ui/feature-gates/feature-gate-cfg-panic.rs11
-rw-r--r--src/test/ui/feature-gates/feature-gate-cfg-panic.stderr21
-rw-r--r--src/test/ui/feature-gates/feature-gate-check-cfg.rs3
-rw-r--r--src/test/ui/feature-gates/feature-gate-check-cfg.stderr2
-rw-r--r--src/test/ui/fmt/format-args-capture.rs1
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-80626.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-80626.stderr2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-86218.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-86218.stderr4
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87735.rs3
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87735.stderr2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87748.rs3
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87748.stderr6
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87755.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87755.stderr2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87803.rs3
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87803.stderr2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88382.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88382.stderr4
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88460.rs2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88460.stderr4
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88526.rs3
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88526.stderr2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-89008.rs5
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-89008.stderr4
-rw-r--r--src/test/ui/generic-associated-types/impl_bounds.stderr7
-rw-r--r--src/test/ui/generic-associated-types/issue-74824.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-74824.stderr11
-rw-r--r--src/test/ui/generic-associated-types/issue-88595.rs5
-rw-r--r--src/test/ui/generic-associated-types/issue-88595.stderr22
-rw-r--r--src/test/ui/generic-associated-types/issue-90014.stderr7
-rw-r--r--src/test/ui/generic-associated-types/issue-92033.rs39
-rw-r--r--src/test/ui/generic-associated-types/issue-92033.stderr22
-rw-r--r--src/test/ui/generic-associated-types/issue-93874.rs35
-rw-r--r--src/test/ui/impl-trait/issues/issue-54600.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-54600.stderr2
-rw-r--r--src/test/ui/impl-trait/issues/issue-54840.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-54840.stderr2
-rw-r--r--src/test/ui/impl-trait/issues/issue-58504.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-58504.stderr2
-rw-r--r--src/test/ui/impl-trait/issues/issue-58956.rs4
-rw-r--r--src/test/ui/impl-trait/issues/issue-58956.stderr4
-rw-r--r--src/test/ui/impl-trait/issues/issue-70971.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-70971.stderr2
-rw-r--r--src/test/ui/impl-trait/issues/issue-79099.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-79099.stderr2
-rw-r--r--src/test/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs4
-rw-r--r--src/test/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr4
-rw-r--r--src/test/ui/impl-trait/issues/issue-84919.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-84919.stderr2
-rw-r--r--src/test/ui/impl-trait/issues/issue-86642.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-86642.stderr2
-rw-r--r--src/test/ui/impl-trait/issues/issue-87295.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-87295.stderr2
-rw-r--r--src/test/ui/impl-trait/nested_impl_trait.rs4
-rw-r--r--src/test/ui/impl-trait/nested_impl_trait.stderr4
-rw-r--r--src/test/ui/impl-trait/where-allowed.rs82
-rw-r--r--src/test/ui/impl-trait/where-allowed.stderr82
-rw-r--r--src/test/ui/invalid/invalid-no-sanitize.stderr2
-rw-r--r--src/test/ui/issues/issue-13497-2.rs4
-rw-r--r--src/test/ui/issues/issue-13497-2.stderr14
-rw-r--r--src/test/ui/issues/issue-14772.rs6
-rw-r--r--src/test/ui/issues/issue-14772.stderr8
-rw-r--r--src/test/ui/issues/issue-47715.rs8
-rw-r--r--src/test/ui/issues/issue-47715.stderr8
-rw-r--r--src/test/ui/issues/issue-68696-catch-during-unwind.rs1
-rw-r--r--src/test/ui/return/return-impl-trait-bad.rs31
-rw-r--r--src/test/ui/return/return-impl-trait-bad.stderr59
-rw-r--r--src/test/ui/return/return-impl-trait.fixed30
-rw-r--r--src/test/ui/return/return-impl-trait.rs30
-rw-r--r--src/test/ui/return/return-impl-trait.stderr34
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr5
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr12
-rw-r--r--src/test/ui/self/elision/lt-ref-self-async.stderr36
-rw-r--r--src/test/ui/self/elision/ref-mut-self-async.stderr36
-rw-r--r--src/test/ui/self/elision/ref-mut-struct-async.stderr30
-rw-r--r--src/test/ui/self/elision/ref-self-async.stderr42
-rw-r--r--src/test/ui/self/elision/ref-struct-async.stderr30
-rw-r--r--src/test/ui/test-attrs/test-on-macro.rs13
-rw-r--r--src/test/ui/test-attrs/test-on-macro.stderr8
-rw-r--r--src/test/ui/test-attrs/test-on-not-fn.rs80
-rw-r--r--src/test/ui/test-attrs/test-on-not-fn.stderr185
-rw-r--r--src/test/ui/trait-bounds/issue-93008.rs10
-rw-r--r--src/test/ui/trait-bounds/issue-93008.stderr12
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr2
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.stderr2
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.fixed6
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.rs6
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.stderr20
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.stderr8
-rw-r--r--src/tools/compiletest/src/header.rs398
-rw-r--r--src/tools/compiletest/src/runtest.rs11
-rw-r--r--src/tools/compiletest/src/util.rs3
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
315 files changed, 3272 insertions, 1650 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 6a0ace04d4b..b94b8c87216 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -230,7 +230,7 @@ impl AttrItem {
     }
 
     pub fn meta_kind(&self) -> Option<MetaItemKind> {
-        Some(MetaItemKind::from_mac_args(&self.args)?)
+        MetaItemKind::from_mac_args(&self.args)
     }
 }
 
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 5a85356d96d..18fcc99ffba 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -129,13 +129,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             .operands
             .iter()
             .map(|(op, op_sp)| {
-                let lower_reg = |reg| match reg {
+                let lower_reg = |reg, is_clobber| match reg {
                     InlineAsmRegOrRegClass::Reg(s) => {
                         asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch {
                             asm::InlineAsmReg::parse(
                                 asm_arch,
                                 &sess.target_features,
                                 &sess.target,
+                                is_clobber,
                                 s,
                             )
                             .unwrap_or_else(|e| {
@@ -162,24 +163,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
                 let op = match *op {
                     InlineAsmOperand::In { reg, ref expr } => hir::InlineAsmOperand::In {
-                        reg: lower_reg(reg),
+                        reg: lower_reg(reg, false),
                         expr: self.lower_expr_mut(expr),
                     },
                     InlineAsmOperand::Out { reg, late, ref expr } => hir::InlineAsmOperand::Out {
-                        reg: lower_reg(reg),
+                        reg: lower_reg(reg, expr.is_none()),
                         late,
                         expr: expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
                     },
                     InlineAsmOperand::InOut { reg, late, ref expr } => {
                         hir::InlineAsmOperand::InOut {
-                            reg: lower_reg(reg),
+                            reg: lower_reg(reg, false),
                             late,
                             expr: self.lower_expr_mut(expr),
                         }
                     }
                     InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => {
                         hir::InlineAsmOperand::SplitInOut {
-                            reg: lower_reg(reg),
+                            reg: lower_reg(reg, false),
                             late,
                             in_expr: self.lower_expr_mut(in_expr),
                             out_expr: out_expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs
index 082c5bb7833..3a7e0a70585 100644
--- a/compiler/rustc_ast_lowering/src/block.rs
+++ b/compiler/rustc_ast_lowering/src/block.rs
@@ -97,7 +97,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let ty = l
             .ty
             .as_ref()
-            .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Binding)));
+            .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
         let init = l.kind.init().map(|init| self.lower_expr(init));
         let hir_id = self.lower_node_id(l.id);
         let pat = self.lower_pat(&l.pat);
@@ -127,7 +127,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let ty = local
             .ty
             .as_ref()
-            .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Binding)));
+            .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
         let span = self.lower_span(local.span);
         let span = self.mark_span_with_reason(DesugaringKind::LetElse, span, None);
         let init = self.lower_expr(init);
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 17bc8d7591b..d48ff10b97d 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -1,3 +1,5 @@
+use crate::{FnDeclKind, ImplTraitPosition};
+
 use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
 
 use rustc_ast::attr;
@@ -53,7 +55,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         ParamMode::Optional,
                         0,
                         ParenthesizedGenericArgs::Err,
-                        ImplTraitContext::disallowed(),
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     ));
                     let args = self.lower_exprs(args);
                     hir::ExprKind::MethodCall(hir_seg, args, self.lower_span(span))
@@ -74,12 +76,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 }
                 ExprKind::Cast(ref expr, ref ty) => {
                     let expr = self.lower_expr(expr);
-                    let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
+                    let ty =
+                        self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
                     hir::ExprKind::Cast(expr, ty)
                 }
                 ExprKind::Type(ref expr, ref ty) => {
                     let expr = self.lower_expr(expr);
-                    let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
+                    let ty =
+                        self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
                     hir::ExprKind::Type(expr, ty)
                 }
                 ExprKind::AddrOf(k, m, ref ohs) => {
@@ -203,7 +207,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         qself,
                         path,
                         ParamMode::Optional,
-                        ImplTraitContext::disallowed(),
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     );
                     hir::ExprKind::Path(qpath)
                 }
@@ -239,7 +243,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             &se.qself,
                             &se.path,
                             ParamMode::Optional,
-                            ImplTraitContext::disallowed(),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         )),
                         self.arena
                             .alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))),
@@ -538,7 +542,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
         body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
     ) -> hir::ExprKind<'hir> {
         let output = match ret_ty {
-            Some(ty) => hir::FnRetTy::Return(self.lower_ty(&ty, ImplTraitContext::disallowed())),
+            Some(ty) => hir::FnRetTy::Return(
+                self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock)),
+            ),
             None => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
         };
 
@@ -827,7 +833,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         });
 
         // Lower outside new scope to preserve `is_in_loop_condition`.
-        let fn_decl = self.lower_fn_decl(decl, None, false, None);
+        let fn_decl = self.lower_fn_decl(decl, None, FnDeclKind::Closure, None);
 
         hir::ExprKind::Closure(
             capture_clause,
@@ -919,7 +925,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         // We need to lower the declaration outside the new scope, because we
         // have to conserve the state of being inside a loop condition for the
         // closure argument types.
-        let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None);
+        let fn_decl = self.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);
 
         hir::ExprKind::Closure(
             capture_clause,
@@ -1064,7 +1070,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         qself,
                         path,
                         ParamMode::Optional,
-                        ImplTraitContext::disallowed(),
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     );
                     // Destructure like a tuple struct.
                     let tuple_struct_pat =
@@ -1089,7 +1095,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &se.qself,
                     &se.path,
                     ParamMode::Optional,
-                    ImplTraitContext::disallowed(),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                 );
                 let fields_omitted = match &se.rest {
                     StructRest::Base(e) => {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index f48cf212a98..6489c729cfe 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1,6 +1,6 @@
 use super::{AnonymousLifetimeMode, LoweringContext, ParamMode};
 use super::{ImplTraitContext, ImplTraitPosition};
-use crate::Arena;
+use crate::{Arena, FnDeclKind};
 
 use rustc_ast::ptr::P;
 use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
@@ -246,7 +246,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         AnonymousLifetimeMode::PassThrough,
                         |this, idty| {
                             let ret_id = asyncness.opt_return_id();
-                            this.lower_fn_decl(&decl, Some((fn_def_id, idty)), true, ret_id)
+                            this.lower_fn_decl(
+                                &decl,
+                                Some((fn_def_id, idty)),
+                                FnDeclKind::Fn,
+                                ret_id,
+                            )
                         },
                     );
                     let sig = hir::FnSig {
@@ -287,12 +292,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         capturable_lifetimes: &mut FxHashSet::default(),
                     },
                 );
-                let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
+                let generics = self.lower_generics(
+                    generics,
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                );
                 hir::ItemKind::TyAlias(ty, generics)
             }
             ItemKind::TyAlias(box TyAlias { ref generics, ty: None, .. }) => {
                 let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
-                let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
+                let generics = self.lower_generics(
+                    generics,
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                );
                 hir::ItemKind::TyAlias(ty, generics)
             }
             ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
@@ -301,20 +312,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         enum_definition.variants.iter().map(|x| self.lower_variant(x)),
                     ),
                 },
-                self.lower_generics(generics, ImplTraitContext::disallowed()),
+                self.lower_generics(
+                    generics,
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                ),
             ),
             ItemKind::Struct(ref struct_def, ref generics) => {
                 let struct_def = self.lower_variant_data(hir_id, struct_def);
                 hir::ItemKind::Struct(
                     struct_def,
-                    self.lower_generics(generics, ImplTraitContext::disallowed()),
+                    self.lower_generics(
+                        generics,
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ),
                 )
             }
             ItemKind::Union(ref vdata, ref generics) => {
                 let vdata = self.lower_variant_data(hir_id, vdata);
                 hir::ItemKind::Union(
                     vdata,
-                    self.lower_generics(generics, ImplTraitContext::disallowed()),
+                    self.lower_generics(
+                        generics,
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ),
                 )
             }
             ItemKind::Impl(box Impl {
@@ -347,10 +367,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     AnonymousLifetimeMode::CreateParameter,
                     |this, _| {
                         let trait_ref = trait_ref.as_ref().map(|trait_ref| {
-                            this.lower_trait_ref(trait_ref, ImplTraitContext::disallowed())
+                            this.lower_trait_ref(
+                                trait_ref,
+                                ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
+                            )
                         });
 
-                        let lowered_ty = this.lower_ty(ty, ImplTraitContext::disallowed());
+                        let lowered_ty = this
+                            .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
 
                         (trait_ref, lowered_ty)
                     },
@@ -390,21 +414,33 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ref bounds,
                 ref items,
             }) => {
-                let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
+                let bounds = self.lower_param_bounds(
+                    bounds,
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                );
                 let items = self
                     .arena
                     .alloc_from_iter(items.iter().map(|item| self.lower_trait_item_ref(item)));
                 hir::ItemKind::Trait(
                     is_auto,
                     self.lower_unsafety(unsafety),
-                    self.lower_generics(generics, ImplTraitContext::disallowed()),
+                    self.lower_generics(
+                        generics,
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ),
                     bounds,
                     items,
                 )
             }
             ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemKind::TraitAlias(
-                self.lower_generics(generics, ImplTraitContext::disallowed()),
-                self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
+                self.lower_generics(
+                    generics,
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                ),
+                self.lower_param_bounds(
+                    bounds,
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                ),
             ),
             ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
                 let body = P(self.lower_mac_args(body));
@@ -423,7 +459,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         span: Span,
         body: Option<&Expr>,
     ) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
-        let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Binding));
+        let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
         (ty, self.lower_const_body(span, body))
     }
 
@@ -667,7 +703,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         |this, _| {
                             (
                                 // Disallow `impl Trait` in foreign items.
-                                this.lower_fn_decl(fdec, None, false, None),
+                                this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None),
                                 this.lower_fn_params_to_names(fdec),
                             )
                         },
@@ -676,7 +712,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
                 }
                 ForeignItemKind::Static(ref t, m, _) => {
-                    let ty = self.lower_ty(t, ImplTraitContext::disallowed());
+                    let ty =
+                        self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
                     hir::ForeignItemKind::Static(ty, m)
                 }
                 ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
@@ -744,11 +781,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 qself,
                 path,
                 ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
-                ImplTraitContext::disallowed(),
+                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
             );
             self.arena.alloc(t)
         } else {
-            self.lower_ty(&f.ty, ImplTraitContext::disallowed())
+            self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
         };
         let hir_id = self.lower_node_id(f.id);
         self.lower_attrs(hir_id, &f.attrs);
@@ -771,14 +808,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
         let (generics, kind) = match i.kind {
             AssocItemKind::Const(_, ref ty, ref default) => {
-                let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
+                let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
                 let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
                 (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body))
             }
             AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
                 let names = self.lower_fn_params_to_names(&sig.decl);
-                let (generics, sig) =
-                    self.lower_method_sig(generics, sig, trait_item_def_id, false, None);
+                let (generics, sig) = self.lower_method_sig(
+                    generics,
+                    sig,
+                    trait_item_def_id,
+                    FnDeclKind::Trait,
+                    None,
+                );
                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)))
             }
             AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
@@ -789,16 +831,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     generics,
                     sig,
                     trait_item_def_id,
-                    false,
+                    FnDeclKind::Trait,
                     asyncness.opt_return_id(),
                 );
                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
             }
             AssocItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => {
-                let ty = ty.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::disallowed()));
-                let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
+                let ty = ty.as_ref().map(|x| {
+                    self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
+                });
+                let generics = self.lower_generics(
+                    generics,
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                );
                 let kind = hir::TraitItemKind::Type(
-                    self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
+                    self.lower_param_bounds(
+                        bounds,
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                    ),
                     ty,
                 );
 
@@ -850,7 +900,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
         let (generics, kind) = match &i.kind {
             AssocItemKind::Const(_, ty, expr) => {
-                let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
+                let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
                 (
                     hir::Generics::empty(),
                     hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())),
@@ -861,19 +911,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 let asyncness = sig.header.asyncness;
                 let body_id =
                     self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref());
-                let impl_trait_return_allow = !self.is_in_trait_impl;
                 let (generics, sig) = self.lower_method_sig(
                     generics,
                     sig,
                     impl_item_def_id,
-                    impl_trait_return_allow,
+                    if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
                     asyncness.opt_return_id(),
                 );
 
                 (generics, hir::ImplItemKind::Fn(sig, body_id))
             }
             AssocItemKind::TyAlias(box TyAlias { generics, ty, .. }) => {
-                let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
+                let generics = self.lower_generics(
+                    generics,
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                );
                 let kind = match ty {
                     None => {
                         let ty = self.arena.alloc(self.ty(i.span, hir::TyKind::Err));
@@ -1248,7 +1300,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         generics: &Generics,
         sig: &FnSig,
         fn_def_id: LocalDefId,
-        impl_trait_return_allow: bool,
+        kind: FnDeclKind,
         is_async: Option<NodeId>,
     ) -> (hir::Generics<'hir>, hir::FnSig<'hir>) {
         let header = self.lower_fn_header(sig.header);
@@ -1256,14 +1308,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             generics,
             fn_def_id,
             AnonymousLifetimeMode::PassThrough,
-            |this, idty| {
-                this.lower_fn_decl(
-                    &sig.decl,
-                    Some((fn_def_id, idty)),
-                    impl_trait_return_allow,
-                    is_async,
-                )
-            },
+            |this, idty| this.lower_fn_decl(&sig.decl, Some((fn_def_id, idty)), kind, is_async),
         );
         (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
     }
@@ -1409,11 +1454,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 span,
             }) => self.with_in_scope_lifetime_defs(&bound_generic_params, |this| {
                 hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
-                    bound_generic_params: this
-                        .lower_generic_params(bound_generic_params, ImplTraitContext::disallowed()),
-                    bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()),
+                    bound_generic_params: this.lower_generic_params(
+                        bound_generic_params,
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ),
+                    bounded_ty: this.lower_ty(
+                        bounded_ty,
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Type),
+                    ),
                     bounds: this.arena.alloc_from_iter(bounds.iter().map(|bound| {
-                        this.lower_param_bound(bound, ImplTraitContext::disallowed())
+                        this.lower_param_bound(
+                            bound,
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                        )
                     })),
                     span: this.lower_span(span),
                 })
@@ -1425,13 +1478,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
                 span: self.lower_span(span),
                 lifetime: self.lower_lifetime(lifetime),
-                bounds: self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
+                bounds: self.lower_param_bounds(
+                    bounds,
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                ),
             }),
             WherePredicate::EqPredicate(WhereEqPredicate { id, ref lhs_ty, ref rhs_ty, span }) => {
                 hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
                     hir_id: self.lower_node_id(id),
-                    lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::disallowed()),
-                    rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::disallowed()),
+                    lhs_ty: self
+                        .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
+                    rhs_ty: self
+                        .lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
                     span: self.lower_span(span),
                 })
             }
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 60b5aeb52b1..ae7f22923df 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -256,19 +256,28 @@ enum ImplTraitContext<'b, 'a> {
 /// Position in which `impl Trait` is disallowed.
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 enum ImplTraitPosition {
-    /// Disallowed in `let` / `const` / `static` bindings.
-    Binding,
-
-    /// All other positions.
-    Other,
+    Path,
+    Variable,
+    Type,
+    Trait,
+    AsyncBlock,
+    Bound,
+    Generic,
+    ExternFnParam,
+    ClosureParam,
+    PointerParam,
+    FnTraitParam,
+    TraitParam,
+    ImplParam,
+    ExternFnReturn,
+    ClosureReturn,
+    PointerReturn,
+    FnTraitReturn,
+    TraitReturn,
+    ImplReturn,
 }
 
 impl<'a> ImplTraitContext<'_, 'a> {
-    #[inline]
-    fn disallowed() -> Self {
-        ImplTraitContext::Disallowed(ImplTraitPosition::Other)
-    }
-
     fn reborrow<'this>(&'this mut self) -> ImplTraitContext<'this, 'a> {
         use self::ImplTraitContext::*;
         match self {
@@ -284,6 +293,54 @@ impl<'a> ImplTraitContext<'_, 'a> {
     }
 }
 
+impl std::fmt::Display for ImplTraitPosition {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        let name = match self {
+            ImplTraitPosition::Path => "path",
+            ImplTraitPosition::Variable => "variable binding",
+            ImplTraitPosition::Type => "type",
+            ImplTraitPosition::Trait => "trait",
+            ImplTraitPosition::AsyncBlock => "async block",
+            ImplTraitPosition::Bound => "bound",
+            ImplTraitPosition::Generic => "generic",
+            ImplTraitPosition::ExternFnParam => "`extern fn` param",
+            ImplTraitPosition::ClosureParam => "closure param",
+            ImplTraitPosition::PointerParam => "`fn` pointer param",
+            ImplTraitPosition::FnTraitParam => "`Fn` trait param",
+            ImplTraitPosition::TraitParam => "trait method param",
+            ImplTraitPosition::ImplParam => "`impl` method param",
+            ImplTraitPosition::ExternFnReturn => "`extern fn` return",
+            ImplTraitPosition::ClosureReturn => "closure return",
+            ImplTraitPosition::PointerReturn => "`fn` pointer return",
+            ImplTraitPosition::FnTraitReturn => "`Fn` trait return",
+            ImplTraitPosition::TraitReturn => "trait method return",
+            ImplTraitPosition::ImplReturn => "`impl` method return",
+        };
+
+        write!(f, "{}", name)
+    }
+}
+
+#[derive(Debug)]
+enum FnDeclKind {
+    Fn,
+    Inherent,
+    ExternFn,
+    Closure,
+    Pointer,
+    Trait,
+    Impl,
+}
+
+impl FnDeclKind {
+    fn impl_trait_return_allowed(&self) -> bool {
+        match self {
+            FnDeclKind::Fn | FnDeclKind::Inherent => true,
+            _ => false,
+        }
+    }
+}
+
 pub fn lower_crate<'a, 'hir>(
     sess: &'a Session,
     krate: &'a Crate,
@@ -1232,11 +1289,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
                         generic_params: this.lower_generic_params(
                             &f.generic_params,
-                            ImplTraitContext::disallowed(),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                         ),
                         unsafety: this.lower_unsafety(f.unsafety),
                         abi: this.lower_extern(f.ext),
-                        decl: this.lower_fn_decl(&f.decl, None, false, None),
+                        decl: this.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None),
                         param_names: this.lower_fn_params_to_names(&f.decl),
                     }))
                 })
@@ -1357,13 +1414,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             }),
                         ))
                     }
-                    ImplTraitContext::Disallowed(_) => {
+                    ImplTraitContext::Disallowed(position) => {
                         let mut err = struct_span_err!(
                             self.sess,
                             t.span,
                             E0562,
-                            "`impl Trait` not allowed outside of {}",
-                            "function and method return types",
+                            "`impl Trait` only allowed in function and inherent method return types, not in {}",
+                            position
                         );
                         err.emit();
                         hir::TyKind::Err
@@ -1528,16 +1585,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         &mut self,
         decl: &FnDecl,
         mut in_band_ty_params: Option<(LocalDefId, &mut Vec<hir::GenericParam<'hir>>)>,
-        impl_trait_return_allow: bool,
+        kind: FnDeclKind,
         make_ret_async: Option<NodeId>,
     ) -> &'hir hir::FnDecl<'hir> {
         debug!(
             "lower_fn_decl(\
             fn_decl: {:?}, \
             in_band_ty_params: {:?}, \
-            impl_trait_return_allow: {}, \
+            kind: {:?}, \
             make_ret_async: {:?})",
-            decl, in_band_ty_params, impl_trait_return_allow, make_ret_async,
+            decl, in_band_ty_params, kind, make_ret_async,
         );
         let lt_mode = if make_ret_async.is_some() {
             // In `async fn`, argument-position elided lifetimes
@@ -1567,7 +1624,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         ImplTraitContext::Universal(ibty, this.current_hir_id_owner),
                     )
                 } else {
-                    this.lower_ty_direct(&param.ty, ImplTraitContext::disallowed())
+                    this.lower_ty_direct(
+                        &param.ty,
+                        ImplTraitContext::Disallowed(match kind {
+                            FnDeclKind::Fn | FnDeclKind::Inherent => {
+                                unreachable!("fn should allow in-band lifetimes")
+                            }
+                            FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam,
+                            FnDeclKind::Closure => ImplTraitPosition::ClosureParam,
+                            FnDeclKind::Pointer => ImplTraitPosition::PointerParam,
+                            FnDeclKind::Trait => ImplTraitPosition::TraitParam,
+                            FnDeclKind::Impl => ImplTraitPosition::ImplParam,
+                        }),
+                    )
                 }
             }))
         });
@@ -1582,13 +1651,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             match decl.output {
                 FnRetTy::Ty(ref ty) => {
                     let context = match in_band_ty_params {
-                        Some((def_id, _)) if impl_trait_return_allow => {
+                        Some((def_id, _)) if kind.impl_trait_return_allowed() => {
                             ImplTraitContext::ReturnPositionOpaqueTy {
                                 fn_def_id: def_id,
                                 origin: hir::OpaqueTyOrigin::FnReturn(def_id),
                             }
                         }
-                        _ => ImplTraitContext::disallowed(),
+                        _ => ImplTraitContext::Disallowed(match kind {
+                            FnDeclKind::Fn | FnDeclKind::Inherent => {
+                                unreachable!("fn should allow in-band lifetimes")
+                            }
+                            FnDeclKind::ExternFn => ImplTraitPosition::ExternFnReturn,
+                            FnDeclKind::Closure => ImplTraitPosition::ClosureReturn,
+                            FnDeclKind::Pointer => ImplTraitPosition::PointerReturn,
+                            FnDeclKind::Trait => ImplTraitPosition::TraitReturn,
+                            FnDeclKind::Impl => ImplTraitPosition::ImplReturn,
+                        }),
                     };
                     hir::FnRetTy::Return(self.lower_ty(ty, context))
                 }
@@ -1659,12 +1737,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         // 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
-        // return type). This is done by:
+        // return type). This is done by introducing lifetime parameters for:
         //
-        // - making the opaque type inherit all lifetime parameters from its parent;
-        // - make all the elided lifetimes in the fn arguments into parameters;
-        // - manually introducing parameters on the opaque type for elided
-        //   lifetimes in the return type.
+        // - all the explicitly declared lifetimes from the impl and function itself;
+        // - all the elided lifetimes in the fn arguments;
+        // - all the elided lifetimes in the return type.
         //
         // So for example in this snippet:
         //
@@ -1680,14 +1757,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         // we would create an opaque type like:
         //
         // ```
-        // type Foo<'a>::bar<'b, '0, '1>::Bar<'2> = impl Future<Output = &'2 u32>;
+        // type Bar<'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
         // ```
         //
         // and we would then desugar `bar` to the equivalent of:
         //
         // ```rust
         // impl<'a> Foo<'a> {
-        //   fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'_>
+        //   fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_>
         // }
         // ```
         //
@@ -1695,7 +1772,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         // this is because the elided lifetimes from the return type
         // should be figured out using the ordinary elision rules, and
         // this desugaring achieves that.
-        let mut lifetime_params = Vec::new();
+
+        debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", self.in_scope_lifetimes);
+        debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", self.lifetimes_to_define);
+
+        // Calculate all the lifetimes that should be captured
+        // by the opaque type. This should include all in-scope
+        // lifetime parameters, including those defined in-band.
+        //
+        // `lifetime_params` is a vector of tuple (span, parameter name, lifetime name).
+
+        // Input lifetime like `'a` or `'1`:
+        let mut lifetime_params: Vec<_> = self
+            .in_scope_lifetimes
+            .iter()
+            .cloned()
+            .map(|name| (name.ident().span, name, hir::LifetimeName::Param(name)))
+            .chain(
+                self.lifetimes_to_define
+                    .iter()
+                    .map(|&(span, name)| (span, name, hir::LifetimeName::Param(name))),
+            )
+            .collect();
+
         self.with_hir_id_owner(opaque_ty_node_id, |this| {
             // We have to be careful to get elision right here. The
             // idea is that we create a lifetime parameter for each
@@ -1714,12 +1813,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound);
             debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", lifetimes_to_define);
 
-            // Output lifetime like `'_`:
-            lifetime_params = lifetimes_to_define;
+            lifetime_params.extend(
+                // Output lifetime like `'_`:
+                lifetimes_to_define
+                    .into_iter()
+                    .map(|(span, name)| (span, name, hir::LifetimeName::Implicit(false))),
+            );
             debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params);
 
             let generic_params =
-                this.arena.alloc_from_iter(lifetime_params.iter().map(|&(span, hir_name)| {
+                this.arena.alloc_from_iter(lifetime_params.iter().map(|&(span, hir_name, _)| {
                     this.lifetime_to_generic_param(span, hir_name, opaque_ty_def_id)
                 }));
 
@@ -1737,22 +1840,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             this.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
         });
 
-        // We need to create the lifetime arguments to our opaque type.
-        // Continuing with our example, we're creating the type arguments
-        // for the return type:
+        // As documented above on the variable
+        // `input_lifetimes_count`, we need to create the lifetime
+        // arguments to our opaque type. Continuing with our example,
+        // we're creating the type arguments for the return type:
         //
         // ```
-        // For<'a>::bar<'b, '0, '1>::Bar<'_>
+        // Bar<'a, 'b, '0, '1, '_>
         // ```
         //
-        // For the "input" lifetime parameters are inherited automatically.
-        // For the "output" lifetime parameters, we just want to generate `'_`.
+        // For the "input" lifetime parameters, we wish to create
+        // references to the parameters themselves, including the
+        // "implicit" ones created from parameter types (`'a`, `'b`,
+        // '`0`, `'1`).
+        //
+        // For the "output" lifetime parameters, we just want to
+        // generate `'_`.
         let generic_args =
-            self.arena.alloc_from_iter(lifetime_params.into_iter().map(|(span, _)| {
+            self.arena.alloc_from_iter(lifetime_params.into_iter().map(|(span, _, name)| {
                 GenericArg::Lifetime(hir::Lifetime {
                     hir_id: self.next_id(),
                     span: self.lower_span(span),
-                    name: hir::LifetimeName::Implicit(false),
+                    name,
                 })
             }));
 
@@ -1915,7 +2024,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             GenericParamKind::Type { ref default, .. } => {
                 let kind = hir::GenericParamKind::Type {
                     default: default.as_ref().map(|x| {
-                        self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Other))
+                        self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
                     }),
                     synthetic: false,
                 };
@@ -1923,9 +2032,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
             }
             GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
-                let ty = self
-                    .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
-                        this.lower_ty(&ty, ImplTraitContext::disallowed())
+                let ty =
+                    self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
+                        this.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
                     });
                 let default = default.as_ref().map(|def| self.lower_anon_const(def));
                 (
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index ebae7798433..2c331767b89 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -1,3 +1,5 @@
+use crate::ImplTraitPosition;
+
 use super::{ImplTraitContext, LoweringContext, ParamMode};
 
 use rustc_ast::ptr::P;
@@ -33,7 +35,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             qself,
                             path,
                             ParamMode::Optional,
-                            ImplTraitContext::disallowed(),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         );
                         let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
                         break hir::PatKind::TupleStruct(qpath, pats, ddpos);
@@ -49,7 +51,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             qself,
                             path,
                             ParamMode::Optional,
-                            ImplTraitContext::disallowed(),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         );
                         break hir::PatKind::Path(qpath);
                     }
@@ -59,7 +61,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             qself,
                             path,
                             ParamMode::Optional,
-                            ImplTraitContext::disallowed(),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         );
 
                         let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::PatField {
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 79262235cd9..b35e3a07161 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -1,3 +1,5 @@
+use crate::ImplTraitPosition;
+
 use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode};
 use super::{GenericArgsCtor, ParenthesizedGenericArgs};
 
@@ -184,7 +186,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     param_mode,
                     0,
                     ParenthesizedGenericArgs::Err,
-                    ImplTraitContext::disallowed(),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                 )
             })),
             span: self.lower_span(p.span),
@@ -392,11 +394,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         // we generally don't permit such things (see #51008).
         self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::PassThrough, |this| {
             let ParenthesizedArgs { span, inputs, inputs_span, output } = data;
-            let inputs = this.arena.alloc_from_iter(
-                inputs.iter().map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())),
-            );
+            let inputs = this.arena.alloc_from_iter(inputs.iter().map(|ty| {
+                this.lower_ty_direct(
+                    ty,
+                    ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam),
+                )
+            }));
             let output_ty = match output {
-                FnRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()),
+                FnRetTy::Ty(ty) => this
+                    .lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)),
                 FnRetTy::Default(_) => this.arena.alloc(this.ty_tup(*span, &[])),
             };
             let args = smallvec![GenericArg::Type(this.ty_tup(*inputs_span, inputs))];
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 0a96e60d4d3..6c44fb0df23 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -823,7 +823,7 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
             );
             let mut all_stable = true;
             for ident in
-                attr.meta_item_list().into_iter().flatten().map(|nested| nested.ident()).flatten()
+                attr.meta_item_list().into_iter().flatten().flat_map(|nested| nested.ident())
             {
                 let name = ident.name;
                 let stable_since = lang_features
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index dca7f5dd487..49043e9f5f9 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -1,10 +1,13 @@
 //! Parsing and validation of builtin attributes
 
-use rustc_ast::{self as ast, Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem};
+use rustc_ast as ast;
+use rustc_ast::node_id::CRATE_NODE_ID;
+use rustc_ast::{Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem};
 use rustc_ast_pretty::pprust;
 use rustc_errors::{struct_span_err, Applicability};
 use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
 use rustc_macros::HashStable_Generic;
+use rustc_session::lint::builtin::UNEXPECTED_CFGS;
 use rustc_session::parse::{feature_err, ParseSess};
 use rustc_session::Session;
 use rustc_span::hygiene::Transparency;
@@ -458,8 +461,30 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat
                 true
             }
             MetaItemKind::NameValue(..) | MetaItemKind::Word => {
-                let ident = cfg.ident().expect("multi-segment cfg predicate");
-                sess.config.contains(&(ident.name, cfg.value_str()))
+                let name = cfg.ident().expect("multi-segment cfg predicate").name;
+                let value = cfg.value_str();
+                if sess.check_config.names_checked && !sess.check_config.names_valid.contains(&name)
+                {
+                    sess.buffer_lint(
+                        UNEXPECTED_CFGS,
+                        cfg.span,
+                        CRATE_NODE_ID,
+                        "unexpected `cfg` condition name",
+                    );
+                }
+                if let Some(val) = value {
+                    if sess.check_config.values_checked.contains(&name)
+                        && !sess.check_config.values_valid.contains(&(name, val))
+                    {
+                        sess.buffer_lint(
+                            UNEXPECTED_CFGS,
+                            cfg.span,
+                            CRATE_NODE_ID,
+                            "unexpected `cfg` condition value",
+                        );
+                    }
+                }
+                sess.config.contains(&(name, value))
             }
         }
     })
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index 904a8a22e01..2a906e41b8c 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -142,11 +142,9 @@ trait TypeOpInfo<'tcx> {
         let tcx = mbcx.infcx.tcx;
         let base_universe = self.base_universe();
 
-        let adjusted_universe = if let Some(adjusted) =
+        let Some(adjusted_universe) =
             placeholder.universe.as_u32().checked_sub(base_universe.as_u32())
-        {
-            adjusted
-        } else {
+        else {
             mbcx.buffer_error(self.fallback_error(tcx, cause.span));
             return;
         };
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 5da2021e711..73b0d398285 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -867,15 +867,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             kind: TerminatorKind::Call { fn_span, from_hir_call, .. }, ..
         }) = &self.body[location.block].terminator
         {
-            let (method_did, method_substs) = if let Some(info) =
+            let Some((method_did, method_substs)) =
                 rustc_const_eval::util::find_self_call(
                     self.infcx.tcx,
                     &self.body,
                     target_temp,
                     location.block,
-                ) {
-                info
-            } else {
+                )
+            else {
                 return normal_ret;
             };
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 5963904aa0b..7d0dde53c2b 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -639,11 +639,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         let hir_map = self.infcx.tcx.hir();
         let my_def = self.body.source.def_id();
         let my_hir = hir_map.local_def_id_to_hir_id(my_def.as_local().unwrap());
-        let td = if let Some(a) =
+        let Some(td) =
             self.infcx.tcx.impl_of_method(my_def).and_then(|x| self.infcx.tcx.trait_id_of_impl(x))
-        {
-            a
-        } else {
+        else {
             return (false, None);
         };
         (
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index ca1e77ff8fd..e6a323d676e 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -5,6 +5,7 @@ use rustc_infer::infer::{
     error_reporting::nice_region_error::NiceRegionError,
     error_reporting::unexpected_hidden_region_diagnostic, NllRegionVariableOrigin,
 };
+use rustc_middle::hir::place::PlaceBase;
 use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
 use rustc_middle::ty::subst::{InternalSubsts, Subst};
 use rustc_middle::ty::{self, RegionVid, Ty};
@@ -421,17 +422,26 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
         diag.span_label(*span, message);
 
-        // FIXME(project-rfc-2229#48): This should store a captured_place not a hir id
-        if let ReturnConstraint::ClosureUpvar(upvar) = kind {
+        if let ReturnConstraint::ClosureUpvar(upvar_field) = kind {
             let def_id = match self.regioncx.universal_regions().defining_ty {
                 DefiningTy::Closure(def_id, _) => def_id,
                 ty => bug!("unexpected DefiningTy {:?}", ty),
             };
 
-            let upvar_def_span = self.infcx.tcx.hir().span(upvar);
-            let upvar_span = self.infcx.tcx.upvars_mentioned(def_id).unwrap()[&upvar].span;
-            diag.span_label(upvar_def_span, "variable defined here");
-            diag.span_label(upvar_span, "variable captured here");
+            let captured_place = &self.upvars[upvar_field.index()].place;
+            let defined_hir = match captured_place.place.base {
+                PlaceBase::Local(hirid) => Some(hirid),
+                PlaceBase::Upvar(upvar) => Some(upvar.var_path.hir_id),
+                _ => None,
+            };
+
+            if defined_hir.is_some() {
+                let upvars_map = self.infcx.tcx.upvars_mentioned(def_id).unwrap();
+                let upvar_def_span = self.infcx.tcx.hir().span(defined_hir.unwrap());
+                let upvar_span = upvars_map.get(&defined_hir.unwrap()).unwrap().span;
+                diag.span_label(upvar_def_span, "variable defined here");
+                diag.span_label(upvar_span, "variable captured here");
+            }
         }
 
         if let Some(fr_span) = self.give_region_a_name(*outlived_fr).unwrap().span() {
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index dee47a3e440..abd6a15334c 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -2156,24 +2156,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 }
             }
 
-            // When in async fn, prefer errors that come from inside the closure.
-            if !categorized_path[i].from_closure {
-                let span = categorized_path.iter().find_map(|p| {
-                    if p.from_closure
-                        && p.category == categorized_path[i].category
-                        && categorized_path[i].cause.span.contains(p.cause.span)
-                    {
-                        Some(p.cause.span)
-                    } else {
-                        None
-                    }
-                });
-
-                if let Some(span) = span {
-                    categorized_path[i].cause.span = span;
-                }
-            }
-
             return categorized_path[i].clone();
         }
 
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 46924f50d2e..a5824090096 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2530,9 +2530,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             body,
         );
         let category = if let Some(field) = field {
-            let var_hir_id = self.borrowck_context.upvars[field.index()].place.get_root_variable();
-            // FIXME(project-rfc-2229#8): Use Place for better diagnostics
-            ConstraintCategory::ClosureUpvar(var_hir_id)
+            ConstraintCategory::ClosureUpvar(field)
         } else {
             ConstraintCategory::Boring
         };
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index eb08170959b..c06af5206d5 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -6,9 +6,7 @@ use rustc_expand::base::{self, DummyResult};
 
 /// Emits errors for literal expressions that are invalid inside and outside of an array.
 fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_nested: bool) {
-    let lit = if let ast::ExprKind::Lit(lit) = &expr.kind {
-        lit
-    } else {
+    let ast::ExprKind::Lit(lit) = &expr.kind else {
         unreachable!();
     };
     match lit.kind {
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 0289acac606..38877399943 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -9,6 +9,7 @@
 #![feature(decl_macro)]
 #![feature(is_sorted)]
 #![feature(nll)]
+#![feature(let_else)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
 #![recursion_limit = "256"]
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index 6f61e4cba07..c9dd114047b 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -56,7 +56,6 @@ pub fn inject(
     is_proc_macro_crate: bool,
     has_proc_macro_decls: bool,
     is_test_crate: bool,
-    num_crate_types: usize,
     handler: &rustc_errors::Handler,
 ) -> ast::Crate {
     let ecfg = ExpansionConfig::default("proc_macro".to_string());
@@ -81,10 +80,6 @@ pub fn inject(
         return krate;
     }
 
-    if num_crate_types > 1 {
-        handler.err("cannot mix `proc-macro` crate type with others");
-    }
-
     if is_test_crate {
         return krate;
     }
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index 9459bb7047f..69087962405 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -6,6 +6,7 @@ use rustc_ast as ast;
 use rustc_ast::attr;
 use rustc_ast::ptr::P;
 use rustc_ast_pretty::pprust;
+use rustc_errors::Applicability;
 use rustc_expand::base::*;
 use rustc_session::Session;
 use rustc_span::symbol::{sym, Ident, Symbol};
@@ -102,11 +103,20 @@ pub fn expand_test_or_bench(
         }
     };
 
-    if let ast::ItemKind::MacCall(_) = item.kind {
-        cx.sess.parse_sess.span_diagnostic.span_warn(
-            item.span,
-            "`#[test]` attribute should not be used on macros. Use `#[cfg(test)]` instead.",
-        );
+    // Note: non-associated fn items are already handled by `expand_test_or_bench`
+    if !matches!(item.kind, ast::ItemKind::Fn(_)) {
+        cx.sess
+            .parse_sess
+            .span_diagnostic
+            .struct_span_err(
+                attr_sp,
+                "the `#[test]` attribute may only be used on a non-associated function",
+            )
+            .note("the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions")
+            .span_label(item.span, format!("expected a non-associated function, found {} {}", item.kind.article(), item.kind.descr()))
+            .span_suggestion(attr_sp, "replace with conditional compilation to make the item only exist when tests are being run", String::from("#[cfg(test)]"), Applicability::MaybeIncorrect)
+            .emit();
+
         return vec![Annotatable::Item(item)];
     }
 
@@ -466,7 +476,7 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
             (false, _) => true,
         }
     } else {
-        sd.span_err(i.span, "only functions may be used as tests");
+        // should be unreachable because `is_test_fn_item` should catch all non-fn items
         false
     }
 }
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 30a52d6bd67..f6d7221d4e9 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -55,6 +55,19 @@ pub fn sanitize<'ll>(cx: &CodegenCx<'ll, '_>, no_sanitize: SanitizerSet, llfn: &
     if enabled.contains(SanitizerSet::HWADDRESS) {
         llvm::Attribute::SanitizeHWAddress.apply_llfn(Function, llfn);
     }
+    if enabled.contains(SanitizerSet::MEMTAG) {
+        // Check to make sure the mte target feature is actually enabled.
+        let sess = cx.tcx.sess;
+        let features = llvm_util::llvm_global_features(sess).join(",");
+        let mte_feature_enabled = features.rfind("+mte");
+        let mte_feature_disabled = features.rfind("-mte");
+
+        if mte_feature_enabled.is_none() || (mte_feature_disabled > mte_feature_enabled) {
+            sess.err("`-Zsanitizer=memtag` requires `-Ctarget-feature=+mte`");
+        }
+
+        llvm::Attribute::SanitizeMemTag.apply_llfn(Function, llfn);
+    }
 }
 
 /// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index ec68f6eb0f8..90ddf791450 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -292,7 +292,7 @@ pub unsafe fn create_module<'ll>(
             "sign-return-address-all\0".as_ptr().cast(),
             pac_opts.leaf.into(),
         );
-        let is_bkey = if pac_opts.key == PAuthKey::A { false } else { true };
+        let is_bkey: bool = pac_opts.key != PAuthKey::A;
         llvm::LLVMRustAddModuleFlag(
             llmod,
             llvm::LLVMModFlagBehavior::Error,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
index 6dd0d58efe3..acd032a7dc6 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
@@ -6,7 +6,7 @@ use super::CrateDebugContext;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, DefIdTree, Ty};
-use rustc_target::abi::VariantIdx;
+use rustc_target::abi::Variants;
 
 use crate::common::CodegenCx;
 use crate::llvm;
@@ -72,20 +72,15 @@ pub(crate) fn fat_pointer_kind<'ll, 'tcx>(
     match *pointee_ty.kind() {
         ty::Str | ty::Slice(_) => Some(FatPtrKind::Slice),
         ty::Dynamic(..) => Some(FatPtrKind::Dyn),
-        ty::Adt(adt_def, _) => {
-            assert!(adt_def.is_struct());
-            assert!(adt_def.variants.len() == 1);
-            let variant = &adt_def.variants[VariantIdx::from_usize(0)];
-            assert!(!variant.fields.is_empty());
-            let last_field_index = variant.fields.len() - 1;
-
+        ty::Adt(..) | ty::Tuple(..) if matches!(layout.variants, Variants::Single { .. }) => {
+            let last_field_index = layout.fields.count() - 1;
             debug_assert!(
                 (0..last_field_index)
                     .all(|field_index| { !layout.field(cx, field_index).is_unsized() })
             );
 
             let unsized_field = layout.field(cx, last_field_index);
-            assert!(unsized_field.is_unsized());
+            debug_assert!(unsized_field.is_unsized());
             fat_pointer_kind(cx, unsized_field.ty)
         }
         ty::Foreign(_) => {
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 90d4367a280..657f1fcf31e 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -190,6 +190,7 @@ pub enum Attribute {
     StackProtectStrong = 31,
     StackProtect = 32,
     NoUndef = 33,
+    SanitizeMemTag = 34,
 }
 
 /// LLVMIntPredicate
diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index 81d0603bc52..fafb9a6dbde 100644
--- a/compiler/rustc_codegen_llvm/src/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -330,7 +330,9 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
             ty::Ref(..) | ty::RawPtr(_) => {
                 return self.field(cx, index).llvm_type(cx);
             }
-            ty::Adt(def, _) if def.is_box() => {
+            // only wide pointer boxes are handled as pointers
+            // thin pointer boxes with scalar allocators are handled by the general logic below
+            ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
                 let ptr_ty = cx.tcx.mk_mut_ptr(self.ty.boxed_ty());
                 return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
             }
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index e53c9842117..58e0667d678 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -216,17 +216,18 @@ pub fn each_linked_rlib(
         }
         let name = &info.crate_name[&cnum];
         let used_crate_source = &info.used_crate_source[&cnum];
-        let path = if let Some((path, _)) = &used_crate_source.rlib {
-            path
-        } else if used_crate_source.rmeta.is_some() {
-            return Err(format!(
-                "could not find rlib for: `{}`, found rmeta (metadata) file",
-                name
-            ));
+        if let Some((path, _)) = &used_crate_source.rlib {
+            f(cnum, &path);
         } else {
-            return Err(format!("could not find rlib for: `{}`", name));
-        };
-        f(cnum, &path);
+            if used_crate_source.rmeta.is_some() {
+                return Err(format!(
+                    "could not find rlib for: `{}`, found rmeta (metadata) file",
+                    name
+                ));
+            } else {
+                return Err(format!("could not find rlib for: `{}`", name));
+            }
+        }
     }
     Ok(())
 }
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 6849533abc0..9ebbcac76a2 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -200,9 +200,7 @@ fn create_object_file(sess: &Session) -> Option<write::Object<'static>> {
 //   `SHF_EXCLUDE` flag we can set on sections in an object file to get
 //   automatically removed from the final output.
 pub fn create_rmeta_file(sess: &Session, metadata: &[u8]) -> Vec<u8> {
-    let mut file = if let Some(file) = create_object_file(sess) {
-        file
-    } else {
+    let Some(mut file) = create_object_file(sess) else {
         // This is used to handle all "other" targets. This includes targets
         // in two categories:
         //
@@ -262,9 +260,7 @@ pub fn create_compressed_metadata_file(
 ) -> Vec<u8> {
     let mut compressed = rustc_metadata::METADATA_HEADER.to_vec();
     FrameEncoder::new(&mut compressed).write_all(metadata.raw_data()).unwrap();
-    let mut file = if let Some(file) = create_object_file(sess) {
-        file
-    } else {
+    let Some(mut file) = create_object_file(sess) else {
         return compressed.to_vec();
     };
     let section = file.add_section(
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index c21d19a6227..6976999c0e4 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -476,7 +476,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 mir::ProjectionElem::Subslice { from, to, from_end } => {
                     let mut subslice = cg_base.project_index(bx, bx.cx().const_usize(from as u64));
                     let projected_ty =
-                        PlaceTy::from_ty(cg_base.layout.ty).projection_ty(tcx, elem.clone()).ty;
+                        PlaceTy::from_ty(cg_base.layout.ty).projection_ty(tcx, *elem).ty;
                     subslice.layout = bx.cx().layout_of(self.monomorphize(projected_ty));
 
                     if subslice.layout.is_unsized() {
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs
index 3601169528b..85826cfbf01 100644
--- a/compiler/rustc_driver/src/lib.rs
+++ b/compiler/rustc_driver/src/lib.rs
@@ -216,10 +216,12 @@ fn run_compiler(
     }
 
     let cfg = interface::parse_cfgspecs(matches.opt_strs("cfg"));
+    let check_cfg = interface::parse_check_cfg(matches.opt_strs("check-cfg"));
     let (odir, ofile) = make_output(&matches);
     let mut config = interface::Config {
         opts: sopts,
         crate_cfg: cfg,
+        crate_check_cfg: check_cfg,
         input: Input::File(PathBuf::new()),
         input_path: None,
         output_file: ofile,
diff --git a/compiler/rustc_error_codes/src/error_codes/E0760.md b/compiler/rustc_error_codes/src/error_codes/E0760.md
index 65acd4fabdf..e1dcfefebcd 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0760.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0760.md
@@ -1,4 +1,4 @@
-`impl trait` return type cannot contain a projection
+`async fn`/`impl trait` return type cannot contain a projection
 or `Self` that references lifetimes from a parent scope.
 
 Erroneous code example:
@@ -7,7 +7,7 @@ Erroneous code example:
 struct S<'a>(&'a i32);
 
 impl<'a> S<'a> {
-    fn new(i: &'a i32) -> impl Into<Self> {
+    async fn new(i: &'a i32) -> Self {
         S(&22)
     }
 }
@@ -19,7 +19,7 @@ To fix this error we need to spell out `Self` to `S<'a>`:
 struct S<'a>(&'a i32);
 
 impl<'a> S<'a> {
-    fn new(i: &'a i32) -> impl Into<S<'a>> {
+    async fn new(i: &'a i32) -> S<'a> {
         S(&22)
     }
 }
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 8065911afb9..f71fb58cf6b 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -1039,7 +1039,7 @@ fn check_matcher_core(
                                 ));
                                 err.span_suggestion(
                                     span,
-                                    &format!("try a `pat_param` fragment specifier instead"),
+                                    "try a `pat_param` fragment specifier instead",
                                     suggestion,
                                     Applicability::MaybeIncorrect,
                                 );
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 32a9d081ed8..d43f926d0a5 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -70,6 +70,8 @@ declare_features! (
     (accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
     /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
     (accepted, cfg_doctest, "1.40.0", Some(62210), None),
+    /// Enables `#[cfg(panic = "...")]` config key.
+    (accepted, cfg_panic, "1.60.0", Some(77443), None),
     /// Allows `cfg(target_feature = "...")`.
     (accepted, cfg_target_feature, "1.27.0", Some(29717), None),
     /// Allows `cfg(target_vendor = "...")`.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 3c85ff77cfb..5545abc6024 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -285,13 +285,13 @@ declare_features! (
     /// Allows trait methods with arbitrary self types.
     (active, arbitrary_self_types, "1.23.0", Some(44874), None),
     /// Allows using `const` operands in inline assembly.
-    (active, asm_const, "1.58.0", Some(72016), None),
+    (active, asm_const, "1.58.0", Some(93332), None),
     /// Enables experimental inline assembly support for additional architectures.
-    (active, asm_experimental_arch, "1.58.0", Some(72016), None),
+    (active, asm_experimental_arch, "1.58.0", Some(93335), None),
     /// Allows using `sym` operands in inline assembly.
-    (active, asm_sym, "1.58.0", Some(72016), None),
+    (active, asm_sym, "1.58.0", Some(93333), None),
     /// Allows the `may_unwind` option in inline assembly.
-    (active, asm_unwind, "1.58.0", Some(72016), None),
+    (active, asm_unwind, "1.58.0", Some(93334), None),
     /// Allows users to enforce equality of associated constants `TraitImpl<AssocConst=3>`.
     (active, associated_const_equality, "1.58.0", Some(92827), None),
     /// Allows the user of associated type bounds.
@@ -306,8 +306,6 @@ declare_features! (
     (active, c_variadic, "1.34.0", Some(44930), None),
     /// Allows capturing disjoint fields in a closure/generator (RFC 2229).
     (incomplete, capture_disjoint_fields, "1.49.0", Some(53488), None),
-    /// Enables `#[cfg(panic = "...")]` config key.
-    (active, cfg_panic, "1.49.0", Some(77443), None),
     /// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used.
     (active, cfg_sanitize, "1.41.0", Some(39699), None),
     /// Allows `cfg(target_abi = "...")`.
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index d9a986aba7d..1fb1a38a927 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -34,7 +34,6 @@ const GATED_CFGS: &[GatedCfg] = &[
     (sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
     (sym::sanitize, sym::cfg_sanitize, cfg_fn!(cfg_sanitize)),
     (sym::version, sym::cfg_version, cfg_fn!(cfg_version)),
-    (sym::panic, sym::cfg_panic, cfg_fn!(cfg_panic)),
 ];
 
 /// Find a gated cfg determined by the `pred`icate which is given the cfg's name.
diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs
index cf86c450a5b..7f376c5fbe5 100644
--- a/compiler/rustc_index/src/bit_set.rs
+++ b/compiler/rustc_index/src/bit_set.rs
@@ -852,11 +852,7 @@ impl<T: Idx> HybridBitSet<T> {
             Bound::Excluded(end) => end.index(),
             Bound::Unbounded => self.domain_size() - 1,
         };
-        let len = if let Some(l) = end.checked_sub(start) {
-            l
-        } else {
-            return;
-        };
+        let Some(len) = end.checked_sub(start) else { return };
         match self {
             HybridBitSet::Sparse(sparse) if sparse.len() + len < SPARSE_MAX => {
                 // The set is sparse and has space for `elems`.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index aba5666b58c..205ad044554 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -497,16 +497,32 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         let ty_to_string = |ty: Ty<'tcx>| -> String {
             let mut s = String::new();
             let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
-            let mut inner = self.inner.borrow_mut();
-            let ty_vars = inner.type_variables();
-            let getter = move |ty_vid| {
-                let var_origin = ty_vars.var_origin(ty_vid);
-                if let TypeVariableOriginKind::TypeParameterDefinition(name, _) = var_origin.kind {
+            let ty_getter = move |ty_vid| {
+                if let TypeVariableOriginKind::TypeParameterDefinition(name, _) =
+                    self.inner.borrow_mut().type_variables().var_origin(ty_vid).kind
+                {
+                    Some(name.to_string())
+                } else {
+                    None
+                }
+            };
+            printer.ty_infer_name_resolver = Some(Box::new(ty_getter));
+            let const_getter = move |ct_vid| {
+                if let ConstVariableOriginKind::ConstParameterDefinition(name, _) = self
+                    .inner
+                    .borrow_mut()
+                    .const_unification_table()
+                    .probe_value(ct_vid)
+                    .origin
+                    .kind
+                {
                     return Some(name.to_string());
+                } else {
+                    None
                 }
-                None
             };
-            printer.name_resolver = Some(Box::new(&getter));
+            printer.const_infer_name_resolver = Some(Box::new(const_getter));
+
             let _ = if let ty::FnDef(..) = ty.kind() {
                 // We don't want the regular output for `fn`s because it includes its path in
                 // invalid pseudo-syntax, we want the `fn`-pointer output instead.
@@ -553,8 +569,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         let ty_msg = match (local_visitor.found_node_ty, local_visitor.found_exact_method_call) {
             (_, Some(_)) => String::new(),
             (Some(ty), _) if ty.is_closure() => {
-                let substs =
-                    if let ty::Closure(_, substs) = *ty.kind() { substs } else { unreachable!() };
+                let ty::Closure(_, substs) = *ty.kind() else { unreachable!() };
                 let fn_sig = substs.as_closure().sig();
                 let args = closure_args(&fn_sig);
                 let ret = fn_sig.output().skip_binder().to_string();
@@ -597,8 +612,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         let param_type = arg_data.kind.descr();
         let suffix = match local_visitor.found_node_ty {
             Some(ty) if ty.is_closure() => {
-                let substs =
-                    if let ty::Closure(_, substs) = *ty.kind() { substs } else { unreachable!() };
+                let ty::Closure(_, substs) = *ty.kind() else { unreachable!() };
                 let fn_sig = substs.as_closure().sig();
                 let ret = fn_sig.output().skip_binder().to_string();
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
index 8512597cb91..f44e6e04346 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs
@@ -64,7 +64,7 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
             .or_else(|| self.try_report_mismatched_static_lifetime())
     }
 
-    pub fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> {
+    pub(super) fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> {
         match (&self.error, self.regions) {
             (Some(ConcreteFailure(origin, sub, sup)), None) => Some((origin.span(), *sub, *sup)),
             (Some(SubSupConflict(_, _, origin, sub, _, sup, _)), None) => {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index 8e5efa12ac6..8671ecba6e9 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -102,6 +102,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "...so that the definition in impl matches the definition from the trait",
                 );
             }
+            infer::CheckAssociatedTypeBounds { ref parent, .. } => {
+                self.note_region_origin(err, &parent);
+            }
         }
     }
 
@@ -345,6 +348,55 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     trait_item_def_id,
                     &format!("`{}: {}`", sup, sub),
                 ),
+            infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => {
+                let mut err = self.report_concrete_failure(*parent, sub, sup);
+
+                let trait_item_span = self.tcx.def_span(trait_item_def_id);
+                let item_name = self.tcx.item_name(impl_item_def_id);
+                err.span_label(
+                    trait_item_span,
+                    format!("definition of `{}` from trait", item_name),
+                );
+
+                let trait_predicates = self.tcx.explicit_predicates_of(trait_item_def_id);
+                let impl_predicates = self.tcx.explicit_predicates_of(impl_item_def_id);
+
+                let impl_predicates: rustc_data_structures::stable_set::FxHashSet<_> =
+                    impl_predicates.predicates.into_iter().map(|(pred, _)| pred).collect();
+                let clauses: Vec<_> = trait_predicates
+                    .predicates
+                    .into_iter()
+                    .filter(|&(pred, _)| !impl_predicates.contains(pred))
+                    .map(|(pred, _)| format!("{}", pred))
+                    .collect();
+
+                if !clauses.is_empty() {
+                    let where_clause_span = self
+                        .tcx
+                        .hir()
+                        .get_generics(impl_item_def_id.expect_local())
+                        .unwrap()
+                        .where_clause
+                        .tail_span_for_suggestion();
+
+                    let suggestion = format!(
+                        "{} {}",
+                        if !impl_predicates.is_empty() { "," } else { " where" },
+                        clauses.join(", "),
+                    );
+                    err.span_suggestion(
+                        where_clause_span,
+                        &format!(
+                            "try copying {} from the trait",
+                            if clauses.len() > 1 { "these clauses" } else { "this clause" }
+                        ),
+                        suggestion,
+                        rustc_errors::Applicability::MaybeIncorrect,
+                    );
+                }
+
+                err
+            }
         }
     }
 
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index f0a4ec81313..57ac98ca897 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -438,6 +438,13 @@ pub enum SubregionOrigin<'tcx> {
     /// Comparing the signature and requirements of an impl associated type
     /// against the containing trait
     CompareImplTypeObligation { span: Span, impl_item_def_id: DefId, trait_item_def_id: DefId },
+
+    /// Checking that the bounds of a trait's associated type hold for a given impl
+    CheckAssociatedTypeBounds {
+        parent: Box<SubregionOrigin<'tcx>>,
+        impl_item_def_id: DefId,
+        trait_item_def_id: DefId,
+    },
 }
 
 // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -1832,6 +1839,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
             ReferenceOutlivesReferent(_, a) => a,
             CompareImplMethodObligation { span, .. } => span,
             CompareImplTypeObligation { span, .. } => span,
+            CheckAssociatedTypeBounds { ref parent, .. } => parent.span(),
         }
     }
 
@@ -1862,6 +1870,15 @@ impl<'tcx> SubregionOrigin<'tcx> {
                 trait_item_def_id,
             },
 
+            traits::ObligationCauseCode::CheckAssociatedTypeBounds {
+                impl_item_def_id,
+                trait_item_def_id,
+            } => SubregionOrigin::CheckAssociatedTypeBounds {
+                impl_item_def_id,
+                trait_item_def_id,
+                parent: Box::new(default()),
+            },
+
             _ => default(),
         }
     }
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index e79ece9a4a4..e7dca94806c 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -276,7 +276,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         debug!(?concrete_ty);
 
         let first_own_region = match opaque_defn.origin {
-            hir::OpaqueTyOrigin::FnReturn(..) => {
+            hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {
                 // We lower
                 //
                 // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm>
@@ -291,7 +291,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             }
             // These opaque type inherit all lifetime parameters from their
             // parent, so we have to check them all.
-            hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::TyAlias => 0,
+            hir::OpaqueTyOrigin::TyAlias => 0,
         };
 
         // For a case like `impl Foo<'a, 'b>`, we would generate a constraint
diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs
index 0864edf4451..74c44089045 100644
--- a/compiler/rustc_infer/src/infer/type_variable.rs
+++ b/compiler/rustc_infer/src/infer/type_variable.rs
@@ -263,7 +263,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
         let index = self.values().push(TypeVariableData { origin });
         assert_eq!(eq_key.vid.as_u32(), index as u32);
 
-        debug!("new_var(index={:?}, universe={:?}, origin={:?}", eq_key.vid, universe, origin,);
+        debug!("new_var(index={:?}, universe={:?}, origin={:?})", eq_key.vid, universe, origin);
 
         eq_key.vid
     }
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 9a588b55393..609fc4b78c0 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -2,7 +2,7 @@ pub use crate::passes::BoxedResolver;
 use crate::util;
 
 use rustc_ast::token;
-use rustc_ast::{self as ast, MetaItemKind};
+use rustc_ast::{self as ast, LitKind, MetaItemKind};
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::Lrc;
@@ -13,12 +13,13 @@ use rustc_lint::LintStore;
 use rustc_middle::ty;
 use rustc_parse::maybe_new_parser_from_source_str;
 use rustc_query_impl::QueryCtxt;
-use rustc_session::config::{self, ErrorOutputType, Input, OutputFilenames};
+use rustc_session::config::{self, CheckCfg, ErrorOutputType, Input, OutputFilenames};
 use rustc_session::early_error;
 use rustc_session::lint;
 use rustc_session::parse::{CrateConfig, ParseSess};
 use rustc_session::{DiagnosticOutput, Session};
 use rustc_span::source_map::{FileLoader, FileName};
+use rustc_span::symbol::sym;
 use std::path::PathBuf;
 use std::result;
 
@@ -139,6 +140,90 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
     })
 }
 
+/// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`.
+pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
+    rustc_span::create_default_session_if_not_set_then(move |_| {
+        let mut cfg = CheckCfg::default();
+
+        'specs: for s in specs {
+            let sess = ParseSess::with_silent_emitter(Some(format!(
+                "this error occurred on the command line: `--check-cfg={}`",
+                s
+            )));
+            let filename = FileName::cfg_spec_source_code(&s);
+
+            macro_rules! error {
+                ($reason: expr) => {
+                    early_error(
+                        ErrorOutputType::default(),
+                        &format!(
+                            concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"),
+                            s
+                        ),
+                    );
+                };
+            }
+
+            match maybe_new_parser_from_source_str(&sess, filename, s.to_string()) {
+                Ok(mut parser) => match &mut parser.parse_meta_item() {
+                    Ok(meta_item) if parser.token == token::Eof => {
+                        if let Some(args) = meta_item.meta_item_list() {
+                            if meta_item.has_name(sym::names) {
+                                cfg.names_checked = true;
+                                for arg in args {
+                                    if arg.is_word() && arg.ident().is_some() {
+                                        let ident = arg.ident().expect("multi-segment cfg key");
+                                        cfg.names_valid.insert(ident.name.to_string());
+                                    } else {
+                                        error!("`names()` arguments must be simple identifers");
+                                    }
+                                }
+                                continue 'specs;
+                            } else if meta_item.has_name(sym::values) {
+                                if let Some((name, values)) = args.split_first() {
+                                    if name.is_word() && name.ident().is_some() {
+                                        let ident = name.ident().expect("multi-segment cfg key");
+                                        cfg.values_checked.insert(ident.to_string());
+                                        for val in values {
+                                            if let Some(LitKind::Str(s, _)) =
+                                                val.literal().map(|lit| &lit.kind)
+                                            {
+                                                cfg.values_valid
+                                                    .insert((ident.to_string(), s.to_string()));
+                                            } else {
+                                                error!(
+                                                    "`values()` arguments must be string literals"
+                                                );
+                                            }
+                                        }
+
+                                        continue 'specs;
+                                    } else {
+                                        error!(
+                                            "`values()` first argument must be a simple identifer"
+                                        );
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    Ok(..) => {}
+                    Err(err) => err.cancel(),
+                },
+                Err(errs) => errs.into_iter().for_each(|mut err| err.cancel()),
+            }
+
+            error!(
+                "expected `names(name1, name2, ... nameN)` or \
+                `values(name, \"value1\", \"value2\", ... \"valueN\")`"
+            );
+        }
+
+        cfg.names_valid.extend(cfg.values_checked.iter().cloned());
+        cfg
+    })
+}
+
 /// The compiler configuration
 pub struct Config {
     /// Command line options
@@ -146,6 +231,7 @@ pub struct Config {
 
     /// cfg! configuration in addition to the default ones
     pub crate_cfg: FxHashSet<(String, Option<String>)>,
+    pub crate_check_cfg: CheckCfg,
 
     pub input: Input,
     pub input_path: Option<PathBuf>,
@@ -188,6 +274,7 @@ pub fn create_compiler_and_run<R>(config: Config, f: impl FnOnce(&Compiler) -> R
     let (mut sess, codegen_backend) = util::create_session(
         config.opts,
         config.crate_cfg,
+        config.crate_check_cfg,
         config.diagnostic_output,
         config.file_loader,
         config.input_path.clone(),
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 66e1e78b285..c0552fd200b 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -393,8 +393,18 @@ pub fn configure_and_expand(
     });
 
     let crate_types = sess.crate_types();
+    let is_executable_crate = crate_types.contains(&CrateType::Executable);
     let is_proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
 
+    if crate_types.len() > 1 {
+        if is_executable_crate {
+            sess.err("cannot mix `bin` crate type with others");
+        }
+        if is_proc_macro_crate {
+            sess.err("cannot mix `proc-macro` crate type with others");
+        }
+    }
+
     // For backwards compatibility, we don't try to run proc macro injection
     // if rustdoc is run on a proc macro crate without '--crate-type proc-macro' being
     // specified. This should only affect users who manually invoke 'rustdoc', as
@@ -411,7 +421,6 @@ pub fn configure_and_expand(
         msg.emit()
     } else {
         krate = sess.time("maybe_create_a_macro_crate", || {
-            let num_crate_types = crate_types.len();
             let is_test_crate = sess.opts.test;
             rustc_builtin_macros::proc_macro_harness::inject(
                 sess,
@@ -420,7 +429,6 @@ pub fn configure_and_expand(
                 is_proc_macro_crate,
                 has_proc_macro_decls,
                 is_test_crate,
-                num_crate_types,
                 sess.diagnostic(),
             )
         });
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 700710c82c9..46964f52685 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -15,6 +15,7 @@ use rustc_parse::validate_attr;
 use rustc_query_impl::QueryCtxt;
 use rustc_resolve::{self, Resolver};
 use rustc_session as session;
+use rustc_session::config::CheckCfg;
 use rustc_session::config::{self, CrateType};
 use rustc_session::config::{ErrorOutputType, Input, OutputFilenames};
 use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
@@ -65,6 +66,7 @@ pub fn add_configuration(
 pub fn create_session(
     sopts: config::Options,
     cfg: FxHashSet<(String, Option<String>)>,
+    check_cfg: CheckCfg,
     diagnostic_output: DiagnosticOutput,
     file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
     input_path: Option<PathBuf>,
@@ -100,7 +102,13 @@ pub fn create_session(
 
     let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg));
     add_configuration(&mut cfg, &mut sess, &*codegen_backend);
+
+    let mut check_cfg = config::to_crate_check_config(check_cfg);
+    check_cfg.fill_well_known();
+    check_cfg.fill_actual(&cfg);
+
     sess.parse_sess.config = cfg;
+    sess.parse_sess.check_config = check_cfg;
 
     (Lrc::new(sess), Lrc::new(codegen_backend))
 }
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index f4eba25475e..adec1a3ab00 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2957,6 +2957,43 @@ declare_lint! {
     };
 }
 
+declare_lint! {
+    /// The `unexpected_cfgs` lint detects unexpected conditional compilation conditions.
+    ///
+    /// ### Example
+    ///
+    /// ```text
+    /// rustc --check-cfg 'names()'
+    /// ```
+    ///
+    /// ```rust,ignore (needs command line option)
+    /// #[cfg(widnows)]
+    /// fn foo() {}
+    /// ```
+    ///
+    /// This will produce:
+    ///
+    /// ```text
+    /// warning: unknown condition name used
+    ///  --> lint_example.rs:1:7
+    ///   |
+    /// 1 | #[cfg(widnows)]
+    ///   |       ^^^^^^^
+    ///   |
+    ///   = note: `#[warn(unexpected_cfgs)]` on by default
+    /// ```
+    ///
+    /// ### Explanation
+    ///
+    /// This lint is only active when a `--check-cfg='names(...)'` option has been passed
+    /// to the compiler and triggers whenever an unknown condition name or value is used.
+    /// The known condition include names or values passed in `--check-cfg`, `--cfg`, and some
+    /// well-knows names and values built into the compiler.
+    pub UNEXPECTED_CFGS,
+    Warn,
+    "detects unexpected names and values in `#[cfg]` conditions",
+}
+
 declare_lint_pass! {
     /// Does nothing as a lint pass, but registers some `Lint`s
     /// that are used by other parts of the compiler.
@@ -3055,6 +3092,7 @@ declare_lint_pass! {
         DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
         DUPLICATE_MACRO_ATTRIBUTES,
         SUSPICIOUS_AUTO_TRAIT_IMPLS,
+        UNEXPECTED_CFGS,
     ]
 }
 
diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
index 9e0a9b354e1..a2b0e9b4d29 100644
--- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
+++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
@@ -83,6 +83,7 @@ enum LLVMRustAttribute {
   StackProtectStrong = 31,
   StackProtect = 32,
   NoUndef = 33,
+  SanitizeMemTag = 34,
 };
 
 typedef struct OpaqueRustString *RustStringRef;
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 23333199506..c8f31adbfd9 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -226,6 +226,8 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
     return Attribute::StackProtect;
   case NoUndef:
     return Attribute::NoUndef;
+  case SanitizeMemTag:
+    return Attribute::SanitizeMemTag;
   }
   report_fatal_error("bad AttributeKind");
 }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 87a88fbac71..66968c9ba54 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1032,13 +1032,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     }
 
     /// Iterates over the language items in the given crate.
-    fn get_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
-        tcx.arena.alloc_from_iter(
-            self.root
-                .lang_items
-                .decode(self)
-                .map(|(def_index, index)| (self.local_def_id(def_index), index)),
-        )
+    fn get_lang_items(self) -> impl Iterator<Item = (DefId, usize)> + 'a {
+        self.root
+            .lang_items
+            .decode(self)
+            .map(move |(def_index, index)| (self.local_def_id(def_index), index))
     }
 
     /// Iterates over the diagnostic items in the given crate.
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 9b0272e7fd3..7708b5193f4 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -200,7 +200,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
         tcx.arena.alloc_slice(&result)
     }
     defined_lib_features => { cdata.get_lib_features(tcx) }
-    defined_lang_items => { cdata.get_lang_items(tcx) }
+    defined_lang_items => { tcx.arena.alloc_from_iter(cdata.get_lang_items()) }
     diagnostic_items => { cdata.get_diagnostic_items() }
     missing_lang_items => { cdata.get_missing_lang_items(tcx) }
 
@@ -501,6 +501,11 @@ impl CStore {
     ) -> impl Iterator<Item = (DefId, DefId)> + '_ {
         self.get_crate_data(cnum).get_inherent_impls()
     }
+
+    /// Decodes all lang items in the crate (for rustdoc).
+    pub fn lang_items_untracked(&self, cnum: CrateNum) -> impl Iterator<Item = DefId> + '_ {
+        self.get_crate_data(cnum).get_lang_items().map(|(def_id, _)| def_id)
+    }
 }
 
 impl CrateStore for CStore {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 4d6b97eff24..4dea04e62ff 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -982,7 +982,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         for local_id in hir.iter_local_def_id() {
             let def_id = local_id.to_def_id();
             let def_kind = tcx.opt_def_kind(local_id);
-            let def_kind = if let Some(def_kind) = def_kind { def_kind } else { continue };
+            let Some(def_kind) = def_kind else { continue };
             record!(self.tables.def_kind[def_id] <- match def_kind {
                 // Replace Ctor by the enclosing object to avoid leaking details in children crates.
                 DefKind::Ctor(CtorOf::Struct, _) => DefKind::Struct,
diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs
index cf50378ad60..6bfd1b7ffab 100644
--- a/compiler/rustc_middle/src/dep_graph/mod.rs
+++ b/compiler/rustc_middle/src/dep_graph/mod.rs
@@ -61,7 +61,7 @@ impl rustc_query_system::dep_graph::DepKind for DepKind {
         OP: for<'a> FnOnce(TaskDepsRef<'a>),
     {
         ty::tls::with_context_opt(|icx| {
-            let icx = if let Some(icx) = icx { icx } else { return };
+            let Some(icx) = icx else { return };
             op(icx.task_deps)
         })
     }
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 03cca51dc0b..fedf456ccc8 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -198,7 +198,7 @@ fn deprecation_message(
     } else {
         let since = since.as_ref().map(Symbol::as_str);
 
-        if since.as_deref() == Some("TBD") {
+        if since == Some("TBD") {
             format!("use of {} `{}` that will be deprecated in a future Rust version", kind, path)
         } else {
             format!(
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 5c616425957..fbd5a2d08a5 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -341,7 +341,7 @@ pub enum ConstraintCategory {
     /// like `Foo { field: my_val }`)
     Usage,
     OpaqueType,
-    ClosureUpvar(hir::HirId),
+    ClosureUpvar(Field),
 
     /// A constraint from a user-written predicate
     /// with the provided span, written on the item
@@ -363,7 +363,7 @@ pub enum ConstraintCategory {
 #[derive(TyEncodable, TyDecodable, HashStable)]
 pub enum ReturnConstraint {
     Normal,
-    ClosureUpvar(hir::HirId),
+    ClosureUpvar(Field),
 }
 
 /// The subject of a `ClosureOutlivesRequirement` -- that is, the thing
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 1123cab8076..b54418e5201 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -285,6 +285,12 @@ pub enum ObligationCauseCode<'tcx> {
         trait_item_def_id: DefId,
     },
 
+    /// Checking that the bounds of a trait's associated type hold for a given impl
+    CheckAssociatedTypeBounds {
+        impl_item_def_id: DefId,
+        trait_item_def_id: DefId,
+    },
+
     /// Checking that this expression can be assigned where it needs to be
     // FIXME(eddyb) #11161 is the original Expr required?
     ExprAssignable,
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index b3006672e22..4922d07ae1c 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -1,38 +1,56 @@
-//! Generalized type folding mechanism. The setup is a bit convoluted
-//! but allows for convenient usage. Let T be an instance of some
-//! "foldable type" (one which implements `TypeFoldable`) and F be an
-//! instance of a "folder" (a type which implements `TypeFolder`). Then
-//! the setup is intended to be:
+//! A generalized traversal mechanism for complex data structures that contain
+//! type information.
 //!
-//!     T.fold_with(F) --calls--> F.fold_T(T) --calls--> T.super_fold_with(F)
+//! There are two types of traversal.
+//! - Folding. This is a modifying traversal. It consumes the data structure,
+//!   producing a (possibly) modified version of it. Both fallible and
+//!   infallible versions are available. The name is potentially
+//!   confusing, because this traversal is more like `Iterator::map` than
+//!   `Iterator::fold`.
+//! - Visiting. This is a read-only traversal of the data structure.
 //!
-//! This way, when you define a new folder F, you can override
-//! `fold_T()` to customize the behavior, and invoke `T.super_fold_with()`
-//! to get the original behavior. Meanwhile, to actually fold
-//! something, you can just write `T.fold_with(F)`, which is
-//! convenient. (Note that `fold_with` will also transparently handle
-//! things like a `Vec<T>` where T is foldable and so on.)
+//! These traversals have limited flexibility. Only a small number of "types of
+//! interest" within the complex data structures can receive custom
+//! modification (when folding) or custom visitation (when visiting). These are
+//! the ones containing the most important type-related information, such as
+//! `Ty`, `Predicate`, `Region`, and `Const`.
 //!
-//! In this ideal setup, the only function that actually *does*
-//! anything is `T.super_fold_with()`, which traverses the type `T`.
-//! Moreover, `T.super_fold_with()` should only ever call `T.fold_with()`.
+//! There are two traits involved in each traversal type.
+//! - The first trait is `TypeFoldable`, which is implemented once for many
+//!   types. This includes both (a) types of interest, and (b) all other
+//!   relevant types, including generic containers like `Vec` and `Option`. It
+//!   defines a "skeleton" of how they should be traversed, for both folding
+//!   and visiting.
+//! - The second trait is `TypeFolder`/`FallibleTypeFolder` (for
+//!   infallible/fallible folding traversals) or `TypeVisitor` (for visiting
+//!   traversals). One of these is implemented for each folder/visitor. This
+//!   defines how types of interest are handled.
 //!
-//! In some cases, we follow a degenerate pattern where we do not have
-//! a `fold_T` method. Instead, `T.fold_with` traverses the structure directly.
-//! This is suboptimal because the behavior cannot be overridden, but it's
-//! much less work to implement. If you ever *do* need an override that
-//! doesn't exist, it's not hard to convert the degenerate pattern into the
-//! proper thing.
+//! This means each traversal is a mixture of (a) generic traversal operations,
+//! and (b) custom fold/visit operations that are specific to the
+//! folder/visitor.
+//! - The `TypeFoldable` impls handle most of the traversal, and call into
+//!   `TypeFolder`/`FallibleTypeFolder`/`TypeVisitor` when they encounter a
+//!   type of interest.
+//! - A `TypeFolder`/`FallibleTypeFolder`/`TypeVisitor` may also call back into
+//!   a `TypeFoldable` impl, because (a) the types of interest are recursive
+//!   and can contain other types of interest, and (b) each folder/visitor
+//!   might provide custom handling only for some types of interest, or only
+//!   for some variants of each type of interest, and then use default
+//!   traversal for the remaining cases.
 //!
-//! A `TypeFoldable` T can also be visited by a `TypeVisitor` V using similar setup:
-//!
-//!     T.visit_with(V) --calls--> V.visit_T(T) --calls--> T.super_visit_with(V).
-//!
-//! These methods return true to indicate that the visitor has found what it is
-//! looking for, and does not need to visit anything else.
+//! For example, if you have `struct S(Ty, U)` where `S: TypeFoldable` and `U:
+//! TypeFoldable`, and an instance `S(ty, u)`, it would be visited like so:
+//! ```
+//! s.visit_with(visitor) calls
+//! - s.super_visit_with(visitor) calls
+//!   - ty.visit_with(visitor) calls
+//!     - visitor.visit_ty(ty) may call
+//!       - ty.super_visit_with(visitor)
+//!   - u.visit_with(visitor)
+//! ```
 use crate::mir;
 use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags};
-use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 
 use rustc_data_structures::fx::FxHashSet;
@@ -41,42 +59,67 @@ use std::collections::BTreeMap;
 use std::fmt;
 use std::ops::ControlFlow;
 
-/// This trait is implemented for every type that can be folded.
-/// Basically, every type that has a corresponding method in `TypeFolder`.
+/// This trait is implemented for every type that can be folded/visited,
+/// providing the skeleton of the traversal.
 ///
-/// To implement this conveniently, use the derive macro located in `rustc_macros`.
+/// To implement this conveniently, use the derive macro located in
+/// `rustc_macros`.
 pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
-    /// Consumers may find this more convenient to use with infallible folders than
-    /// [`try_super_fold_with`][`TypeFoldable::try_super_fold_with`], to which the
-    /// provided default definition delegates.  Implementors **should not** override
-    /// this provided default definition, to ensure that the two methods are coherent
-    /// (provide a definition of `try_super_fold_with` instead).
-    fn super_fold_with<F: TypeFolder<'tcx, Error = !>>(self, folder: &mut F) -> Self {
-        self.try_super_fold_with(folder).into_ok()
+    /// The main entry point for folding. To fold a value `t` with a folder `f`
+    /// call: `t.try_fold_with(f)`.
+    ///
+    /// For types of interest (such as `Ty`), this default is overridden with a
+    /// method that calls a folder method specifically for that type (such as
+    /// `F::try_fold_ty`). This is where control transfers from `TypeFoldable`
+    /// to `TypeFolder`.
+    ///
+    /// For other types, this default is used.
+    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
+        self.try_super_fold_with(folder)
     }
-    /// Consumers may find this more convenient to use with infallible folders than
-    /// [`try_fold_with`][`TypeFoldable::try_fold_with`], to which the provided
-    /// default definition delegates.  Implementors **should not** override this
-    /// provided default definition, to ensure that the two methods are coherent
-    /// (provide a definition of `try_fold_with` instead).
+
+    /// A convenient alternative to `try_fold_with` for use with infallible
+    /// folders. Do not override this method, to ensure coherence with
+    /// `try_fold_with`.
     fn fold_with<F: TypeFolder<'tcx, Error = !>>(self, folder: &mut F) -> Self {
         self.try_fold_with(folder).into_ok()
     }
 
+    /// Traverses the type in question, typically by calling `try_fold_with` on
+    /// each field/element. This is true even for types of interest such as
+    /// `Ty`. This should only be called within `TypeFolder` methods, when
+    /// non-custom traversals are desired for types of interest.
     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error>;
 
-    fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
-        self.try_super_fold_with(folder)
+    /// A convenient alternative to `try_super_fold_with` for use with
+    /// infallible folders. Do not override this method, to ensure coherence
+    /// with `try_super_fold_with`.
+    fn super_fold_with<F: TypeFolder<'tcx, Error = !>>(self, folder: &mut F) -> Self {
+        self.try_super_fold_with(folder).into_ok()
     }
 
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
+    /// The entry point for visiting. To visit a value `t` with a visitor `v`
+    /// call: `t.visit_with(v)`.
+    ///
+    /// For types of interest (such as `Ty`), this default is overridden with a
+    /// method that calls a visitor method specifically for that type (such as
+    /// `V::visit_ty`). This is where control transfers from `TypeFoldable` to
+    /// `TypeVisitor`.
+    ///
+    /// For other types, this default is used.
     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         self.super_visit_with(visitor)
     }
 
+    /// Traverses the type in question, typically by calling `visit_with` on
+    /// each field/element. This is true even for types of interest such as
+    /// `Ty`. This should only be called within `TypeVisitor` methods, when
+    /// non-custom traversals are desired for types of interest.
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
+
     /// Returns `true` if `self` has any late-bound regions that are either
     /// bound by `binder` or bound by some binder outside of `binder`.
     /// If `binder` is `ty::INNERMOST`, this indicates whether
@@ -168,24 +211,13 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for hir::Constness {
-    fn try_super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
-        Ok(self)
-    }
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
-        ControlFlow::CONTINUE
-    }
-}
-
-/// The `TypeFolder` trait defines the actual *folding*. There is a
-/// method defined for every foldable type. Each of these has a
-/// default implementation that does an "identity" fold. Within each
-/// identity fold, it should invoke `foo.fold_with(self)` to fold each
-/// sub-item.
+/// This trait is implemented for every folding traversal. There is a fold
+/// method defined for every type of interest. Each such method has a default
+/// that does an "identity" fold.
 ///
 /// If this folder is fallible (and therefore its [`Error`][`TypeFolder::Error`]
-/// associated type is something other than the default, never),
-/// [`FallibleTypeFolder`] should be implemented manually; otherwise,
+/// associated type is something other than the default `!`) then
+/// [`FallibleTypeFolder`] should be implemented manually. Otherwise,
 /// a blanket implementation of [`FallibleTypeFolder`] will defer to
 /// the infallible methods of this trait to ensure that the two APIs
 /// are coherent.
@@ -238,11 +270,9 @@ pub trait TypeFolder<'tcx>: Sized {
     }
 }
 
-/// The `FallibleTypeFolder` trait defines the actual *folding*. There is a
-/// method defined for every foldable type. Each of these has a
-/// default implementation that does an "identity" fold. Within each
-/// identity fold, it should invoke `foo.try_fold_with(self)` to fold each
-/// sub-item.
+/// This trait is implemented for every folding traversal. There is a fold
+/// method defined for every type of interest. Each such method has a default
+/// that does an "identity" fold.
 ///
 /// A blanket implementation of this trait (that defers to the relevant
 /// method of [`TypeFolder`]) is provided for all infallible folders in
@@ -282,8 +312,8 @@ pub trait FallibleTypeFolder<'tcx>: TypeFolder<'tcx> {
     }
 }
 
-// Blanket implementation of fallible trait for infallible folders
-// delegates to infallible methods to prevent incoherence
+// This blanket implementation of the fallible trait for infallible folders
+// delegates to infallible methods to ensure coherence.
 impl<'tcx, F> FallibleTypeFolder<'tcx> for F
 where
     F: TypeFolder<'tcx, Error = !>,
@@ -322,6 +352,9 @@ where
     }
 }
 
+/// This trait is implemented for every visiting traversal. There is a visit
+/// method defined for every type of interest. Each such method has a default
+/// that recurses into the type's fields in a non-custom fashion.
 pub trait TypeVisitor<'tcx>: Sized {
     type BreakTy = !;
 
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index ae838a46157..bf7370c9e0e 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -606,7 +606,7 @@ pub trait PrettyPrinter<'tcx>:
             ty::Infer(infer_ty) => {
                 let verbose = self.tcx().sess.verbose();
                 if let ty::TyVar(ty_vid) = infer_ty {
-                    if let Some(name) = self.infer_ty_name(ty_vid) {
+                    if let Some(name) = self.ty_infer_name(ty_vid) {
                         p!(write("{}", name))
                     } else {
                         if verbose {
@@ -1015,7 +1015,11 @@ pub trait PrettyPrinter<'tcx>:
         }
     }
 
-    fn infer_ty_name(&self, _: ty::TyVid) -> Option<String> {
+    fn ty_infer_name(&self, _: ty::TyVid) -> Option<String> {
+        None
+    }
+
+    fn const_infer_name(&self, _: ty::ConstVid<'tcx>) -> Option<String> {
         None
     }
 
@@ -1203,7 +1207,14 @@ pub trait PrettyPrinter<'tcx>:
                     }
                 }
             }
-            ty::ConstKind::Infer(..) => print_underscore!(),
+            ty::ConstKind::Infer(infer_ct) => {
+                match infer_ct {
+                    ty::InferConst::Var(ct_vid)
+                        if let Some(name) = self.const_infer_name(ct_vid) =>
+                            p!(write("{}", name)),
+                    _ => print_underscore!(),
+                }
+            }
             ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
             ty::ConstKind::Value(value) => {
                 return self.pretty_print_const_value(value, ct.ty(), print_ty);
@@ -1559,7 +1570,8 @@ pub struct FmtPrinterData<'a, 'tcx, F> {
 
     pub region_highlight_mode: RegionHighlightMode<'tcx>,
 
-    pub name_resolver: Option<Box<&'a dyn Fn(ty::TyVid) -> Option<String>>>,
+    pub ty_infer_name_resolver: Option<Box<dyn Fn(ty::TyVid) -> Option<String> + 'a>>,
+    pub const_infer_name_resolver: Option<Box<dyn Fn(ty::ConstVid<'tcx>) -> Option<String> + 'a>>,
 }
 
 impl<'a, 'tcx, F> Deref for FmtPrinter<'a, 'tcx, F> {
@@ -1588,7 +1600,8 @@ impl<'a, 'tcx, F> FmtPrinter<'a, 'tcx, F> {
             binder_depth: 0,
             printed_type_count: 0,
             region_highlight_mode: RegionHighlightMode::new(tcx),
-            name_resolver: None,
+            ty_infer_name_resolver: None,
+            const_infer_name_resolver: None,
         }))
     }
 }
@@ -1843,8 +1856,12 @@ impl<'tcx, F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
 }
 
 impl<'tcx, F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
-    fn infer_ty_name(&self, id: ty::TyVid) -> Option<String> {
-        self.0.name_resolver.as_ref().and_then(|func| func(id))
+    fn ty_infer_name(&self, id: ty::TyVid) -> Option<String> {
+        self.0.ty_infer_name_resolver.as_ref().and_then(|func| func(id))
+    }
+
+    fn const_infer_name(&self, id: ty::ConstVid<'tcx>) -> Option<String> {
+        self.0.const_infer_name_resolver.as_ref().and_then(|func| func(id))
     }
 
     fn print_value_path(
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index b59fb6afe6f..7c57d42631a 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -855,7 +855,7 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
     ) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> {
         Ok(ty::ProjectionPredicate {
             projection_ty: relation.relate(a.projection_ty, b.projection_ty)?,
-            term: relation.relate(a.term, b.term)?.into(),
+            term: relation.relate(a.term, b.term)?,
         })
     }
 }
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index c1d714ed8d6..e4691dee779 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -8,6 +8,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor};
 use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
 use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt};
 use rustc_data_structures::functor::IdFunctor;
+use rustc_hir as hir;
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::CRATE_DEF_INDEX;
 use rustc_index::vec::{Idx, IndexVec};
@@ -663,14 +664,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
 
 ///////////////////////////////////////////////////////////////////////////
 // TypeFoldable implementations.
-//
-// Ideally, each type should invoke `folder.fold_foo(self)` and
-// nothing else. In some cases, though, we haven't gotten around to
-// adding methods on the `folder` yet, and thus the folding is
-// hard-coded here. This is less-flexible, because folders cannot
-// override the behavior, but there are a lot of random types and one
-// can easily refactor the folding into the TypeFolder trait as
-// needed.
 
 /// AdtDefs are basically the same as a DefId.
 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
@@ -1270,3 +1263,13 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> {
         self.substs.visit_with(visitor)
     }
 }
+
+impl<'tcx> TypeFoldable<'tcx> for hir::Constness {
+    fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
+        Ok(self)
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
+        ControlFlow::CONTINUE
+    }
+}
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 9835211a748..7c6d6ea1cb6 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -8,7 +8,9 @@ use crate::infer::canonical::Canonical;
 use crate::ty::fold::ValidateBoundVars;
 use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
 use crate::ty::InferTy::{self, *};
-use crate::ty::{self, AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable};
+use crate::ty::{
+    self, AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitor,
+};
 use crate::ty::{DelaySpanBugEmitted, List, ParamEnv};
 use polonius_engine::Atom;
 use rustc_data_structures::captures::Captures;
@@ -24,7 +26,7 @@ use std::borrow::Cow;
 use std::cmp::Ordering;
 use std::fmt;
 use std::marker::PhantomData;
-use std::ops::{Deref, Range};
+use std::ops::{ControlFlow, Deref, Range};
 use ty::util::IntTypeExt;
 
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
@@ -2072,6 +2074,24 @@ impl<'tcx> Ty<'tcx> {
         !matches!(self.kind(), Param(_) | Infer(_) | Error(_))
     }
 
+    /// Checks whether a type recursively contains another type
+    ///
+    /// Example: `Option<()>` contains `()`
+    pub fn contains(self, other: Ty<'tcx>) -> bool {
+        struct ContainsTyVisitor<'tcx>(Ty<'tcx>);
+
+        impl<'tcx> TypeVisitor<'tcx> for ContainsTyVisitor<'tcx> {
+            type BreakTy = ();
+
+            fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
+                if self.0 == t { ControlFlow::BREAK } else { t.super_visit_with(self) }
+            }
+        }
+
+        let cf = self.visit_with(&mut ContainsTyVisitor(other));
+        cf.is_break()
+    }
+
     /// Returns the type and mutability of `*ty`.
     ///
     /// The parameter `explicit` indicates if this is an *explicit* dereference.
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index 597f7dd95a2..8f4cc182e7f 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -210,7 +210,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn all_impls(self, def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
         let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(def_id);
 
-        blanket_impls.iter().chain(non_blanket_impls.iter().map(|(_, v)| v).flatten()).cloned()
+        blanket_impls.iter().chain(non_blanket_impls.iter().flat_map(|(_, v)| v)).cloned()
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index c2a4cea2b1a..92d9cb2fc1b 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -17,7 +17,7 @@ use rustc_data_structures::intern::Interned;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_errors::ErrorReported;
 use rustc_hir as hir;
-use rustc_hir::def::DefKind;
+use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_macros::HashStable;
 use rustc_query_system::ich::NodeIdHashingMode;
@@ -146,6 +146,37 @@ impl<'tcx> TyCtxt<'tcx> {
         hasher.finish()
     }
 
+    pub fn res_generics_def_id(self, res: Res) -> Option<DefId> {
+        match res {
+            Res::Def(DefKind::Ctor(CtorOf::Variant, _), def_id) => {
+                Some(self.parent(def_id).and_then(|def_id| self.parent(def_id)).unwrap())
+            }
+            Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Struct, _), def_id) => {
+                Some(self.parent(def_id).unwrap())
+            }
+            // Other `DefKind`s don't have generics and would ICE when calling
+            // `generics_of`.
+            Res::Def(
+                DefKind::Struct
+                | DefKind::Union
+                | DefKind::Enum
+                | DefKind::Trait
+                | DefKind::OpaqueTy
+                | DefKind::TyAlias
+                | DefKind::ForeignTy
+                | DefKind::TraitAlias
+                | DefKind::AssocTy
+                | DefKind::Fn
+                | DefKind::AssocFn
+                | DefKind::AssocConst
+                | DefKind::Impl,
+                def_id,
+            ) => Some(def_id),
+            Res::Err => None,
+            _ => None,
+        }
+    }
+
     pub fn has_error_field(self, ty: Ty<'tcx>) -> bool {
         if let ty::Adt(def, substs) = *ty.kind() {
             for field in def.all_fields() {
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index 46de6d939a1..da921904523 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -140,7 +140,7 @@ fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx Cod
     let body = mir_body(tcx, def_id);
     body.basic_blocks()
         .iter()
-        .map(|data| {
+        .flat_map(|data| {
             data.statements.iter().filter_map(|statement| match statement.kind {
                 StatementKind::Coverage(box ref coverage) => {
                     if is_inlined(body, statement) {
@@ -152,7 +152,6 @@ fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx Cod
                 _ => None,
             })
         })
-        .flatten()
         .collect()
 }
 
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 433a1c6ad67..05de52458ad 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -1241,9 +1241,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
     }
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        let yield_ty = if let Some(yield_ty) = body.yield_ty() {
-            yield_ty
-        } else {
+        let Some(yield_ty) = body.yield_ty() else {
             // This only applies to generators
             return;
         };
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index f0e4129b002..55ce5910c81 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -7,6 +7,7 @@ use rustc_index::vec::Idx;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
+use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
 use rustc_span::{hygiene::ExpnKind, ExpnData, Span};
@@ -75,10 +76,18 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
         return false;
     }
 
+    let param_env = tcx.param_env_reveal_all_normalized(def_id);
+    let param_env = rustc_trait_selection::traits::normalize_param_env_or_error(
+        tcx,
+        def_id,
+        param_env,
+        ObligationCause::misc(body.span, hir_id),
+    );
+
     let mut this = Inliner {
         tcx,
-        param_env: tcx.param_env_reveal_all_normalized(body.source.def_id()),
-        codegen_fn_attrs: tcx.codegen_fn_attrs(body.source.def_id()),
+        param_env,
+        codegen_fn_attrs: tcx.codegen_fn_attrs(def_id),
         hir_id,
         history: Vec::new(),
         changed: false,
diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs
index 0392c5a5468..cdfd49ef478 100644
--- a/compiler/rustc_mir_transform/src/normalize_array_len.rs
+++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs
@@ -212,12 +212,7 @@ fn normalize_array_len_call<'tcx>(
                         let Some(local) = place.as_local() else { return };
                         match operand {
                             Operand::Copy(place) | Operand::Move(place) => {
-                                let operand_local =
-                                    if let Some(local) = place.local_or_deref_local() {
-                                        local
-                                    } else {
-                                        return;
-                                    };
+                                let Some(operand_local) = place.local_or_deref_local() else { return; };
                                 if !interesting_locals.contains(operand_local) {
                                     return;
                                 }
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 8a1fe6e91cb..72c1b3fa6e9 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -947,9 +947,7 @@ fn visit_instance_use<'tcx>(
 /// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we
 /// can just link to the upstream crate and therefore don't need a mono item.
 fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool {
-    let def_id = if let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() {
-        def_id
-    } else {
+    let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() else {
         return true;
     };
 
diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs
index 67597a0d7b4..b8684a09fd7 100644
--- a/compiler/rustc_monomorphize/src/partitioning/mod.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs
@@ -220,18 +220,16 @@ pub fn partition<'tcx>(
         let mut cgus: Vec<_> = post_inlining.codegen_units.iter_mut().collect();
         cgus.sort_by_key(|cgu| cgu.size_estimate());
 
-        let dead_code_cgu = if let Some(cgu) = cgus
-            .into_iter()
-            .rev()
-            .filter(|cgu| cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External))
-            .next()
-        {
-            cgu
-        } else {
-            // If there are no CGUs that have externally linked items,
-            // then we just pick the first CGU as a fallback.
-            &mut post_inlining.codegen_units[0]
-        };
+        let dead_code_cgu =
+            if let Some(cgu) = cgus.into_iter().rev().find(|cgu| {
+                cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External)
+            }) {
+                cgu
+            } else {
+                // If there are no CGUs that have externally linked items,
+                // then we just pick the first CGU as a fallback.
+                &mut post_inlining.codegen_units[0]
+            };
         dead_code_cgu.make_code_coverage_dead_code_cgu();
     }
 
diff --git a/compiler/rustc_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs
index 27540395c07..04baa01832b 100644
--- a/compiler/rustc_monomorphize/src/util.rs
+++ b/compiler/rustc_monomorphize/src/util.rs
@@ -8,13 +8,11 @@ use std::io::prelude::*;
 /// During the same compile all closures dump the information in the same file
 /// "closure_profile_XXXXX.csv", which is created in the directory where the compiler is invoked.
 crate fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: Instance<'tcx>) {
-    let mut file = if let Ok(file) = OpenOptions::new()
+    let Ok(mut file) = OpenOptions::new()
         .create(true)
         .append(true)
         .open(&format!("closure_profile_{}.csv", std::process::id()))
-    {
-        file
-    } else {
+    else {
         eprintln!("Cound't open file for writing closure profile");
         return;
     };
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 1a620968d56..4cdd83c0acd 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -158,9 +158,7 @@ impl<'a> StringReader<'a> {
         Some(match token {
             rustc_lexer::TokenKind::LineComment { doc_style } => {
                 // Skip non-doc comments
-                let doc_style = if let Some(doc_style) = doc_style {
-                    doc_style
-                } else {
+                let Some(doc_style) = doc_style else {
                     self.lint_unicode_text_flow(start);
                     return None;
                 };
@@ -185,9 +183,7 @@ impl<'a> StringReader<'a> {
                 }
 
                 // Skip non-doc comments
-                let doc_style = if let Some(doc_style) = doc_style {
-                    doc_style
-                } else {
+                let Some(doc_style) = doc_style else {
                     self.lint_unicode_text_flow(start);
                     return None;
                 };
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 2b1b2f3fce4..eb0d1a12c77 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -4,6 +4,7 @@
 #![feature(crate_visibility_modifier)]
 #![feature(if_let_guard)]
 #![feature(box_patterns)]
+#![feature(let_else)]
 #![recursion_limit = "256"]
 
 #[macro_use]
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 7b74b137d21..def23005fbe 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -2156,7 +2156,7 @@ impl<'a> Parser<'a> {
                             | PatKind::TupleStruct(qself @ None, path, _)
                             | PatKind::Path(qself @ None, path) => match &first_pat.kind {
                                 PatKind::Ident(_, ident, _) => {
-                                    path.segments.insert(0, PathSegment::from_ident(ident.clone()));
+                                    path.segments.insert(0, PathSegment::from_ident(*ident));
                                     path.span = new_span;
                                     show_sugg = true;
                                     first_pat = pat;
@@ -2183,8 +2183,8 @@ impl<'a> Parser<'a> {
                                             Path {
                                                 span: new_span,
                                                 segments: vec![
-                                                    PathSegment::from_ident(old_ident.clone()),
-                                                    PathSegment::from_ident(ident.clone()),
+                                                    PathSegment::from_ident(*old_ident),
+                                                    PathSegment::from_ident(*ident),
                                                 ],
                                                 tokens: None,
                                             },
@@ -2194,7 +2194,7 @@ impl<'a> Parser<'a> {
                                     }
                                     PatKind::Path(old_qself, old_path) => {
                                         let mut segments = old_path.segments.clone();
-                                        segments.push(PathSegment::from_ident(ident.clone()));
+                                        segments.push(PathSegment::from_ident(*ident));
                                         let path = PatKind::Path(
                                             old_qself.clone(),
                                             Path { span: new_span, segments, tokens: None },
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 62ed104aef3..4b57aa1f24a 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -260,7 +260,7 @@ impl<'a> Parser<'a> {
             let ate_comma = self.eat(&token::Comma);
 
             if self.eat_keyword_noexpect(kw::Where) {
-                let msg = &format!("cannot define duplicate `where` clauses on an item");
+                let msg = "cannot define duplicate `where` clauses on an item";
                 let mut err = self.struct_span_err(self.token.span, msg);
                 err.span_label(lo, "previous `where` clause starts here");
                 err.span_suggestion_verbose(
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 4b85531557c..9a2fb3b86e2 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1362,8 +1362,7 @@ impl<'a> Resolver<'a> {
                     .filter(|(_, module)| {
                         current_module.is_ancestor_of(module) && !ptr::eq(current_module, *module)
                     })
-                    .map(|(_, module)| module.kind.name())
-                    .flatten(),
+                    .flat_map(|(_, module)| module.kind.name()),
             )
             .filter(|c| !c.to_string().is_empty())
             .collect::<Vec<_>>();
@@ -1859,7 +1858,7 @@ crate fn show_candidates(
         let instead = if instead { " instead" } else { "" };
         let mut msg = format!("consider importing {} {}{}", determiner, kind, instead);
 
-        for note in accessible_path_strings.iter().map(|cand| cand.3.as_ref()).flatten() {
+        for note in accessible_path_strings.iter().flat_map(|cand| cand.3.as_ref()) {
             err.note(note);
         }
 
@@ -1942,7 +1941,7 @@ crate fn show_candidates(
                 multi_span.push_span_label(span, format!("`{}`: not accessible", name));
             }
 
-            for note in inaccessible_path_strings.iter().map(|cand| cand.3.as_ref()).flatten() {
+            for note in inaccessible_path_strings.iter().flat_map(|cand| cand.3.as_ref()) {
                 err.note(note);
             }
 
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 5d843b46ee2..129db038f4a 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -704,7 +704,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         ) = &bounded_ty.kind
         {
             // use this to verify that ident is a type param.
-            let partial_res = if let Ok(Some(partial_res)) = self.resolve_qpath_anywhere(
+            let Ok(Some(partial_res)) = self.resolve_qpath_anywhere(
                 bounded_ty.id,
                 None,
                 &Segment::from_path(path),
@@ -712,9 +712,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 span,
                 true,
                 CrateLint::No,
-            ) {
-                partial_res
-            } else {
+            ) else {
                 return false;
             };
             if !(matches!(
@@ -731,7 +729,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
 
         if let ast::TyKind::Path(None, type_param_path) = &ty.peel_refs().kind {
             // Confirm that the `SelfTy` is a type parameter.
-            let partial_res = if let Ok(Some(partial_res)) = self.resolve_qpath_anywhere(
+            let Ok(Some(partial_res)) = self.resolve_qpath_anywhere(
                 bounded_ty.id,
                 None,
                 &Segment::from_path(type_param_path),
@@ -739,9 +737,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 span,
                 true,
                 CrateLint::No,
-            ) {
-                partial_res
-            } else {
+            ) else {
                 return false;
             };
             if !(matches!(
@@ -1167,7 +1163,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                         err.span_suggestion(
                             span,
                             &"use this syntax instead",
-                            format!("{path_str}"),
+                            path_str.to_string(),
                             Applicability::MaybeIncorrect,
                         );
                     }
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 1ce70f5dcf7..3bea95fa1d5 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -729,16 +729,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
         match item.kind {
             hir::ItemKind::Fn(ref sig, ref generics, _) => {
                 self.missing_named_lifetime_spots.push(generics.into());
-                self.visit_early_late(
-                    None,
-                    item.hir_id(),
-                    &sig.decl,
-                    generics,
-                    sig.header.asyncness,
-                    |this| {
-                        intravisit::walk_item(this, item);
-                    },
-                );
+                self.visit_early_late(None, item.hir_id(), &sig.decl, generics, |this| {
+                    intravisit::walk_item(this, item);
+                });
                 self.missing_named_lifetime_spots.pop();
             }
 
@@ -856,16 +849,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
 
     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
         match item.kind {
-            hir::ForeignItemKind::Fn(ref decl, _, ref generics) => self.visit_early_late(
-                None,
-                item.hir_id(),
-                decl,
-                generics,
-                hir::IsAsync::NotAsync,
-                |this| {
+            hir::ForeignItemKind::Fn(ref decl, _, ref generics) => {
+                self.visit_early_late(None, item.hir_id(), decl, generics, |this| {
                     intravisit::walk_foreign_item(this, item);
-                },
-            ),
+                })
+            }
             hir::ForeignItemKind::Static(..) => {
                 intravisit::walk_foreign_item(self, item);
             }
@@ -1142,7 +1130,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                     trait_item.hir_id(),
                     &sig.decl,
                     &trait_item.generics,
-                    sig.header.asyncness,
                     |this| intravisit::walk_trait_item(this, trait_item),
                 );
                 self.missing_named_lifetime_spots.pop();
@@ -1212,7 +1199,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                     impl_item.hir_id(),
                     &sig.decl,
                     &impl_item.generics,
-                    sig.header.asyncness,
                     |this| intravisit::walk_impl_item(this, impl_item),
                 );
                 self.missing_named_lifetime_spots.pop();
@@ -2173,15 +2159,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         hir_id: hir::HirId,
         decl: &'tcx hir::FnDecl<'tcx>,
         generics: &'tcx hir::Generics<'tcx>,
-        asyncness: hir::IsAsync,
         walk: F,
     ) where
         F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>),
     {
-        // Async fns need all their lifetime parameters to be early bound.
-        if asyncness != hir::IsAsync::Async {
-            insert_late_bound_lifetimes(self.map, decl, generics);
-        }
+        insert_late_bound_lifetimes(self.map, decl, generics);
 
         // Find the start of nested early scopes, e.g., in methods.
         let mut next_early_index = 0;
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 68e7cc3dc98..7a0d9a212c9 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -16,7 +16,7 @@ use rustc_target::spec::{LinkerFlavor, SplitDebuginfo, Target, TargetTriple, Tar
 
 use rustc_serialize::json;
 
-use crate::parse::CrateConfig;
+use crate::parse::{CrateCheckConfig, CrateConfig};
 use rustc_feature::UnstableFeatures;
 use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
 use rustc_span::source_map::{FileName, FilePathMapping};
@@ -936,6 +936,7 @@ pub const fn default_lib_output() -> CrateType {
 }
 
 fn default_configuration(sess: &Session) -> CrateConfig {
+    // NOTE: This should be kept in sync with `CrateCheckConfig::fill_well_known` below.
     let end = &sess.target.endian;
     let arch = &sess.target.arch;
     let wordsz = sess.target.pointer_width.to_string();
@@ -1020,6 +1021,91 @@ pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> CrateConfig
     cfg.into_iter().map(|(a, b)| (Symbol::intern(&a), b.map(|b| Symbol::intern(&b)))).collect()
 }
 
+/// The parsed `--check-cfg` options
+pub struct CheckCfg<T = String> {
+    /// Set if `names()` checking is enabled
+    pub names_checked: bool,
+    /// The union of all `names()`
+    pub names_valid: FxHashSet<T>,
+    /// The set of names for which `values()` was used
+    pub values_checked: FxHashSet<T>,
+    /// The set of all (name, value) pairs passed in `values()`
+    pub values_valid: FxHashSet<(T, T)>,
+}
+
+impl<T> Default for CheckCfg<T> {
+    fn default() -> Self {
+        CheckCfg {
+            names_checked: false,
+            names_valid: FxHashSet::default(),
+            values_checked: FxHashSet::default(),
+            values_valid: FxHashSet::default(),
+        }
+    }
+}
+
+impl<T> CheckCfg<T> {
+    fn map_data<O: Eq + Hash>(&self, f: impl Fn(&T) -> O) -> CheckCfg<O> {
+        CheckCfg {
+            names_checked: self.names_checked,
+            names_valid: self.names_valid.iter().map(|a| f(a)).collect(),
+            values_checked: self.values_checked.iter().map(|a| f(a)).collect(),
+            values_valid: self.values_valid.iter().map(|(a, b)| (f(a), f(b))).collect(),
+        }
+    }
+}
+
+/// Converts the crate `--check-cfg` options from `String` to `Symbol`.
+/// `rustc_interface::interface::Config` accepts this in the compiler configuration,
+/// but the symbol interner is not yet set up then, so we must convert it later.
+pub fn to_crate_check_config(cfg: CheckCfg) -> CrateCheckConfig {
+    cfg.map_data(|s| Symbol::intern(s))
+}
+
+impl CrateCheckConfig {
+    /// Fills a `CrateCheckConfig` with well-known configuration names.
+    pub fn fill_well_known(&mut self) {
+        // NOTE: This should be kept in sync with `default_configuration`
+        const WELL_KNOWN_NAMES: &[Symbol] = &[
+            sym::unix,
+            sym::windows,
+            sym::target_os,
+            sym::target_family,
+            sym::target_arch,
+            sym::target_endian,
+            sym::target_pointer_width,
+            sym::target_env,
+            sym::target_abi,
+            sym::target_vendor,
+            sym::target_thread_local,
+            sym::target_has_atomic_load_store,
+            sym::target_has_atomic,
+            sym::target_has_atomic_equal_alignment,
+            sym::panic,
+            sym::sanitize,
+            sym::debug_assertions,
+            sym::proc_macro,
+            sym::test,
+            sym::doc,
+            sym::doctest,
+            sym::feature,
+        ];
+        for &name in WELL_KNOWN_NAMES {
+            self.names_valid.insert(name);
+        }
+    }
+
+    /// Fills a `CrateCheckConfig` with configuration names and values that are actually active.
+    pub fn fill_actual(&mut self, cfg: &CrateConfig) {
+        for &(k, v) in cfg {
+            self.names_valid.insert(k);
+            if let Some(v) = v {
+                self.values_valid.insert((k, v));
+            }
+        }
+    }
+}
+
 pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateConfig {
     // Combine the configuration requested by the session (command line) with
     // some default and generated configuration items.
@@ -1163,6 +1249,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
     vec![
         opt::flag_s("h", "help", "Display this message"),
         opt::multi_s("", "cfg", "Configure the compilation environment", "SPEC"),
+        opt::multi("", "check-cfg", "Provide list of valid cfg options for checking", "SPEC"),
         opt::multi_s(
             "L",
             "",
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index c069144fa9f..0a4bd23937d 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -376,7 +376,7 @@ mod desc {
     pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
     pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
     pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
-    pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `leak`, `memory` or `thread`";
+    pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `leak`, `memory`, `memtag`, or `thread`";
     pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
     pub const parse_cfguard: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
@@ -639,6 +639,7 @@ mod parse {
                     "cfi" => SanitizerSet::CFI,
                     "leak" => SanitizerSet::LEAK,
                     "memory" => SanitizerSet::MEMORY,
+                    "memtag" => SanitizerSet::MEMTAG,
                     "thread" => SanitizerSet::THREAD,
                     "hwaddress" => SanitizerSet::HWADDRESS,
                     _ => return false,
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index d5b520325e5..7113f9b0a2f 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -1,6 +1,7 @@
 //! Contains `ParseSess` which holds state living beyond what one `Parser` might.
 //! It also serves as an input to the parser itself.
 
+use crate::config::CheckCfg;
 use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId};
 use rustc_ast::node_id::NodeId;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -18,6 +19,7 @@ use std::str;
 /// The set of keys (and, optionally, values) that define the compilation
 /// environment of the crate, used to drive conditional compilation.
 pub type CrateConfig = FxHashSet<(Symbol, Option<Symbol>)>;
+pub type CrateCheckConfig = CheckCfg<Symbol>;
 
 /// Collected spans during parsing for places where a certain feature was
 /// used and should be feature gated accordingly in `check_crate`.
@@ -117,6 +119,7 @@ pub struct ParseSess {
     pub span_diagnostic: Handler,
     pub unstable_features: UnstableFeatures,
     pub config: CrateConfig,
+    pub check_config: CrateCheckConfig,
     pub edition: Edition,
     pub missing_fragment_specifiers: Lock<FxHashMap<Span, NodeId>>,
     /// Places where raw identifiers were used. This is used to avoid complaining about idents
@@ -162,6 +165,7 @@ impl ParseSess {
             span_diagnostic: handler,
             unstable_features: UnstableFeatures::from_environment(None),
             config: FxHashSet::default(),
+            check_config: CrateCheckConfig::default(),
             edition: ExpnId::root().expn_data().edition,
             missing_fragment_specifiers: Default::default(),
             raw_identifier_spans: Lock::new(Vec::new()),
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 33140911f91..c746255e95e 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -876,6 +876,7 @@ symbols! {
         mem_zeroed,
         member_constraints,
         memory,
+        memtag,
         message,
         meta,
         metadata_type,
@@ -910,6 +911,7 @@ symbols! {
         naked,
         naked_functions,
         name,
+        names,
         native_link_modifiers,
         native_link_modifiers_as_needed,
         native_link_modifiers_bundle,
@@ -1481,6 +1483,7 @@ symbols! {
         va_list,
         va_start,
         val,
+        values,
         var,
         variant_count,
         vec,
diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs
index da875508676..d184ad4e78a 100644
--- a/compiler/rustc_target/src/asm/aarch64.rs
+++ b/compiler/rustc_target/src/asm/aarch64.rs
@@ -77,6 +77,7 @@ pub fn reserved_x18(
     _arch: InlineAsmArch,
     _target_features: &FxHashSet<Symbol>,
     target: &Target,
+    _is_clobber: bool,
 ) -> Result<(), &'static str> {
     if target.os == "android"
         || target.is_like_fuchsia
diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs
index e3615b43c70..b2d5bb3736a 100644
--- a/compiler/rustc_target/src/asm/arm.rs
+++ b/compiler/rustc_target/src/asm/arm.rs
@@ -66,10 +66,13 @@ fn frame_pointer_is_r7(target_features: &FxHashSet<Symbol>, target: &Target) ->
 }
 
 fn frame_pointer_r11(
-    _arch: InlineAsmArch,
+    arch: InlineAsmArch,
     target_features: &FxHashSet<Symbol>,
     target: &Target,
+    is_clobber: bool,
 ) -> Result<(), &'static str> {
+    not_thumb1(arch, target_features, target, is_clobber)?;
+
     if !frame_pointer_is_r7(target_features, target) {
         Err("the frame pointer (r11) cannot be used as an operand for inline asm")
     } else {
@@ -81,6 +84,7 @@ fn frame_pointer_r7(
     _arch: InlineAsmArch,
     target_features: &FxHashSet<Symbol>,
     target: &Target,
+    _is_clobber: bool,
 ) -> Result<(), &'static str> {
     if frame_pointer_is_r7(target_features, target) {
         Err("the frame pointer (r7) cannot be used as an operand for inline asm")
@@ -93,9 +97,13 @@ fn not_thumb1(
     _arch: InlineAsmArch,
     target_features: &FxHashSet<Symbol>,
     _target: &Target,
+    is_clobber: bool,
 ) -> Result<(), &'static str> {
-    if target_features.contains(&sym::thumb_mode) && !target_features.contains(&sym::thumb2) {
-        Err("high registers (r8+) cannot be used in Thumb-1 code")
+    if !is_clobber
+        && target_features.contains(&sym::thumb_mode)
+        && !target_features.contains(&sym::thumb2)
+    {
+        Err("high registers (r8+) can only be used as clobbers in Thumb-1 code")
     } else {
         Ok(())
     }
@@ -105,8 +113,9 @@ fn reserved_r9(
     arch: InlineAsmArch,
     target_features: &FxHashSet<Symbol>,
     target: &Target,
+    is_clobber: bool,
 ) -> Result<(), &'static str> {
-    not_thumb1(arch, target_features, target)?;
+    not_thumb1(arch, target_features, target, is_clobber)?;
 
     // We detect this using the reserved-r9 feature instead of using the target
     // because the relocation model can be changed with compiler options.
diff --git a/compiler/rustc_target/src/asm/bpf.rs b/compiler/rustc_target/src/asm/bpf.rs
index d94fcb53e24..b4d982f3836 100644
--- a/compiler/rustc_target/src/asm/bpf.rs
+++ b/compiler/rustc_target/src/asm/bpf.rs
@@ -47,6 +47,7 @@ fn only_alu32(
     _arch: InlineAsmArch,
     target_features: &FxHashSet<Symbol>,
     _target: &Target,
+    _is_clobber: bool,
 ) -> Result<(), &'static str> {
     if !target_features.contains(&sym::alu32) {
         Err("register can't be used without the `alu32` target feature")
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index a84410d0f3c..fd95b0338a6 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -83,12 +83,13 @@ macro_rules! def_regs {
                 _arch: super::InlineAsmArch,
                 _target_features: &rustc_data_structures::fx::FxHashSet<Symbol>,
                 _target: &crate::spec::Target,
+                _is_clobber: bool,
                 name: &str,
             ) -> Result<Self, &'static str> {
                 match name {
                     $(
                         $($alias)|* | $reg_name => {
-                            $($filter(_arch, _target_features, _target)?;)?
+                            $($filter(_arch, _target_features, _target, _is_clobber)?;)?
                             Ok(Self::$reg)
                         }
                     )*
@@ -112,7 +113,7 @@ macro_rules! def_regs {
             #[allow(unused_imports)]
             use super::{InlineAsmReg, InlineAsmRegClass};
             $(
-                if $($filter(_arch, _target_features, _target).is_ok() &&)? true {
+                if $($filter(_arch, _target_features, _target, false).is_ok() &&)? true {
                     if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) {
                         set.insert(InlineAsmReg::$arch($arch_reg::$reg));
                     }
@@ -298,6 +299,7 @@ impl InlineAsmReg {
         arch: InlineAsmArch,
         target_features: &FxHashSet<Symbol>,
         target: &Target,
+        is_clobber: bool,
         name: Symbol,
     ) -> Result<Self, &'static str> {
         // FIXME: use direct symbol comparison for register names
@@ -305,47 +307,79 @@ impl InlineAsmReg {
         let name = name.as_str();
         Ok(match arch {
             InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
-                Self::X86(X86InlineAsmReg::parse(arch, target_features, target, name)?)
+                Self::X86(X86InlineAsmReg::parse(arch, target_features, target, is_clobber, name)?)
             }
             InlineAsmArch::Arm => {
-                Self::Arm(ArmInlineAsmReg::parse(arch, target_features, target, name)?)
-            }
-            InlineAsmArch::AArch64 => {
-                Self::AArch64(AArch64InlineAsmReg::parse(arch, target_features, target, name)?)
-            }
-            InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
-                Self::RiscV(RiscVInlineAsmReg::parse(arch, target_features, target, name)?)
-            }
-            InlineAsmArch::Nvptx64 => {
-                Self::Nvptx(NvptxInlineAsmReg::parse(arch, target_features, target, name)?)
-            }
-            InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
-                Self::PowerPC(PowerPCInlineAsmReg::parse(arch, target_features, target, name)?)
-            }
-            InlineAsmArch::Hexagon => {
-                Self::Hexagon(HexagonInlineAsmReg::parse(arch, target_features, target, name)?)
-            }
-            InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
-                Self::Mips(MipsInlineAsmReg::parse(arch, target_features, target, name)?)
-            }
-            InlineAsmArch::S390x => {
-                Self::S390x(S390xInlineAsmReg::parse(arch, target_features, target, name)?)
-            }
-            InlineAsmArch::SpirV => {
-                Self::SpirV(SpirVInlineAsmReg::parse(arch, target_features, target, name)?)
-            }
-            InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
-                Self::Wasm(WasmInlineAsmReg::parse(arch, target_features, target, name)?)
+                Self::Arm(ArmInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?)
             }
+            InlineAsmArch::AArch64 => Self::AArch64(AArch64InlineAsmReg::parse(
+                arch,
+                target_features,
+                target,
+                is_clobber,
+                name,
+            )?),
+            InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => Self::RiscV(
+                RiscVInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?,
+            ),
+            InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmReg::parse(
+                arch,
+                target_features,
+                target,
+                is_clobber,
+                name,
+            )?),
+            InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => Self::PowerPC(
+                PowerPCInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?,
+            ),
+            InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(
+                arch,
+                target_features,
+                target,
+                is_clobber,
+                name,
+            )?),
+            InlineAsmArch::Mips | InlineAsmArch::Mips64 => Self::Mips(MipsInlineAsmReg::parse(
+                arch,
+                target_features,
+                target,
+                is_clobber,
+                name,
+            )?),
+            InlineAsmArch::S390x => Self::S390x(S390xInlineAsmReg::parse(
+                arch,
+                target_features,
+                target,
+                is_clobber,
+                name,
+            )?),
+            InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmReg::parse(
+                arch,
+                target_features,
+                target,
+                is_clobber,
+                name,
+            )?),
+            InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => Self::Wasm(WasmInlineAsmReg::parse(
+                arch,
+                target_features,
+                target,
+                is_clobber,
+                name,
+            )?),
             InlineAsmArch::Bpf => {
-                Self::Bpf(BpfInlineAsmReg::parse(arch, target_features, target, name)?)
+                Self::Bpf(BpfInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?)
             }
             InlineAsmArch::Avr => {
-                Self::Avr(AvrInlineAsmReg::parse(arch, target_features, target, name)?)
-            }
-            InlineAsmArch::Msp430 => {
-                Self::Msp430(Msp430InlineAsmReg::parse(arch, target_features, target, name)?)
+                Self::Avr(AvrInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?)
             }
+            InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmReg::parse(
+                arch,
+                target_features,
+                target,
+                is_clobber,
+                name,
+            )?),
         })
     }
 
@@ -844,7 +878,7 @@ impl InlineAsmClobberAbi {
             },
             InlineAsmArch::AArch64 => match name {
                 "C" | "system" | "efiapi" => {
-                    Ok(if aarch64::reserved_x18(arch, target_features, target).is_err() {
+                    Ok(if aarch64::reserved_x18(arch, target_features, target, true).is_err() {
                         InlineAsmClobberAbi::AArch64NoX18
                     } else {
                         InlineAsmClobberAbi::AArch64
diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs
index 39644d232ba..e145ba8a16e 100644
--- a/compiler/rustc_target/src/asm/riscv.rs
+++ b/compiler/rustc_target/src/asm/riscv.rs
@@ -56,6 +56,7 @@ fn not_e(
     _arch: InlineAsmArch,
     target_features: &FxHashSet<Symbol>,
     _target: &Target,
+    _is_clobber: bool,
 ) -> Result<(), &'static str> {
     if target_features.contains(&sym::e) {
         Err("register can't be used with the `e` target feature")
diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs
index 01d32570f78..a8ee80ec4ea 100644
--- a/compiler/rustc_target/src/asm/x86.rs
+++ b/compiler/rustc_target/src/asm/x86.rs
@@ -141,6 +141,7 @@ fn x86_64_only(
     arch: InlineAsmArch,
     _target_features: &FxHashSet<Symbol>,
     _target: &Target,
+    _is_clobber: bool,
 ) -> Result<(), &'static str> {
     match arch {
         InlineAsmArch::X86 => Err("register is only available on x86_64"),
@@ -153,6 +154,7 @@ fn high_byte(
     arch: InlineAsmArch,
     _target_features: &FxHashSet<Symbol>,
     _target: &Target,
+    _is_clobber: bool,
 ) -> Result<(), &'static str> {
     match arch {
         InlineAsmArch::X86_64 => Err("high byte registers cannot be used as an operand on x86_64"),
@@ -164,6 +166,7 @@ fn rbx_reserved(
     arch: InlineAsmArch,
     _target_features: &FxHashSet<Symbol>,
     _target: &Target,
+    _is_clobber: bool,
 ) -> Result<(), &'static str> {
     match arch {
         InlineAsmArch::X86 => Ok(()),
@@ -178,6 +181,7 @@ fn esi_reserved(
     arch: InlineAsmArch,
     _target_features: &FxHashSet<Symbol>,
     _target: &Target,
+    _is_clobber: bool,
 ) -> Result<(), &'static str> {
     match arch {
         InlineAsmArch::X86 => {
diff --git a/compiler/rustc_target/src/spec/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/aarch64_linux_android.rs
index 1e9abbbe1e7..5692925f63b 100644
--- a/compiler/rustc_target/src/spec/aarch64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/aarch64_linux_android.rs
@@ -14,7 +14,9 @@ pub fn target() -> Target {
             // As documented in https://developer.android.com/ndk/guides/cpu-features.html
             // the neon (ASIMD) and FP must exist on all android aarch64 targets.
             features: "+neon,+fp-armv8".to_string(),
-            supported_sanitizers: SanitizerSet::CFI | SanitizerSet::HWADDRESS,
+            supported_sanitizers: SanitizerSet::CFI
+                | SanitizerSet::HWADDRESS
+                | SanitizerSet::MEMTAG,
             ..super::android_base::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs
index 850381f7fb0..974a5b84d1d 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs
@@ -14,6 +14,7 @@ pub fn target() -> Target {
                 | SanitizerSet::CFI
                 | SanitizerSet::LEAK
                 | SanitizerSet::MEMORY
+                | SanitizerSet::MEMTAG
                 | SanitizerSet::THREAD
                 | SanitizerSet::HWADDRESS,
             ..super::linux_gnu_base::opts()
diff --git a/compiler/rustc_target/src/spec/mips64_openwrt_linux_musl.rs b/compiler/rustc_target/src/spec/mips64_openwrt_linux_musl.rs
index 1199ed44202..5991cd8bfa9 100644
--- a/compiler/rustc_target/src/spec/mips64_openwrt_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/mips64_openwrt_linux_musl.rs
@@ -6,7 +6,7 @@ use crate::spec::{Target, TargetOptions};
 pub fn target() -> Target {
     let mut base = super::linux_musl_base::opts();
     base.cpu = "mips64r2".to_string();
-    base.features = "+mips64r2".to_string();
+    base.features = "+mips64r2,+soft-float".to_string();
     base.max_atomic_width = Some(64);
     base.crt_static_default = false;
 
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index bfafe2d83d7..92678aed5b1 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -606,6 +606,7 @@ bitflags::bitflags! {
         const THREAD  = 1 << 3;
         const HWADDRESS = 1 << 4;
         const CFI     = 1 << 5;
+        const MEMTAG  = 1 << 6;
     }
 }
 
@@ -619,6 +620,7 @@ impl SanitizerSet {
             SanitizerSet::CFI => "cfi",
             SanitizerSet::LEAK => "leak",
             SanitizerSet::MEMORY => "memory",
+            SanitizerSet::MEMTAG => "memtag",
             SanitizerSet::THREAD => "thread",
             SanitizerSet::HWADDRESS => "hwaddress",
             _ => return None,
@@ -652,6 +654,7 @@ impl IntoIterator for SanitizerSet {
             SanitizerSet::CFI,
             SanitizerSet::LEAK,
             SanitizerSet::MEMORY,
+            SanitizerSet::MEMTAG,
             SanitizerSet::THREAD,
             SanitizerSet::HWADDRESS,
         ]
@@ -1883,6 +1886,7 @@ impl Target {
                                 Some("cfi") => SanitizerSet::CFI,
                                 Some("leak") => SanitizerSet::LEAK,
                                 Some("memory") => SanitizerSet::MEMORY,
+                                Some("memtag") => SanitizerSet::MEMTAG,
                                 Some("thread") => SanitizerSet::THREAD,
                                 Some("hwaddress") => SanitizerSet::HWADDRESS,
                                 Some(s) => return Err(format!("unknown sanitizer {}", s)),
diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs
index 603ab0622f0..bf6e6a4fcbb 100644
--- a/compiler/rustc_trait_selection/src/traits/codegen.rs
+++ b/compiler/rustc_trait_selection/src/traits/codegen.rs
@@ -64,6 +64,8 @@ pub fn codegen_fulfill_obligation<'tcx>(
             Err(Unimplemented) => {
                 // This can trigger when we probe for the source of a `'static` lifetime requirement
                 // on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound.
+                // This can also trigger when we have a global bound that is not actually satisfied,
+                // but was included during typeck due to the trivial_bounds feature.
                 infcx.tcx.sess.delay_span_bug(
                     rustc_span::DUMMY_SP,
                     &format!(
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 f22b4e8d072..c3df17c83bb 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1437,8 +1437,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                                     self.tcx
                                         .associated_items(did)
                                         .in_definition_order()
-                                        .filter(|assoc| assoc.ident(self.tcx) == trait_assoc_ident)
-                                        .next()
+                                        .find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident)
                                 },
                             )
                         })
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 40cb9647a35..7df880a7cc0 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1099,9 +1099,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             _ => return false,
         };
 
-        let ret_ty = if let hir::FnRetTy::Return(ret_ty) = sig.decl.output {
-            ret_ty
-        } else {
+        let hir::FnRetTy::Return(ret_ty) = sig.decl.output else {
             return false;
         };
 
@@ -1168,7 +1166,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             };
 
         let sm = self.tcx.sess.source_map();
-        let snippet = if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true) = (
+        let (true, hir::TyKind::TraitObject(..), Ok(snippet), true) = (
             // Verify that we're dealing with a return `dyn Trait`
             ret_ty.span.overlaps(span),
             &ret_ty.kind,
@@ -1176,9 +1174,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             // If any of the return types does not conform to the trait, then we can't
             // suggest `impl Trait` nor trait objects: it is a type mismatch error.
             all_returns_conform_to_trait,
-        ) {
-            snippet
-        } else {
+        ) else {
             return false;
         };
         err.code(error_code!(E0746));
@@ -1932,7 +1928,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             | ObligationCauseCode::AwaitableExpr(_)
             | ObligationCauseCode::ForLoopIterator
             | ObligationCauseCode::QuestionMark
-            | ObligationCauseCode::LetElse => {}
+            | ObligationCauseCode::LetElse
+            | ObligationCauseCode::CheckAssociatedTypeBounds { .. } => {}
             ObligationCauseCode::SliceOrArrayElem => {
                 err.note("slice and array elements must have `Sized` type");
             }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 5f338664c9a..dba24fb2f31 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -19,6 +19,7 @@ use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
 use crate::traits::error_reporting::InferCtxtExt as _;
+use crate::traits::select::ProjectionMatchesProjection;
 use rustc_data_structures::sso::SsoHashSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::ErrorReported;
@@ -959,7 +960,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
                 infcx.inner.borrow_mut().projection_cache().insert_term(cache_key, result.clone());
             }
             obligations.extend(result.obligations);
-            Ok(Some(result.value.into()))
+            Ok(Some(result.value))
         }
         Ok(Projected::NoProgress(projected_ty)) => {
             let result = Normalized { value: projected_ty, obligations: vec![] };
@@ -1075,16 +1076,6 @@ fn project<'cx, 'tcx>(
         return Ok(Projected::Progress(Progress::error(selcx.tcx())));
     }
 
-    // If the obligation contains any inference types or consts in associated
-    // type substs, then we don't assemble any candidates.
-    // This isn't really correct, but otherwise we can end up in a case where
-    // we constrain inference variables by selecting a single predicate, when
-    // we need to stay general. See issue #91762.
-    let (_, predicate_own_substs) = obligation.predicate.trait_ref_and_own_substs(selcx.tcx());
-    if predicate_own_substs.iter().any(|g| g.has_infer_types_or_consts()) {
-        return Err(ProjectionError::TooManyCandidates);
-    }
-
     let mut candidates = ProjectionCandidateSet::None;
 
     // Make sure that the following procedures are kept in order. ParamEnv
@@ -1182,7 +1173,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
         ProjectionCandidate::TraitDef,
         bounds.iter(),
         true,
-    )
+    );
 }
 
 /// In the case of a trait object like
@@ -1247,28 +1238,35 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
         let bound_predicate = predicate.kind();
         if let ty::PredicateKind::Projection(data) = predicate.kind().skip_binder() {
             let data = bound_predicate.rebind(data);
-            let same_def_id = data.projection_def_id() == obligation.predicate.item_def_id;
-
-            let is_match = same_def_id
-                && infcx.probe(|_| {
-                    selcx.match_projection_projections(
-                        obligation,
-                        data,
-                        potentially_unnormalized_candidates,
-                    )
-                });
+            if data.projection_def_id() != obligation.predicate.item_def_id {
+                continue;
+            }
 
-            if is_match {
-                candidate_set.push_candidate(ctor(data));
+            let is_match = infcx.probe(|_| {
+                selcx.match_projection_projections(
+                    obligation,
+                    data,
+                    potentially_unnormalized_candidates,
+                )
+            });
 
-                if potentially_unnormalized_candidates
-                    && !obligation.predicate.has_infer_types_or_consts()
-                {
-                    // HACK: Pick the first trait def candidate for a fully
-                    // inferred predicate. This is to allow duplicates that
-                    // differ only in normalization.
-                    return;
+            match is_match {
+                ProjectionMatchesProjection::Yes => {
+                    candidate_set.push_candidate(ctor(data));
+
+                    if potentially_unnormalized_candidates
+                        && !obligation.predicate.has_infer_types_or_consts()
+                    {
+                        // HACK: Pick the first trait def candidate for a fully
+                        // inferred predicate. This is to allow duplicates that
+                        // differ only in normalization.
+                        return;
+                    }
+                }
+                ProjectionMatchesProjection::Ambiguous => {
+                    candidate_set.mark_ambiguous();
                 }
+                ProjectionMatchesProjection::No => {}
             }
         }
     }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 64af875dd22..3b69700530b 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1494,12 +1494,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         })
     }
 
+    /// Return `Yes` if the obligation's predicate type applies to the env_predicate, and
+    /// `No` if it does not. Return `Ambiguous` in the case that the projection type is a GAT,
+    /// and applying this env_predicate constrains any of the obligation's GAT substitutions.
+    ///
+    /// This behavior is a somewhat of a hack to prevent overconstraining inference variables
+    /// in cases like #91762.
     pub(super) fn match_projection_projections(
         &mut self,
         obligation: &ProjectionTyObligation<'tcx>,
         env_predicate: PolyProjectionPredicate<'tcx>,
         potentially_unnormalized_candidates: bool,
-    ) -> bool {
+    ) -> ProjectionMatchesProjection {
         let mut nested_obligations = Vec::new();
         let (infer_predicate, _) = self.infcx.replace_bound_vars_with_fresh_vars(
             obligation.cause.span,
@@ -1521,7 +1527,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             infer_predicate.projection_ty
         };
 
-        self.infcx
+        let is_match = self
+            .infcx
             .at(&obligation.cause, obligation.param_env)
             .sup(obligation.predicate, infer_projection)
             .map_or(false, |InferOk { obligations, value: () }| {
@@ -1530,7 +1537,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     nested_obligations.into_iter().chain(obligations),
                 )
                 .map_or(false, |res| res.may_apply())
-            })
+            });
+
+        if is_match {
+            let generics = self.tcx().generics_of(obligation.predicate.item_def_id);
+            // FIXME(generic-associated-types): Addresses aggressive inference in #92917.
+            // If this type is a GAT, and of the GAT substs resolve to something new,
+            // that means that we must have newly inferred something about the GAT.
+            // We should give up in that case.
+            if !generics.params.is_empty()
+                && obligation.predicate.substs[generics.parent_count..]
+                    .iter()
+                    .any(|&p| p.has_infer_types_or_consts() && self.infcx.shallow_resolve(p) != p)
+            {
+                ProjectionMatchesProjection::Ambiguous
+            } else {
+                ProjectionMatchesProjection::Yes
+            }
+        } else {
+            ProjectionMatchesProjection::No
+        }
     }
 
     ///////////////////////////////////////////////////////////////////////////
@@ -2709,3 +2735,9 @@ impl<'o, 'tcx> fmt::Debug for TraitObligationStack<'o, 'tcx> {
         write!(f, "TraitObligationStack({:?})", self.obligation)
     }
 }
+
+pub enum ProjectionMatchesProjection {
+    Yes,
+    Ambiguous,
+    No,
+}
diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs
index a49d6e24f26..7e9abe3a250 100644
--- a/compiler/rustc_typeck/src/astconv/errors.rs
+++ b/compiler/rustc_typeck/src/astconv/errors.rs
@@ -211,8 +211,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         );
 
         let all_candidate_names: Vec<_> = all_candidates()
-            .map(|r| self.tcx().associated_items(r.def_id()).in_definition_order())
-            .flatten()
+            .flat_map(|r| self.tcx().associated_items(r.def_id()).in_definition_order())
             .filter_map(
                 |item| if item.kind == ty::AssocKind::Type { Some(item.name) } else { None },
             )
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 845f03183c3..96f92049983 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -2409,11 +2409,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 let def_id = item_id.def_id.to_def_id();
 
                 match opaque_ty.kind {
-                    hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
-                        let replace_parent_lifetimes =
-                            matches!(origin, hir::OpaqueTyOrigin::FnReturn(..));
-                        self.impl_trait_ty_to_ty(def_id, lifetimes, replace_parent_lifetimes)
-                    }
+                    hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => self
+                        .impl_trait_ty_to_ty(
+                            def_id,
+                            lifetimes,
+                            matches!(
+                                origin,
+                                hir::OpaqueTyOrigin::FnReturn(..)
+                                    | hir::OpaqueTyOrigin::AsyncFn(..)
+                            ),
+                        ),
                     ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
                 }
             }
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 6dbda1005dd..1650a62f79f 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -392,7 +392,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
                     "when the type does not implement `Copy`, \
                     wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped",
                     vec![
-                        (ty_span.shrink_to_lo(), format!("std::mem::ManuallyDrop<")),
+                        (ty_span.shrink_to_lo(), "std::mem::ManuallyDrop<".into()),
                         (ty_span.shrink_to_hi(), ">".into()),
                     ],
                     Applicability::MaybeIncorrect,
@@ -545,8 +545,10 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
         }
     }
 
-    if let ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(..), .. }) =
-        item.kind
+    if let ItemKind::OpaqueTy(hir::OpaqueTy {
+        origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
+        ..
+    }) = item.kind
     {
         let mut visitor = ProhibitOpaqueVisitor {
             opaque_identity_ty: tcx.mk_opaque(
@@ -568,13 +570,20 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
 
         if let Some(ty) = prohibit_opaque.break_value() {
             visitor.visit_item(&item);
+            let is_async = match item.kind {
+                ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
+                    matches!(origin, hir::OpaqueTyOrigin::AsyncFn(..))
+                }
+                _ => unreachable!(),
+            };
 
             let mut err = struct_span_err!(
                 tcx.sess,
                 span,
                 E0760,
-                "`impl Trait` return type cannot contain a projection or `Self` that references lifetimes from \
+                "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
                  a parent scope",
+                if is_async { "async fn" } else { "impl Trait" },
             );
 
             for (span, name) in visitor.selftys {
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index 457e9cf1ea5..38449c2a76a 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -1378,7 +1378,14 @@ pub fn check_type_bounds<'tcx>(
         let mut selcx = traits::SelectionContext::new(&infcx);
 
         let impl_ty_hir_id = tcx.hir().local_def_id_to_hir_id(impl_ty.def_id.expect_local());
-        let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_hir_id);
+        let normalize_cause = ObligationCause::new(
+            impl_ty_span,
+            impl_ty_hir_id,
+            ObligationCauseCode::CheckAssociatedTypeBounds {
+                impl_item_def_id: impl_ty.def_id,
+                trait_item_def_id: trait_ty.def_id,
+            },
+        );
         let mk_cause = |span: Span| {
             let code = if span.is_dummy() {
                 traits::MiscObligation
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index d0e96e7538c..e7eadb760c7 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -340,7 +340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
                 Some(ident) => format!("{}: ", ident),
-                None => format!(""),
+                None => String::new(),
             };
 
             match &compatible_variants[..] {
@@ -683,7 +683,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                         let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
                             Some(ident) => format!("{}: ", ident),
-                            None => format!(""),
+                            None => String::new(),
                         };
 
                         if let Some(hir::Node::Expr(hir::Expr {
@@ -875,7 +875,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             };
                             let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
                                 Some(ident) => format!("{}: ", ident),
-                                None => format!(""),
+                                None => String::new(),
                             };
                             let (span, suggestion) = if self.is_else_if_block(expr) {
                                 // Don't suggest nonsense like `else *if`
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index b5f13703edf..4869d193d80 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -1318,10 +1318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
     ) -> Ty<'tcx> {
         // Find the relevant variant
-        let (variant, adt_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, expr.hir_id)
-        {
-            variant_ty
-        } else {
+        let Some((variant, adt_ty)) = self.check_struct_path(qpath, expr.hir_id) else {
             self.check_struct_fields_on_error(fields, base_expr);
             return self.tcx.ty_error();
         };
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index 86cf850d723..f9c482713f1 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -8,8 +8,12 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind};
 use rustc_hir::lang_items::LangItem;
-use rustc_hir::{Expr, ExprKind, ItemKind, Node, Path, QPath, Stmt, StmtKind, TyKind};
+use rustc_hir::{
+    Expr, ExprKind, GenericBound, ItemKind, Node, Path, QPath, Stmt, StmtKind, TyKind,
+    WherePredicate,
+};
 use rustc_infer::infer::{self, TyCtxtInferExt};
+
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Binder, Ty};
 use rustc_span::symbol::{kw, sym};
@@ -559,6 +563,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let ty = self.tcx.erase_late_bound_regions(ty);
                 if self.can_coerce(expected, ty) {
                     err.span_label(sp, format!("expected `{}` because of return type", expected));
+                    self.try_suggest_return_impl_trait(err, expected, ty, fn_id);
                     return true;
                 }
                 false
@@ -566,6 +571,115 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    /// check whether the return type is a generic type with a trait bound
+    /// only suggest this if the generic param is not present in the arguments
+    /// if this is true, hint them towards changing the return type to `impl Trait`
+    /// ```
+    /// fn cant_name_it<T: Fn() -> u32>() -> T {
+    ///     || 3
+    /// }
+    /// ```
+    fn try_suggest_return_impl_trait(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        expected: Ty<'tcx>,
+        found: Ty<'tcx>,
+        fn_id: hir::HirId,
+    ) {
+        // Only apply the suggestion if:
+        //  - the return type is a generic parameter
+        //  - the generic param is not used as a fn param
+        //  - the generic param has at least one bound
+        //  - the generic param doesn't appear in any other bounds where it's not the Self type
+        // Suggest:
+        //  - Changing the return type to be `impl <all bounds>`
+
+        debug!("try_suggest_return_impl_trait, expected = {:?}, found = {:?}", expected, found);
+
+        let ty::Param(expected_ty_as_param) = expected.kind() else { return };
+
+        let fn_node = self.tcx.hir().find(fn_id);
+
+        let Some(hir::Node::Item(hir::Item {
+            kind:
+                hir::ItemKind::Fn(
+                    hir::FnSig { decl: hir::FnDecl { inputs: fn_parameters, output: fn_return, .. }, .. },
+                    hir::Generics { params, where_clause, .. },
+                    _body_id,
+                ),
+            ..
+        })) = fn_node else { return };
+
+        let Some(expected_generic_param) = params.get(expected_ty_as_param.index as usize) else { return };
+
+        // get all where BoundPredicates here, because they are used in to cases below
+        let where_predicates = where_clause
+            .predicates
+            .iter()
+            .filter_map(|p| match p {
+                WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
+                    bounds,
+                    bounded_ty,
+                    ..
+                }) => {
+                    // FIXME: Maybe these calls to `ast_ty_to_ty` can be removed (and the ones below)
+                    let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, bounded_ty);
+                    Some((ty, bounds))
+                }
+                _ => None,
+            })
+            .map(|(ty, bounds)| match ty.kind() {
+                ty::Param(param_ty) if param_ty == expected_ty_as_param => Ok(Some(bounds)),
+                // check whether there is any predicate that contains our `T`, like `Option<T>: Send`
+                _ => match ty.contains(expected) {
+                    true => Err(()),
+                    false => Ok(None),
+                },
+            })
+            .collect::<Result<Vec<_>, _>>();
+
+        let Ok(where_predicates) =  where_predicates else { return };
+
+        // now get all predicates in the same types as the where bounds, so we can chain them
+        let predicates_from_where =
+            where_predicates.iter().flatten().map(|bounds| bounds.iter()).flatten();
+
+        // extract all bounds from the source code using their spans
+        let all_matching_bounds_strs = expected_generic_param
+            .bounds
+            .iter()
+            .chain(predicates_from_where)
+            .filter_map(|bound| match bound {
+                GenericBound::Trait(_, _) => {
+                    self.tcx.sess.source_map().span_to_snippet(bound.span()).ok()
+                }
+                _ => None,
+            })
+            .collect::<Vec<String>>();
+
+        if all_matching_bounds_strs.len() == 0 {
+            return;
+        }
+
+        let all_bounds_str = all_matching_bounds_strs.join(" + ");
+
+        let ty_param_used_in_fn_params = fn_parameters.iter().any(|param| {
+                let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, param);
+                matches!(ty.kind(), ty::Param(fn_param_ty_param) if expected_ty_as_param == fn_param_ty_param)
+            });
+
+        if ty_param_used_in_fn_params {
+            return;
+        }
+
+        err.span_suggestion(
+            fn_return.span(),
+            "consider using an impl return type",
+            format!("impl {}", all_bounds_str),
+            Applicability::MaybeIncorrect,
+        );
+    }
+
     pub(in super::super) fn suggest_missing_break_or_return_expr(
         &self,
         err: &mut DiagnosticBuilder<'_>,
diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs
index c4e7d6a199e..972dd622d6e 100644
--- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs
@@ -246,7 +246,7 @@ impl DropRangesBuilder {
 
     fn add_control_edge(&mut self, from: PostOrderId, to: PostOrderId) {
         trace!("adding control edge from {:?} to {:?}", from, to);
-        self.node_mut(from.into()).successors.push(to.into());
+        self.node_mut(from).successors.push(to);
     }
 }
 
diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
index e2a4d9c1b3a..cfed784ea72 100644
--- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
@@ -527,7 +527,7 @@ impl DropRangesBuilder {
 
     fn drop_at(&mut self, value: TrackedValue, location: PostOrderId) {
         let value = self.tracked_value_index(value);
-        self.node_mut(location.into()).drops.push(value);
+        self.node_mut(location).drops.push(value);
     }
 
     fn reinit_at(&mut self, value: TrackedValue, location: PostOrderId) {
@@ -537,7 +537,7 @@ impl DropRangesBuilder {
             // ignore this.
             None => return,
         };
-        self.node_mut(location.into()).reinits.push(value);
+        self.node_mut(location).reinits.push(value);
     }
 
     /// Looks up PostOrderId for any control edges added by HirId and adds a proper edge for them.
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 88dc90dd3e7..18f54eb2246 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -2157,7 +2157,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
                     generics
                 }
                 ItemKind::OpaqueTy(OpaqueTy {
-                    origin: hir::OpaqueTyOrigin::FnReturn(..), ..
+                    origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
+                    ..
                 }) => {
                     // return-position impl trait
                     //
@@ -2177,7 +2178,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
                 }
                 ItemKind::OpaqueTy(OpaqueTy {
                     ref generics,
-                    origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::TyAlias,
+                    origin: hir::OpaqueTyOrigin::TyAlias,
                     ..
                 }) => {
                     // type-alias impl trait
@@ -3008,6 +3009,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
                         codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI;
                     } else if item.has_name(sym::memory) {
                         codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY;
+                    } else if item.has_name(sym::memtag) {
+                        codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG;
                     } else if item.has_name(sym::thread) {
                         codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD;
                     } else if item.has_name(sym::hwaddress) {
@@ -3015,7 +3018,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
                     } else {
                         tcx.sess
                             .struct_span_err(item.span(), "invalid argument for `no_sanitize`")
-                            .note("expected one of: `address`, `hwaddress`, `memory` or `thread`")
+                            .note("expected one of: `address`, `cfi`, `hwaddress`, `memory`, `memtag`, or `thread`")
                             .emit();
                     }
                 }
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 90555b213c1..39da7c82c4e 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -1,7 +1,6 @@
 use rustc_errors::{Applicability, ErrorReported, StashKey};
 use rustc_hir as hir;
-use rustc_hir::def::CtorOf;
-use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def::Res;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit;
 use rustc_hir::intravisit::Visitor;
@@ -9,7 +8,7 @@ use rustc_hir::{HirId, Node};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::util::IntTypeExt;
-use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable, TypeFolder};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder};
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, DUMMY_SP};
 
@@ -198,38 +197,9 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
             // Try to use the segment resolution if it is valid, otherwise we
             // default to the path resolution.
             let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
-            let generics = match res {
-                Res::Def(DefKind::Ctor(CtorOf::Variant, _), def_id) => tcx
-                    .generics_of(tcx.parent(def_id).and_then(|def_id| tcx.parent(def_id)).unwrap()),
-                Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Struct, _), def_id) => {
-                    tcx.generics_of(tcx.parent(def_id).unwrap())
-                }
-                // Other `DefKind`s don't have generics and would ICE when calling
-                // `generics_of`.
-                Res::Def(
-                    DefKind::Struct
-                    | DefKind::Union
-                    | DefKind::Enum
-                    | DefKind::Trait
-                    | DefKind::OpaqueTy
-                    | DefKind::TyAlias
-                    | DefKind::ForeignTy
-                    | DefKind::TraitAlias
-                    | DefKind::AssocTy
-                    | DefKind::Fn
-                    | DefKind::AssocFn
-                    | DefKind::AssocConst
-                    | DefKind::Impl,
-                    def_id,
-                ) => tcx.generics_of(def_id),
-                Res::Err => {
-                    tcx.sess.delay_span_bug(tcx.def_span(def_id), "anon const with Res::Err");
-                    return None;
-                }
-                _ => {
-                    // If the user tries to specify generics on a type that does not take them,
-                    // e.g. `usize<T>`, we may hit this branch, in which case we treat it as if
-                    // no arguments have been passed. An error should already have been emitted.
+            let generics = match tcx.res_generics_def_id(res) {
+                Some(def_id) => tcx.generics_of(def_id),
+                None => {
                     tcx.sess.delay_span_bug(
                         tcx.def_span(def_id),
                         &format!("unexpected anon const res {:?} in path: {:?}", res, path),
@@ -527,7 +497,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                       // FIXME(associated_const_equality): add a useful error message here.
                       tcx.ty_error_with_message(
                         DUMMY_SP,
-                        &format!("Could not find associated const on trait"),
+                        "Could not find associated const on trait",
                     )
                   }
                 }
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index aa7344ba405..68bf59a01b3 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -133,6 +133,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use core::any::Any;
+use core::async_iter::AsyncIterator;
 use core::borrow;
 use core::cmp::Ordering;
 use core::convert::{From, TryFrom};
@@ -149,7 +150,6 @@ use core::ops::{
 };
 use core::pin::Pin;
 use core::ptr::{self, Unique};
-use core::stream::Stream;
 use core::task::{Context, Poll};
 
 #[cfg(not(no_global_oom_handling))]
@@ -1992,8 +1992,8 @@ where
     }
 }
 
-#[unstable(feature = "async_stream", issue = "79024")]
-impl<S: ?Sized + Stream + Unpin> Stream for Box<S> {
+#[unstable(feature = "async_iterator", issue = "79024")]
+impl<S: ?Sized + AsyncIterator + Unpin> AsyncIterator for Box<S> {
     type Item = S::Item;
 
     fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs
index 56a47001811..e18cd8cd464 100644
--- a/library/alloc/src/collections/binary_heap.rs
+++ b/library/alloc/src/collections/binary_heap.rs
@@ -746,9 +746,12 @@ impl<T: Ord> BinaryHeap<T> {
         self.rebuild_tail(start);
     }
 
-    /// Returns an iterator which retrieves elements in heap order.
-    /// The retrieved elements are removed from the original heap.
-    /// The remaining elements will be removed on drop in heap order.
+    /// Clears the binary heap, returning an iterator over the removed elements
+    /// in heap order. If the iterator is dropped before being fully consumed,
+    /// it drops the remaining elements in heap order.
+    ///
+    /// The returned iterator keeps a mutable borrow on the heap to optimize
+    /// its implementation.
     ///
     /// Note:
     /// * `.drain_sorted()` is *O*(*n* \* log(*n*)); much slower than `.drain()`.
@@ -1158,9 +1161,12 @@ impl<T> BinaryHeap<T> {
         self.len() == 0
     }
 
-    /// Clears the binary heap, returning an iterator over the removed elements.
+    /// Clears the binary heap, returning an iterator over the removed elements
+    /// in arbitrary order. If the iterator is dropped before being fully
+    /// consumed, it drops the remaining elements in arbitrary order.
     ///
-    /// The elements are removed in arbitrary order.
+    /// The returned iterator keeps a mutable borrow on the heap to optimize
+    /// its implementation.
     ///
     /// # Examples
     ///
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index 763175fc045..7139a0fb94d 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -1215,21 +1215,25 @@ impl<T, A: Allocator> VecDeque<T, A> {
         unsafe { IterMut::new(ring, tail, head, PhantomData) }
     }
 
-    /// Creates a draining iterator that removes the specified range in the
-    /// deque and yields the removed items.
+    /// Removes the specified range from the deque in bulk, returning all
+    /// removed elements as an iterator. If the iterator is dropped before
+    /// being fully consumed, it drops the remaining removed elements.
     ///
-    /// Note 1: The element range is removed even if the iterator is not
-    /// consumed until the end.
+    /// The returned iterator keeps a mutable borrow on the queue to optimize
+    /// its implementation.
     ///
-    /// Note 2: It is unspecified how many elements are removed from the deque,
-    /// if the `Drain` value is not dropped, but the borrow it holds expires
-    /// (e.g., due to `mem::forget`).
     ///
     /// # Panics
     ///
     /// Panics if the starting point is greater than the end point or if
     /// the end point is greater than the length of the deque.
     ///
+    /// # Leaking
+    ///
+    /// If the returned iterator goes out of scope without being dropped (due to
+    /// [`mem::forget`], for example), the deque may have lost and leaked
+    /// elements arbitrarily, including elements outside the range.
+    ///
     /// # Examples
     ///
     /// ```
@@ -1240,7 +1244,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
     /// assert_eq!(drained, [3]);
     /// assert_eq!(deque, [1, 2]);
     ///
-    /// // A full range clears all contents
+    /// // A full range clears all contents, like `clear()` does
     /// deque.drain(..);
     /// assert!(deque.is_empty());
     /// ```
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index ce75859f963..6da32df57ef 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -91,7 +91,7 @@
 #![feature(array_chunks)]
 #![feature(array_methods)]
 #![feature(array_windows)]
-#![feature(async_stream)]
+#![feature(async_iterator)]
 #![feature(coerce_unsized)]
 #![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
 #![feature(const_box)]
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 7c0faf0659a..716bb4983a6 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -1628,17 +1628,24 @@ impl String {
         self.vec.clear()
     }
 
-    /// Creates a draining iterator that removes the specified range in the `String`
-    /// and yields the removed `chars`.
+    /// Removes the specified range from the string in bulk, returning all
+    /// removed characters as an iterator.
     ///
-    /// Note: The element range is removed even if the iterator is not
-    /// consumed until the end.
+    /// The returned iterator keeps a mutable borrow on the string to optimize
+    /// its implementation.
     ///
     /// # Panics
     ///
     /// Panics if the starting point or end point do not lie on a [`char`]
     /// boundary, or if they're out of bounds.
     ///
+    /// # Leaking
+    ///
+    /// If the returned iterator goes out of scope without being dropped (due to
+    /// [`core::mem::forget`], for example), the string may still contain a copy
+    /// of any drained characters, or may have lost characters arbitrarily,
+    /// including characters outside the range.
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -1652,7 +1659,7 @@ impl String {
     /// assert_eq!(t, "α is alpha, ");
     /// assert_eq!(s, "β is beta");
     ///
-    /// // A full range clears the string
+    /// // A full range clears the string, like `clear()` does
     /// s.drain(..);
     /// assert_eq!(s, "");
     /// ```
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 3dc3eee4133..c29aa0fec5b 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1799,19 +1799,24 @@ impl<T, A: Allocator> Vec<T, A> {
         self.len += count;
     }
 
-    /// Creates a draining iterator that removes the specified range in the vector
-    /// and yields the removed items.
+    /// Removes the specified range from the vector in bulk, returning all
+    /// removed elements as an iterator. If the iterator is dropped before
+    /// being fully consumed, it drops the remaining removed elements.
     ///
-    /// When the iterator **is** dropped, all elements in the range are removed
-    /// from the vector, even if the iterator was not fully consumed. If the
-    /// iterator **is not** dropped (with [`mem::forget`] for example), it is
-    /// unspecified how many elements are removed.
+    /// The returned iterator keeps a mutable borrow on the vector to optimize
+    /// its implementation.
     ///
     /// # Panics
     ///
     /// Panics if the starting point is greater than the end point or if
     /// the end point is greater than the length of the vector.
     ///
+    /// # Leaking
+    ///
+    /// If the returned iterator goes out of scope without being dropped (due to
+    /// [`mem::forget`], for example), the vector may have lost and leaked
+    /// elements arbitrarily, including elements outside the range.
+    ///
     /// # Examples
     ///
     /// ```
@@ -1820,7 +1825,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// assert_eq!(v, &[1]);
     /// assert_eq!(u, &[2, 3]);
     ///
-    /// // A full range clears the vector
+    /// // A full range clears the vector, like `clear()` does
     /// v.drain(..);
     /// assert_eq!(v, &[]);
     /// ```
diff --git a/library/core/src/stream/stream.rs b/library/core/src/async_iter/async_iter.rs
index 2cfddf9ad01..f29de31171a 100644
--- a/library/core/src/stream/stream.rs
+++ b/library/core/src/async_iter/async_iter.rs
@@ -4,50 +4,50 @@ use crate::task::{Context, Poll};
 
 /// An interface for dealing with asynchronous iterators.
 ///
-/// This is the main stream trait. For more about the concept of streams
+/// This is the main async iterator trait. For more about the concept of async iterators
 /// generally, please see the [module-level documentation]. In particular, you
-/// may want to know how to [implement `Stream`][impl].
+/// may want to know how to [implement `AsyncIterator`][impl].
 ///
 /// [module-level documentation]: index.html
-/// [impl]: index.html#implementing-stream
-#[unstable(feature = "async_stream", issue = "79024")]
-#[must_use = "streams do nothing unless polled"]
-pub trait Stream {
-    /// The type of items yielded by the stream.
+/// [impl]: index.html#implementing-async-iterator
+#[unstable(feature = "async_iterator", issue = "79024")]
+#[must_use = "async iterators do nothing unless polled"]
+pub trait AsyncIterator {
+    /// The type of items yielded by the async iterator.
     type Item;
 
-    /// Attempt to pull out the next value of this stream, registering the
+    /// Attempt to pull out the next value of this async iterator, registering the
     /// current task for wakeup if the value is not yet available, and returning
-    /// `None` if the stream is exhausted.
+    /// `None` if the async iterator is exhausted.
     ///
     /// # Return value
     ///
     /// There are several possible return values, each indicating a distinct
-    /// stream state:
+    /// async iterator state:
     ///
-    /// - `Poll::Pending` means that this stream's next value is not ready
+    /// - `Poll::Pending` means that this async iterator's next value is not ready
     /// yet. Implementations will ensure that the current task will be notified
     /// when the next value may be ready.
     ///
-    /// - `Poll::Ready(Some(val))` means that the stream has successfully
+    /// - `Poll::Ready(Some(val))` means that the async iterator has successfully
     /// produced a value, `val`, and may produce further values on subsequent
     /// `poll_next` calls.
     ///
-    /// - `Poll::Ready(None)` means that the stream has terminated, and
+    /// - `Poll::Ready(None)` means that the async iterator has terminated, and
     /// `poll_next` should not be invoked again.
     ///
     /// # Panics
     ///
-    /// Once a stream has finished (returned `Ready(None)` from `poll_next`), calling its
+    /// Once an async iterator has finished (returned `Ready(None)` from `poll_next`), calling its
     /// `poll_next` method again may panic, block forever, or cause other kinds of
-    /// problems; the `Stream` trait places no requirements on the effects of
+    /// problems; the `AsyncIterator` trait places no requirements on the effects of
     /// such a call. However, as the `poll_next` method is not marked `unsafe`,
     /// Rust's usual rules apply: calls must never cause undefined behavior
     /// (memory corruption, incorrect use of `unsafe` functions, or the like),
-    /// regardless of the stream's state.
+    /// regardless of the async iterator's state.
     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
 
-    /// Returns the bounds on the remaining length of the stream.
+    /// Returns the bounds on the remaining length of the async iterator.
     ///
     /// Specifically, `size_hint()` returns a tuple where the first element
     /// is the lower bound, and the second element is the upper bound.
@@ -58,12 +58,12 @@ pub trait Stream {
     ///
     /// # Implementation notes
     ///
-    /// It is not enforced that a stream implementation yields the declared
-    /// number of elements. A buggy stream may yield less than the lower bound
+    /// It is not enforced that an async iterator implementation yields the declared
+    /// number of elements. A buggy async iterator may yield less than the lower bound
     /// or more than the upper bound of elements.
     ///
     /// `size_hint()` is primarily intended to be used for optimizations such as
-    /// reserving space for the elements of the stream, but must not be
+    /// reserving space for the elements of the async iterator, but must not be
     /// trusted to e.g., omit bounds checks in unsafe code. An incorrect
     /// implementation of `size_hint()` should not lead to memory safety
     /// violations.
@@ -72,15 +72,15 @@ pub trait Stream {
     /// because otherwise it would be a violation of the trait's protocol.
     ///
     /// The default implementation returns <code>(0, [None])</code> which is correct for any
-    /// stream.
+    /// async iterator.
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         (0, None)
     }
 }
 
-#[unstable(feature = "async_stream", issue = "79024")]
-impl<S: ?Sized + Stream + Unpin> Stream for &mut S {
+#[unstable(feature = "async_iterator", issue = "79024")]
+impl<S: ?Sized + AsyncIterator + Unpin> AsyncIterator for &mut S {
     type Item = S::Item;
 
     fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
@@ -92,16 +92,16 @@ impl<S: ?Sized + Stream + Unpin> Stream for &mut S {
     }
 }
 
-#[unstable(feature = "async_stream", issue = "79024")]
-impl<P> Stream for Pin<P>
+#[unstable(feature = "async_iterator", issue = "79024")]
+impl<P> AsyncIterator for Pin<P>
 where
     P: DerefMut,
-    P::Target: Stream,
+    P::Target: AsyncIterator,
 {
-    type Item = <P::Target as Stream>::Item;
+    type Item = <P::Target as AsyncIterator>::Item;
 
     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
-        <P::Target as Stream>::poll_next(self.as_deref_mut(), cx)
+        <P::Target as AsyncIterator>::poll_next(self.as_deref_mut(), cx)
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
diff --git a/library/core/src/stream/from_iter.rs b/library/core/src/async_iter/from_iter.rs
index eb9a0fd2842..3180187afc8 100644
--- a/library/core/src/stream/from_iter.rs
+++ b/library/core/src/async_iter/from_iter.rs
@@ -1,31 +1,31 @@
 use crate::pin::Pin;
 
-use crate::stream::Stream;
+use crate::async_iter::AsyncIterator;
 use crate::task::{Context, Poll};
 
-/// A stream that was created from iterator.
+/// An async iterator that was created from iterator.
 ///
-/// This stream is created by the [`from_iter`] function.
+/// This async iterator is created by the [`from_iter`] function.
 /// See it documentation for more.
 ///
 /// [`from_iter`]: fn.from_iter.html
-#[unstable(feature = "stream_from_iter", issue = "81798")]
+#[unstable(feature = "async_iter_from_iter", issue = "81798")]
 #[derive(Clone, Debug)]
 pub struct FromIter<I> {
     iter: I,
 }
 
-#[unstable(feature = "stream_from_iter", issue = "81798")]
+#[unstable(feature = "async_iter_from_iter", issue = "81798")]
 impl<I> Unpin for FromIter<I> {}
 
-/// Converts an iterator into a stream.
-#[unstable(feature = "stream_from_iter", issue = "81798")]
+/// Converts an iterator into an async iterator.
+#[unstable(feature = "async_iter_from_iter", issue = "81798")]
 pub fn from_iter<I: IntoIterator>(iter: I) -> FromIter<I::IntoIter> {
     FromIter { iter: iter.into_iter() }
 }
 
-#[unstable(feature = "stream_from_iter", issue = "81798")]
-impl<I: Iterator> Stream for FromIter<I> {
+#[unstable(feature = "async_iter_from_iter", issue = "81798")]
+impl<I: Iterator> AsyncIterator for FromIter<I> {
     type Item = I::Item;
 
     fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
diff --git a/library/core/src/stream/mod.rs b/library/core/src/async_iter/mod.rs
index b59a46d5f3a..0c6f637711b 100644
--- a/library/core/src/stream/mod.rs
+++ b/library/core/src/async_iter/mod.rs
@@ -1,10 +1,9 @@
 //! Composable asynchronous iteration.
 //!
-//! If futures are asynchronous values, then streams are asynchronous
-//! iterators. If you've found yourself with an asynchronous collection of some kind,
+//! If you've found yourself with an asynchronous collection of some kind,
 //! and needed to perform an operation on the elements of said collection,
-//! you'll quickly run into 'streams'. Streams are heavily used in idiomatic
-//! asynchronous Rust code, so it's worth becoming familiar with them.
+//! you'll quickly run into 'async iterators'. Async Iterators are heavily used in
+//! idiomatic asynchronous Rust code, so it's worth becoming familiar with them.
 //!
 //! Before explaining more, let's talk about how this module is structured:
 //!
@@ -12,71 +11,71 @@
 //!
 //! This module is largely organized by type:
 //!
-//! * [Traits] are the core portion: these traits define what kind of streams
+//! * [Traits] are the core portion: these traits define what kind of async iterators
 //!   exist and what you can do with them. The methods of these traits are worth
 //!   putting some extra study time into.
-//! * Functions provide some helpful ways to create some basic streams.
+//! * Functions provide some helpful ways to create some basic async iterators.
 //! * Structs are often the return types of the various methods on this
 //!   module's traits. You'll usually want to look at the method that creates
 //!   the `struct`, rather than the `struct` itself. For more detail about why,
-//!   see '[Implementing Stream](#implementing-stream)'.
+//!   see '[Implementing Async Iterator](#implementing-async-iterator)'.
 //!
 //! [Traits]: #traits
 //!
-//! That's it! Let's dig into streams.
+//! That's it! Let's dig into async iterators.
 //!
-//! # Stream
+//! # Async Iterators
 //!
-//! The heart and soul of this module is the [`Stream`] trait. The core of
-//! [`Stream`] looks like this:
+//! The heart and soul of this module is the [`AsyncIterator`] trait. The core of
+//! [`AsyncIterator`] looks like this:
 //!
 //! ```
 //! # use core::task::{Context, Poll};
 //! # use core::pin::Pin;
-//! trait Stream {
+//! trait AsyncIterator {
 //!     type Item;
 //!     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
 //! }
 //! ```
 //!
-//! Unlike `Iterator`, `Stream` makes a distinction between the [`poll_next`]
-//! method which is used when implementing a `Stream`, and a (to-be-implemented)
-//! `next` method which is used when consuming a stream. Consumers of `Stream`
+//! Unlike `Iterator`, `AsyncIterator` makes a distinction between the [`poll_next`]
+//! method which is used when implementing an `AsyncIterator`, and a (to-be-implemented)
+//! `next` method which is used when consuming an async iterator. Consumers of `AsyncIterator`
 //! only need to consider `next`, which when called, returns a future which
-//! yields `Option<Stream::Item>`.
+//! yields `Option<AsyncIterator::Item>`.
 //!
 //! The future returned by `next` will yield `Some(Item)` as long as there are
 //! elements, and once they've all been exhausted, will yield `None` to indicate
 //! that iteration is finished. If we're waiting on something asynchronous to
-//! resolve, the future will wait until the stream is ready to yield again.
+//! resolve, the future will wait until the async iterator is ready to yield again.
 //!
-//! Individual streams may choose to resume iteration, and so calling `next`
+//! Individual async iterators may choose to resume iteration, and so calling `next`
 //! again may or may not eventually yield `Some(Item)` again at some point.
 //!
-//! [`Stream`]'s full definition includes a number of other methods as well,
+//! [`AsyncIterator`]'s full definition includes a number of other methods as well,
 //! but they are default methods, built on top of [`poll_next`], and so you get
 //! them for free.
 //!
 //! [`Poll`]: super::task::Poll
-//! [`poll_next`]: Stream::poll_next
+//! [`poll_next`]: AsyncIterator::poll_next
 //!
-//! # Implementing Stream
+//! # Implementing Async Iterator
 //!
-//! Creating a stream of your own involves two steps: creating a `struct` to
-//! hold the stream's state, and then implementing [`Stream`] for that
+//! Creating an async iterator of your own involves two steps: creating a `struct` to
+//! hold the async iterator's state, and then implementing [`AsyncIterator`] for that
 //! `struct`.
 //!
-//! Let's make a stream named `Counter` which counts from `1` to `5`:
+//! Let's make an async iterator named `Counter` which counts from `1` to `5`:
 //!
 //! ```no_run
-//! #![feature(async_stream)]
-//! # use core::stream::Stream;
+//! #![feature(async_iterator)]
+//! # use core::async_iter::AsyncIterator;
 //! # use core::task::{Context, Poll};
 //! # use core::pin::Pin;
 //!
 //! // First, the struct:
 //!
-//! /// A stream which counts from one to five
+//! /// An async iterator which counts from one to five
 //! struct Counter {
 //!     count: usize,
 //! }
@@ -90,9 +89,9 @@
 //!     }
 //! }
 //!
-//! // Then, we implement `Stream` for our `Counter`:
+//! // Then, we implement `AsyncIterator` for our `Counter`:
 //!
-//! impl Stream for Counter {
+//! impl AsyncIterator for Counter {
 //!     // we will be counting with usize
 //!     type Item = usize;
 //!
@@ -113,17 +112,17 @@
 //!
 //! # Laziness
 //!
-//! Streams are *lazy*. This means that just creating a stream doesn't _do_ a
-//! whole lot. Nothing really happens until you call `poll_next`. This is
-//! sometimes a source of confusion when creating a stream solely for its side
+//! Async iterators are *lazy*. This means that just creating an async iterator doesn't
+//! _do_ a whole lot. Nothing really happens until you call `poll_next`. This is
+//! sometimes a source of confusion when creating an async iterator solely for its side
 //! effects. The compiler will warn us about this kind of behavior:
 //!
 //! ```text
-//! warning: unused result that must be used: streams do nothing unless polled
+//! warning: unused result that must be used: async iterators do nothing unless polled
 //! ```
 
+mod async_iter;
 mod from_iter;
-mod stream;
 
+pub use async_iter::AsyncIterator;
 pub use from_iter::{from_iter, FromIter};
-pub use stream::Stream;
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index a8fe5f59bae..5a361edecd9 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -1,6 +1,7 @@
 use crate::cmp::{self, Ordering};
 use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try};
 
+use super::super::try_process;
 use super::super::TrustedRandomAccessNoCoerce;
 use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
 use super::super::{FlatMap, Flatten};
@@ -1777,6 +1778,87 @@ pub trait Iterator {
         FromIterator::from_iter(self)
     }
 
+    /// Fallibly transforms an iterator into a collection, short circuiting if
+    /// a failure is encountered.
+    ///
+    /// `try_collect()` is a variation of [`collect()`][`collect`] that allows fallible
+    /// conversions during collection. Its main use case is simplifying conversions from
+    /// iterators yielding [`Option<T>`][`Option`] into `Option<Collection<T>>`, or similarly for other [`Try`]
+    /// types (e.g. [`Result`]).
+    ///
+    /// Importantly, `try_collect()` doesn't require that the outer [`Try`] type also implements [`FromIterator`];
+    /// only the inner type produced on `Try::Output` must implement it. Concretely,
+    /// this means that collecting into `ControlFlow<_, Vec<i32>>` is valid because `Vec<i32>` implements
+    /// [`FromIterator`], even though [`ControlFlow`] doesn't.
+    ///
+    /// Also, if a failure is encountered during `try_collect()`, the iterator is still valid and
+    /// may continue to be used, in which case it will continue iterating starting after the element that
+    /// triggered the failure. See the last example below for an example of how this works.
+    ///
+    /// # Examples
+    /// Successfully collecting an iterator of `Option<i32>` into `Option<Vec<i32>>`:
+    /// ```
+    /// #![feature(iterator_try_collect)]
+    ///
+    /// let u = vec![Some(1), Some(2), Some(3)];
+    /// let v = u.into_iter().try_collect::<Vec<i32>>();
+    /// assert_eq!(v, Some(vec![1, 2, 3]));
+    /// ```
+    ///
+    /// Failing to collect in the same way:
+    /// ```
+    /// #![feature(iterator_try_collect)]
+    ///
+    /// let u = vec![Some(1), Some(2), None, Some(3)];
+    /// let v = u.into_iter().try_collect::<Vec<i32>>();
+    /// assert_eq!(v, None);
+    /// ```
+    ///
+    /// A similar example, but with `Result`:
+    /// ```
+    /// #![feature(iterator_try_collect)]
+    ///
+    /// let u: Vec<Result<i32, ()>> = vec![Ok(1), Ok(2), Ok(3)];
+    /// let v = u.into_iter().try_collect::<Vec<i32>>();
+    /// assert_eq!(v, Ok(vec![1, 2, 3]));
+    ///
+    /// let u = vec![Ok(1), Ok(2), Err(()), Ok(3)];
+    /// let v = u.into_iter().try_collect::<Vec<i32>>();
+    /// assert_eq!(v, Err(()));
+    /// ```
+    ///
+    /// Finally, even [`ControlFlow`] works, despite the fact that it
+    /// doesn't implement [`FromIterator`]. Note also that the iterator can
+    /// continue to be used, even if a failure is encountered:
+    ///
+    /// ```
+    /// #![feature(iterator_try_collect)]
+    ///
+    /// use core::ops::ControlFlow::{Break, Continue};
+    ///
+    /// let u = [Continue(1), Continue(2), Break(3), Continue(4), Continue(5)];
+    /// let mut it = u.into_iter();
+    ///
+    /// let v = it.try_collect::<Vec<_>>();
+    /// assert_eq!(v, Break(3));
+    ///
+    /// let v = it.try_collect::<Vec<_>>();
+    /// assert_eq!(v, Continue(vec![4, 5]));
+    /// ```
+    ///
+    /// [`collect`]: Iterator::collect
+    #[inline]
+    #[unstable(feature = "iterator_try_collect", issue = "94047")]
+    fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B>
+    where
+        Self: Sized,
+        <Self as Iterator>::Item: Try,
+        <<Self as Iterator>::Item as Try>::Residual: Residual<B>,
+        B: FromIterator<<Self::Item as Try>::Output>,
+    {
+        try_process(self, |i| i.collect())
+    }
+
     /// Consumes an iterator, creating two collections from it.
     ///
     /// The predicate passed to `partition()` can return `true`, or `false`.
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index afef129303e..aa1ad9362a9 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -305,6 +305,8 @@ pub mod ops;
 pub mod any;
 pub mod array;
 pub mod ascii;
+#[unstable(feature = "async_iterator", issue = "79024")]
+pub mod async_iter;
 pub mod cell;
 pub mod char;
 pub mod ffi;
@@ -316,8 +318,6 @@ pub mod panic;
 pub mod panicking;
 pub mod pin;
 pub mod result;
-#[unstable(feature = "async_stream", issue = "79024")]
-pub mod stream;
 pub mod sync;
 
 pub mod fmt;
diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs
index 092b7cf0f2c..95be879e319 100644
--- a/library/core/src/panic/unwind_safe.rs
+++ b/library/core/src/panic/unwind_safe.rs
@@ -1,10 +1,10 @@
+use crate::async_iter::AsyncIterator;
 use crate::cell::UnsafeCell;
 use crate::fmt;
 use crate::future::Future;
 use crate::ops::{Deref, DerefMut};
 use crate::pin::Pin;
 use crate::ptr::{NonNull, Unique};
-use crate::stream::Stream;
 use crate::task::{Context, Poll};
 
 /// A marker trait which represents "panic safe" types in Rust.
@@ -290,8 +290,8 @@ impl<F: Future> Future for AssertUnwindSafe<F> {
     }
 }
 
-#[unstable(feature = "async_stream", issue = "79024")]
-impl<S: Stream> Stream for AssertUnwindSafe<S> {
+#[unstable(feature = "async_iterator", issue = "79024")]
+impl<S: AsyncIterator> AsyncIterator for AssertUnwindSafe<S> {
     type Item = S::Item;
 
     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<S::Item>> {
diff --git a/library/core/tests/iter/traits/iterator.rs b/library/core/tests/iter/traits/iterator.rs
index 972d61ba909..cf69f0a7a4d 100644
--- a/library/core/tests/iter/traits/iterator.rs
+++ b/library/core/tests/iter/traits/iterator.rs
@@ -497,6 +497,52 @@ fn test_collect() {
     assert!(a == b);
 }
 
+#[test]
+fn test_try_collect() {
+    use core::ops::ControlFlow::{Break, Continue};
+
+    let u = vec![Some(1), Some(2), Some(3)];
+    let v = u.into_iter().try_collect::<Vec<i32>>();
+    assert_eq!(v, Some(vec![1, 2, 3]));
+
+    let u = vec![Some(1), Some(2), None, Some(3)];
+    let mut it = u.into_iter();
+    let v = it.try_collect::<Vec<i32>>();
+    assert_eq!(v, None);
+    let v = it.try_collect::<Vec<i32>>();
+    assert_eq!(v, Some(vec![3]));
+
+    let u: Vec<Result<i32, ()>> = vec![Ok(1), Ok(2), Ok(3)];
+    let v = u.into_iter().try_collect::<Vec<i32>>();
+    assert_eq!(v, Ok(vec![1, 2, 3]));
+
+    let u = vec![Ok(1), Ok(2), Err(()), Ok(3)];
+    let v = u.into_iter().try_collect::<Vec<i32>>();
+    assert_eq!(v, Err(()));
+
+    let numbers = vec![1, 2, 3, 4, 5];
+    let all_positive = numbers
+        .iter()
+        .cloned()
+        .map(|n| if n > 0 { Some(n) } else { None })
+        .try_collect::<Vec<i32>>();
+    assert_eq!(all_positive, Some(numbers));
+
+    let numbers = vec![-2, -1, 0, 1, 2];
+    let all_positive =
+        numbers.into_iter().map(|n| if n > 0 { Some(n) } else { None }).try_collect::<Vec<i32>>();
+    assert_eq!(all_positive, None);
+
+    let u = [Continue(1), Continue(2), Break(3), Continue(4), Continue(5)];
+    let mut it = u.into_iter();
+
+    let v = it.try_collect::<Vec<_>>();
+    assert_eq!(v, Break(3));
+
+    let v = it.try_collect::<Vec<_>>();
+    assert_eq!(v, Continue(vec![4, 5]));
+}
+
 // just tests by whether or not this compiles
 fn _empty_impl_all_auto_traits<T>() {
     use std::panic::{RefUnwindSafe, UnwindSafe};
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 65be0c320c2..06c7be054a0 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -6,7 +6,7 @@
 #![feature(bool_to_option)]
 #![feature(box_syntax)]
 #![feature(cell_update)]
-#![feature(cfg_panic)]
+#![cfg_attr(bootstrap, feature(cfg_panic))]
 #![cfg_attr(bootstrap, feature(cfg_target_has_atomic))]
 #![feature(const_assume)]
 #![feature(const_black_box)]
@@ -67,6 +67,7 @@
 #![feature(iter_intersperse)]
 #![feature(iter_is_partitioned)]
 #![feature(iter_order_by)]
+#![feature(iterator_try_collect)]
 #![feature(iterator_try_reduce)]
 #![feature(const_mut_refs)]
 #![feature(const_pin)]
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 9e61defc31e..c9d91d2c03b 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -547,6 +547,10 @@ impl<K, V, S> HashMap<K, V, S> {
     /// Clears the map, returning all key-value pairs as an iterator. Keeps the
     /// allocated memory for reuse.
     ///
+    /// If the returned iterator is dropped before being fully consumed, it
+    /// drops the remaining key-value pairs. The returned iterator keeps a
+    /// mutable borrow on the vector to optimize its implementation.
+    ///
     /// # Examples
     ///
     /// ```
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index d1450987e73..200667ae390 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -227,7 +227,12 @@ impl<T, S> HashSet<T, S> {
         self.base.is_empty()
     }
 
-    /// Clears the set, returning all elements in an iterator.
+    /// Clears the set, returning all elements as an iterator. Keeps the
+    /// allocated memory for reuse.
+    ///
+    /// If the returned iterator is dropped before being fully consumed, it
+    /// drops the remaining elements. The returned iterator keeps a mutable
+    /// borrow on the vector to optimize its implementation.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs
index 6e70d5ca02d..1678367290e 100644
--- a/library/std/src/ffi/c_str.rs
+++ b/library/std/src/ffi/c_str.rs
@@ -382,7 +382,7 @@ impl CString {
                 let bytes: Vec<u8> = self.into();
                 match memchr::memchr(0, &bytes) {
                     Some(i) => Err(NulError(i, bytes)),
-                    None => Ok(unsafe { CString::from_vec_unchecked(bytes) }),
+                    None => Ok(unsafe { CString::_from_vec_unchecked(bytes) }),
                 }
             }
         }
@@ -405,7 +405,7 @@ impl CString {
             // This allows better optimizations if lto enabled.
             match memchr::memchr(0, bytes) {
                 Some(i) => Err(NulError(i, buffer)),
-                None => Ok(unsafe { CString::from_vec_unchecked(buffer) }),
+                None => Ok(unsafe { CString::_from_vec_unchecked(buffer) }),
             }
         }
 
@@ -451,10 +451,15 @@ impl CString {
     /// ```
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
+    pub unsafe fn from_vec_unchecked(v: Vec<u8>) -> Self {
+        debug_assert!(memchr::memchr(0, &v).is_none());
+        unsafe { Self::_from_vec_unchecked(v) }
+    }
+
+    unsafe fn _from_vec_unchecked(mut v: Vec<u8>) -> Self {
         v.reserve_exact(1);
         v.push(0);
-        CString { inner: v.into_boxed_slice() }
+        Self { inner: v.into_boxed_slice() }
     }
 
     /// Retakes ownership of a `CString` that was transferred to C via
@@ -578,7 +583,7 @@ impl CString {
     pub fn into_string(self) -> Result<String, IntoStringError> {
         String::from_utf8(self.into_bytes()).map_err(|e| IntoStringError {
             error: e.utf8_error(),
-            inner: unsafe { CString::from_vec_unchecked(e.into_bytes()) },
+            inner: unsafe { Self::_from_vec_unchecked(e.into_bytes()) },
         })
     }
 
@@ -735,6 +740,11 @@ impl CString {
     #[must_use]
     #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
     pub unsafe fn from_vec_with_nul_unchecked(v: Vec<u8>) -> Self {
+        debug_assert!(memchr::memchr(0, &v).unwrap() + 1 == v.len());
+        unsafe { Self::_from_vec_with_nul_unchecked(v) }
+    }
+
+    unsafe fn _from_vec_with_nul_unchecked(v: Vec<u8>) -> Self {
         Self { inner: v.into_boxed_slice() }
     }
 
@@ -778,7 +788,7 @@ impl CString {
             Some(nul_pos) if nul_pos + 1 == v.len() => {
                 // SAFETY: We know there is only one nul byte, at the end
                 // of the vec.
-                Ok(unsafe { Self::from_vec_with_nul_unchecked(v) })
+                Ok(unsafe { Self::_from_vec_with_nul_unchecked(v) })
             }
             Some(nul_pos) => Err(FromVecWithNulError {
                 error_kind: FromBytesWithNulErrorKind::InteriorNul(nul_pos),
@@ -811,7 +821,7 @@ impl ops::Deref for CString {
 
     #[inline]
     fn deref(&self) -> &CStr {
-        unsafe { CStr::from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) }
+        unsafe { CStr::_from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) }
     }
 }
 
@@ -928,7 +938,7 @@ impl From<Vec<NonZeroU8>> for CString {
             };
             // SAFETY: `v` cannot contain null bytes, given the type-level
             // invariant of `NonZeroU8`.
-            CString::from_vec_unchecked(v)
+            Self::_from_vec_unchecked(v)
         }
     }
 }
@@ -1225,7 +1235,7 @@ impl CStr {
         unsafe {
             let len = sys::strlen(ptr);
             let ptr = ptr as *const u8;
-            CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
+            Self::_from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
         }
     }
 
@@ -1268,7 +1278,7 @@ impl CStr {
             Some(nul_pos) if nul_pos + 1 == bytes.len() => {
                 // SAFETY: We know there is only one nul byte, at the end
                 // of the byte slice.
-                Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
+                Ok(unsafe { Self::_from_bytes_with_nul_unchecked(bytes) })
             }
             Some(nul_pos) => Err(FromBytesWithNulError::interior_nul(nul_pos)),
             None => Err(FromBytesWithNulError::not_nul_terminated()),
@@ -1297,12 +1307,19 @@ impl CStr {
     #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
     #[rustc_const_stable(feature = "const_cstr_unchecked", since = "1.59.0")]
     pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
+        // We're in a const fn, so this is the best we can do
+        debug_assert!(!bytes.is_empty() && bytes[bytes.len() - 1] == 0);
+        unsafe { Self::_from_bytes_with_nul_unchecked(bytes) }
+    }
+
+    #[inline]
+    const unsafe fn _from_bytes_with_nul_unchecked(bytes: &[u8]) -> &Self {
         // SAFETY: Casting to CStr is safe because its internal representation
         // is a [u8] too (safe only inside std).
         // Dereferencing the obtained pointer is safe because it comes from a
         // reference. Making a reference is then safe because its lifetime
         // is bound by the lifetime of the given `bytes`.
-        unsafe { &*(bytes as *const [u8] as *const CStr) }
+        unsafe { &*(bytes as *const [u8] as *const Self) }
     }
 
     /// Returns the inner pointer to this C string.
@@ -1566,7 +1583,7 @@ impl ops::Index<ops::RangeFrom<usize>> for CStr {
         // byte, since otherwise we could get an empty string that doesn't end
         // in a null.
         if index.start < bytes.len() {
-            unsafe { CStr::from_bytes_with_nul_unchecked(&bytes[index.start..]) }
+            unsafe { CStr::_from_bytes_with_nul_unchecked(&bytes[index.start..]) }
         } else {
             panic!(
                 "index out of bounds: the len is {} but the index is {}",
diff --git a/library/std/src/ffi/c_str/tests.rs b/library/std/src/ffi/c_str/tests.rs
index 4f7ba9ad437..00ba5460821 100644
--- a/library/std/src/ffi/c_str/tests.rs
+++ b/library/std/src/ffi/c_str/tests.rs
@@ -33,14 +33,6 @@ fn build_with_zero2() {
 }
 
 #[test]
-fn build_with_zero3() {
-    unsafe {
-        let s = CString::from_vec_unchecked(vec![0]);
-        assert_eq!(s.as_bytes(), b"\0");
-    }
-}
-
-#[test]
 fn formatted() {
     let s = CString::new(&b"abc\x01\x02\n\xE2\x80\xA6\xFF"[..]).unwrap();
     assert_eq!(format!("{:?}", s), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#);
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index a03da0682a5..8c38db9b62c 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -233,7 +233,7 @@
 #![feature(array_error_internals)]
 #![feature(assert_matches)]
 #![feature(associated_type_bounds)]
-#![feature(async_stream)]
+#![feature(async_iterator)]
 #![feature(atomic_mut_ptr)]
 #![feature(auto_traits)]
 #![feature(bench_black_box)]
@@ -404,6 +404,8 @@ pub use alloc_crate::vec;
 pub use core::any;
 #[stable(feature = "core_array", since = "1.36.0")]
 pub use core::array;
+#[unstable(feature = "async_iterator", issue = "79024")]
+pub use core::async_iter;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::cell;
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -458,8 +460,6 @@ pub use core::pin;
 pub use core::ptr;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::result;
-#[unstable(feature = "async_stream", issue = "79024")]
-pub use core::stream;
 #[stable(feature = "i128", since = "1.26.0")]
 #[allow(deprecated, deprecated_in_future)]
 pub use core::u128;
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index adb8b30ec08..e544608f83c 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -268,6 +268,12 @@ pub fn is_separator(c: char) -> bool {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const MAIN_SEPARATOR: char = crate::sys::path::MAIN_SEP;
 
+/// The primary separator of path components for the current platform.
+///
+/// For example, `/` on Unix and `\` on Windows.
+#[unstable(feature = "main_separator_str", issue = "94071")]
+pub const MAIN_SEPARATOR_STR: &str = crate::sys::path::MAIN_SEP_STR;
+
 ////////////////////////////////////////////////////////////////////////////////
 // Misc helpers
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/library/std/src/sys/solid/fs.rs b/library/std/src/sys/solid/fs.rs
index a6ed10f7789..a2cbee4dcf0 100644
--- a/library/std/src/sys/solid/fs.rs
+++ b/library/std/src/sys/solid/fs.rs
@@ -289,7 +289,26 @@ impl OpenOptions {
 }
 
 fn cstr(path: &Path) -> io::Result<CString> {
-    Ok(CString::new(path.as_os_str().as_bytes())?)
+    let path = path.as_os_str().as_bytes();
+
+    if !path.starts_with(br"\") {
+        // Relative paths aren't supported
+        return Err(crate::io::const_io_error!(
+            crate::io::ErrorKind::Unsupported,
+            "relative path is not supported on this platform",
+        ));
+    }
+
+    // Apply the thread-safety wrapper
+    const SAFE_PREFIX: &[u8] = br"\TS";
+    let wrapped_path = [SAFE_PREFIX, &path, &[0]].concat();
+
+    CString::from_vec_with_nul(wrapped_path).map_err(|_| {
+        crate::io::const_io_error!(
+            io::ErrorKind::InvalidInput,
+            "path provided contains a nul byte",
+        )
+    })
 }
 
 impl File {
diff --git a/library/stdarch b/library/stdarch
-Subproject 863d31b8e1314e15d124384e5eaa9ab21e12bd7
+Subproject b4a0e07552cf90ef8f1a5b775bf70e4db94b3d6
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 013687ce377..029049d5434 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1877,12 +1877,6 @@ fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) {
     } else {
         cmd.env("CFG_MINGW", "0").env("CFG_ABI", "MSVC");
     }
-
-    if target.contains("x86_64") {
-        cmd.env("CFG_PLATFORM", "x64");
-    } else {
-        cmd.env("CFG_PLATFORM", "x86");
-    }
 }
 
 /// Maybe add LLVM object files to the given destination lib-dir. Allows either static or dynamic linking.
diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
index d60be193bda..c7fd5ed6fcb 100644
--- a/src/doc/rustdoc/src/unstable-features.md
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -509,3 +509,6 @@ reverse-dependency like `examples/ex.rs` is given to rustdoc with the target
 crate being documented (`foobar`) and a path to output the calls
 (`output.calls`). Then, the generated calls file can be passed via
 `--with-examples` to the subsequent documentation of `foobar`.
+
+To scrape examples from test code, e.g. functions marked `#[test]`, then
+add the `--scrape-tests` flag.
diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
index d630f4ecb7b..457851b0cc7 100644
--- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md
+++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
@@ -16,11 +16,13 @@ This feature allows for use of one of following sanitizers:
   AddressSanitizer, but based on partial hardware assistance.
 * [LeakSanitizer][clang-lsan] a run-time memory leak detector.
 * [MemorySanitizer][clang-msan] a detector of uninitialized reads.
+* [MemTagSanitizer][clang-memtag] fast memory error detector based on
+  Armv8.5-A Memory Tagging Extension.
 * [ThreadSanitizer][clang-tsan] a fast data race detector.
 
 To enable a sanitizer compile with `-Zsanitizer=address`,`-Zsanitizer=cfi`,
-`-Zsanitizer=hwaddress`, `-Zsanitizer=leak`, `-Zsanitizer=memory` or
-`-Zsanitizer=thread`.
+`-Zsanitizer=hwaddress`, `-Zsanitizer=leak`, `-Zsanitizer=memory`,
+`-Zsanitizer=memtag`, or `-Zsanitizer=thread`.
 
 # AddressSanitizer
 
@@ -494,6 +496,20 @@ $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
     #0 0x560c04b2bc50 in memory::main::hd2333c1899d997f5 $CWD/src/main.rs:3
 ```
 
+# MemTagSanitizer
+
+MemTagSanitizer detects a similar class of errors as AddressSanitizer and HardwareAddressSanitizer, but with lower overhead suitable for use as hardening for production binaries.
+
+MemTagSanitizer is supported on the following targets:
+
+* `aarch64-linux-android`
+* `aarch64-unknown-linux-gnu`
+
+MemTagSanitizer requires hardware support and the `mte` target feature.
+To enable this target feature compile with `-C target-feature="+mte"`.
+
+More information can be found in the associated [LLVM documentation](https://llvm.org/docs/MemTagSanitizer.html).
+
 # ThreadSanitizer
 
 ThreadSanitizer is a data race detection tool. It is supported on the following
diff --git a/src/doc/unstable-book/src/language-features/asm-const.md b/src/doc/unstable-book/src/language-features/asm-const.md
index 1063c23b6df..670c4df414f 100644
--- a/src/doc/unstable-book/src/language-features/asm-const.md
+++ b/src/doc/unstable-book/src/language-features/asm-const.md
@@ -1,8 +1,8 @@
 # `asm_const`
 
-The tracking issue for this feature is: [#72016]
+The tracking issue for this feature is: [#93332]
 
-[#72016]: https://github.com/rust-lang/rust/issues/72016
+[#93332]: https://github.com/rust-lang/rust/issues/93332
 
 ------------------------
 
diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
index 37fd67447c1..0a48eb4f81a 100644
--- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
+++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
@@ -1,8 +1,8 @@
 # `asm_experimental_arch`
 
-The tracking issue for this feature is: [#72016]
+The tracking issue for this feature is: [#93335]
 
-[#72016]: https://github.com/rust-lang/rust/issues/72016
+[#93335]: https://github.com/rust-lang/rust/issues/93335
 
 ------------------------
 
diff --git a/src/doc/unstable-book/src/language-features/asm-sym.md b/src/doc/unstable-book/src/language-features/asm-sym.md
index 7544e20807e..103d91caf4c 100644
--- a/src/doc/unstable-book/src/language-features/asm-sym.md
+++ b/src/doc/unstable-book/src/language-features/asm-sym.md
@@ -1,8 +1,8 @@
 # `asm_sym`
 
-The tracking issue for this feature is: [#72016]
+The tracking issue for this feature is: [#93333]
 
-[#72016]: https://github.com/rust-lang/rust/issues/72016
+[#93333]: https://github.com/rust-lang/rust/issues/93333
 
 ------------------------
 
diff --git a/src/doc/unstable-book/src/language-features/asm-unwind.md b/src/doc/unstable-book/src/language-features/asm-unwind.md
index 414193fe801..809e6d75b35 100644
--- a/src/doc/unstable-book/src/language-features/asm-unwind.md
+++ b/src/doc/unstable-book/src/language-features/asm-unwind.md
@@ -1,8 +1,8 @@
 # `asm_unwind`
 
-The tracking issue for this feature is: [#72016]
+The tracking issue for this feature is: [#93334]
 
-[#72016]: https://github.com/rust-lang/rust/issues/72016
+[#93334]: https://github.com/rust-lang/rust/issues/93334
 
 ------------------------
 
diff --git a/src/doc/unstable-book/src/language-features/cfg-panic.md b/src/doc/unstable-book/src/language-features/cfg-panic.md
deleted file mode 100644
index f5b73128ad6..00000000000
--- a/src/doc/unstable-book/src/language-features/cfg-panic.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# `cfg_panic`
-
-The tracking issue for this feature is: [#77443]
-
-[#77443]: https://github.com/rust-lang/rust/issues/77443
-
-------------------------
-
-The `cfg_panic` feature makes it possible to execute different code
-depending on the panic strategy.
-
-Possible values at the moment are `"unwind"` or `"abort"`, although
-it is possible that new panic strategies may be added to Rust in the
-future.
-
-## Examples
-
-```rust
-#![feature(cfg_panic)]
-
-#[cfg(panic = "unwind")]
-fn a() {
-    // ...
-}
-
-#[cfg(not(panic = "unwind"))]
-fn a() {
-    // ...
-}
-
-fn b() {
-    if cfg!(panic = "abort") {
-        // ...
-    } else {
-        // ...
-    }
-}
-```
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index bcbde428e7c..187bc13357a 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -585,12 +585,7 @@ fn clean_ty_generics(
         .params
         .iter()
         .filter_map(|param| match param.kind {
-            ty::GenericParamDefKind::Lifetime => {
-                if param.name == kw::UnderscoreLifetime {
-                    return None;
-                }
-                Some(param.clean(cx))
-            }
+            ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
             ty::GenericParamDefKind::Type { synthetic, .. } => {
                 if param.name == kw::SelfUpper {
                     assert_eq!(param.index, 0);
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 0bad1532808..ea18d915deb 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -51,9 +51,7 @@ crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     // Look for equality predicates on associated types that can be merged into
     // general bound predicates
     equalities.retain(|&(ref lhs, ref rhs)| {
-        let (self_, trait_did, name) = if let Some(p) = lhs.projection() {
-            p
-        } else {
+        let Some((self_, trait_did, name)) = lhs.projection() else {
             return true;
         };
         let generic = match self_ {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 893e126283b..c2f6f7aea75 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -200,6 +200,7 @@ crate fn create_config(
         lint_opts,
         describe_lints,
         lint_cap,
+        scrape_examples_options,
         ..
     }: RustdocOptions,
 ) -> rustc_interface::Config {
@@ -227,6 +228,7 @@ crate fn create_config(
 
     let crate_types =
         if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
+    let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false);
     // plays with error output here!
     let sessopts = config::Options {
         maybe_sysroot,
@@ -244,12 +246,14 @@ crate fn create_config(
         edition,
         describe_lints,
         crate_name,
+        test,
         ..Options::default()
     };
 
     interface::Config {
         opts: sessopts,
         crate_cfg: interface::parse_cfgspecs(cfgs),
+        crate_check_cfg: interface::parse_check_cfg(vec![]),
         input,
         input_path: cpath,
         output_file: None,
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 3a9fb6d1420..696397c5f67 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -91,6 +91,7 @@ crate fn run(options: RustdocOptions) -> Result<(), ErrorReported> {
     let config = interface::Config {
         opts: sessopts,
         crate_cfg: interface::parse_cfgspecs(cfgs),
+        crate_check_cfg: interface::parse_check_cfg(vec![]),
         input,
         input_path: None,
         output_file: None,
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 1c0448828a2..7061a9674e4 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -236,9 +236,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
         let should_panic;
         let ignore;
         let edition;
-        let kind = if let Some(Event::Start(Tag::CodeBlock(kind))) = event {
-            kind
-        } else {
+        let Some(Event::Start(Tag::CodeBlock(kind))) = event else {
             return event;
         };
 
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 1c3f9b56b47..3e3302f8f4d 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1963,16 +1963,12 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
                 // We want links' order to be reproducible so we don't use unstable sort.
                 assoc_consts.sort();
 
-                out.push_str(
-                    "<h3 class=\"sidebar-title\">\
-                        <a href=\"#implementations\">Associated Constants</a>\
-                     </h3>\
-                     <div class=\"sidebar-links\">",
+                print_sidebar_block(
+                    out,
+                    "implementations",
+                    "Associated Constants",
+                    assoc_consts.iter(),
                 );
-                for line in assoc_consts {
-                    write!(out, "{}", line);
-                }
-                out.push_str("</div>");
             }
             let mut methods = v
                 .iter()
@@ -1983,14 +1979,7 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
                 // We want links' order to be reproducible so we don't use unstable sort.
                 methods.sort();
 
-                out.push_str(
-                    "<h3 class=\"sidebar-title\"><a href=\"#implementations\">Methods</a></h3>\
-                     <div class=\"sidebar-links\">",
-                );
-                for line in methods {
-                    write!(out, "{}", line);
-                }
-                out.push_str("</div>");
+                print_sidebar_block(out, "implementations", "Methods", methods.iter());
             }
         }
 
@@ -2029,14 +2018,6 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
                 ret
             };
 
-            let write_sidebar_links = |out: &mut Buffer, links: Vec<String>| {
-                out.push_str("<div class=\"sidebar-links\">");
-                for link in links {
-                    out.push_str(&link);
-                }
-                out.push_str("</div>");
-            };
-
             let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
                 v.iter().partition::<Vec<_>, _>(|i| i.inner_impl().kind.is_auto());
             let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) =
@@ -2047,27 +2028,30 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
             let blanket_format = format_impls(blanket_impl);
 
             if !concrete_format.is_empty() {
-                out.push_str(
-                    "<h3 class=\"sidebar-title\"><a href=\"#trait-implementations\">\
-                        Trait Implementations</a></h3>",
+                print_sidebar_block(
+                    out,
+                    "trait-implementations",
+                    "Trait Implementations",
+                    concrete_format.iter(),
                 );
-                write_sidebar_links(out, concrete_format);
             }
 
             if !synthetic_format.is_empty() {
-                out.push_str(
-                    "<h3 class=\"sidebar-title\"><a href=\"#synthetic-implementations\">\
-                        Auto Trait Implementations</a></h3>",
+                print_sidebar_block(
+                    out,
+                    "synthetic-implementations",
+                    "Auto Trait Implementations",
+                    synthetic_format.iter(),
                 );
-                write_sidebar_links(out, synthetic_format);
             }
 
             if !blanket_format.is_empty() {
-                out.push_str(
-                    "<h3 class=\"sidebar-title\"><a href=\"#blanket-implementations\">\
-                        Blanket Implementations</a></h3>",
+                print_sidebar_block(
+                    out,
+                    "blanket-implementations",
+                    "Blanket Implementations",
+                    blanket_format.iter(),
                 );
-                write_sidebar_links(out, blanket_format);
             }
         }
     }
@@ -2127,20 +2111,14 @@ fn sidebar_deref_methods(
                 } else {
                     "deref-methods"
                 };
-                write!(
-                    out,
-                    "<h3 class=\"sidebar-title\"><a href=\"#{}\">Methods from {}&lt;Target={}&gt;</a></h3>",
-                    id,
+                let title = format!(
+                    "Methods from {}&lt;Target={}&gt;",
                     Escape(&format!("{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print(cx))),
                     Escape(&format!("{:#}", real_target.print(cx))),
                 );
                 // We want links' order to be reproducible so we don't use unstable sort.
                 ret.sort();
-                out.push_str("<div class=\"sidebar-links\">");
-                for link in ret {
-                    write!(out, "{}", link);
-                }
-                out.push_str("</div>");
+                print_sidebar_block(out, id, &title, ret.iter());
             }
         }
 
@@ -2166,27 +2144,19 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea
     let fields = get_struct_fields_name(&s.fields);
 
     if !fields.is_empty() {
-        if let CtorKind::Fictive = s.struct_type {
-            sidebar.push_str(
-                "<h3 class=\"sidebar-title\"><a href=\"#fields\">Fields</a></h3>\
-                <div class=\"sidebar-links\">",
-            );
-
-            for field in fields {
-                sidebar.push_str(&field);
+        match s.struct_type {
+            CtorKind::Fictive => {
+                print_sidebar_block(&mut sidebar, "fields", "Fields", fields.iter());
             }
-
-            sidebar.push_str("</div>");
-        } else if let CtorKind::Fn = s.struct_type {
-            sidebar
-                .push_str("<h3 class=\"sidebar-title\"><a href=\"#fields\">Tuple Fields</a></h3>");
+            CtorKind::Fn => print_sidebar_title(&mut sidebar, "fields", "Tuple Fields"),
+            CtorKind::Const => {}
         }
     }
 
     sidebar_assoc_items(cx, &mut sidebar, it);
 
     if !sidebar.is_empty() {
-        write!(buf, "<div class=\"block items\">{}</div>", sidebar.into_inner());
+        write!(buf, "<section>{}</section>", sidebar.into_inner());
     }
 }
 
@@ -2214,18 +2184,50 @@ fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String
     }
 }
 
+/// Don't call this function directly!!! Use `print_sidebar_title` or `print_sidebar_block` instead!
+fn print_sidebar_title_inner(buf: &mut Buffer, id: &str, title: &str) {
+    write!(
+        buf,
+        "<h3 class=\"sidebar-title\">\
+             <a href=\"#{}\">{}</a>\
+         </h3>",
+        id, title
+    );
+}
+
+fn print_sidebar_title(buf: &mut Buffer, id: &str, title: &str) {
+    buf.push_str("<div class=\"block\">");
+    print_sidebar_title_inner(buf, id, title);
+    buf.push_str("</div>");
+}
+
+fn print_sidebar_block(
+    buf: &mut Buffer,
+    id: &str,
+    title: &str,
+    items: impl Iterator<Item = impl fmt::Display>,
+) {
+    buf.push_str("<div class=\"block\">");
+    print_sidebar_title_inner(buf, id, title);
+    buf.push_str("<ul>");
+    for item in items {
+        write!(buf, "<li>{}</li>", item);
+    }
+    buf.push_str("</ul></div>");
+}
+
 fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean::Trait) {
-    buf.write_str("<div class=\"block items\">");
+    buf.write_str("<section>");
 
     fn print_sidebar_section(
         out: &mut Buffer,
         items: &[clean::Item],
-        before: &str,
+        id: &str,
+        title: &str,
         filter: impl Fn(&clean::Item) -> bool,
-        write: impl Fn(&mut Buffer, &str),
-        after: &str,
+        mapper: impl Fn(&str) -> String,
     ) {
-        let mut items = items
+        let mut items: Vec<&str> = items
             .iter()
             .filter_map(|m| match m.name {
                 Some(ref name) if filter(m) => Some(name.as_str()),
@@ -2235,52 +2237,44 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
 
         if !items.is_empty() {
             items.sort_unstable();
-            out.push_str(before);
-            for item in items.into_iter() {
-                write(out, &item);
-            }
-            out.push_str(after);
+            print_sidebar_block(out, id, title, items.into_iter().map(mapper));
         }
     }
 
     print_sidebar_section(
         buf,
         &t.items,
-        "<h3 class=\"sidebar-title\"><a href=\"#associated-types\">\
-            Associated Types</a></h3><div class=\"sidebar-links\">",
+        "associated-types",
+        "Associated Types",
         |m| m.is_associated_type(),
-        |out, sym| write!(out, "<a href=\"#associatedtype.{0}\">{0}</a>", sym),
-        "</div>",
+        |sym| format!("<a href=\"#associatedtype.{0}\">{0}</a>", sym),
     );
 
     print_sidebar_section(
         buf,
         &t.items,
-        "<h3 class=\"sidebar-title\"><a href=\"#associated-const\">\
-            Associated Constants</a></h3><div class=\"sidebar-links\">",
+        "associated-const",
+        "Associated Constants",
         |m| m.is_associated_const(),
-        |out, sym| write!(out, "<a href=\"#associatedconstant.{0}\">{0}</a>", sym),
-        "</div>",
+        |sym| format!("<a href=\"#associatedconstant.{0}\">{0}</a>", sym),
     );
 
     print_sidebar_section(
         buf,
         &t.items,
-        "<h3 class=\"sidebar-title\"><a href=\"#required-methods\">\
-            Required Methods</a></h3><div class=\"sidebar-links\">",
+        "required-methods",
+        "Required Methods",
         |m| m.is_ty_method(),
-        |out, sym| write!(out, "<a href=\"#tymethod.{0}\">{0}</a>", sym),
-        "</div>",
+        |sym| format!("<a href=\"#tymethod.{0}\">{0}</a>", sym),
     );
 
     print_sidebar_section(
         buf,
         &t.items,
-        "<h3 class=\"sidebar-title\"><a href=\"#provided-methods\">\
-            Provided Methods</a></h3><div class=\"sidebar-links\">",
+        "provided-methods",
+        "Provided Methods",
         |m| m.is_method(),
-        |out, sym| write!(out, "<a href=\"#method.{0}\">{0}</a>", sym),
-        "</div>",
+        |sym| format!("<a href=\"#method.{0}\">{0}</a>", sym),
     );
 
     let cache = cx.cache();
@@ -2295,29 +2289,23 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
 
         if !res.is_empty() {
             res.sort();
-            buf.push_str(
-                "<h3 class=\"sidebar-title\"><a href=\"#foreign-impls\">\
-                    Implementations on Foreign Types</a></h3>\
-                 <div class=\"sidebar-links\">",
+            print_sidebar_block(
+                buf,
+                "foreign-impls",
+                "Implementations on Foreign Types",
+                res.iter().map(|(name, id)| format!("<a href=\"#{}\">{}</a>", id, Escape(&name))),
             );
-            for (name, id) in res.into_iter() {
-                write!(buf, "<a href=\"#{}\">{}</a>", id, Escape(&name));
-            }
-            buf.push_str("</div>");
         }
     }
 
     sidebar_assoc_items(cx, buf, it);
 
-    buf.push_str("<h3 class=\"sidebar-title\"><a href=\"#implementors\">Implementors</a></h3>");
+    print_sidebar_title(buf, "implementors", "Implementors");
     if t.is_auto {
-        buf.push_str(
-            "<h3 class=\"sidebar-title\"><a \
-                href=\"#synthetic-implementors\">Auto Implementors</a></h3>",
-        );
+        print_sidebar_title(buf, "synthetic-implementors", "Auto Implementors");
     }
 
-    buf.push_str("</div>")
+    buf.push_str("</section>")
 }
 
 fn sidebar_primitive(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item) {
@@ -2325,7 +2313,7 @@ fn sidebar_primitive(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item) {
     sidebar_assoc_items(cx, &mut sidebar, it);
 
     if !sidebar.is_empty() {
-        write!(buf, "<div class=\"block items\">{}</div>", sidebar.into_inner());
+        write!(buf, "<section>{}</section>", sidebar.into_inner());
     }
 }
 
@@ -2334,7 +2322,7 @@ fn sidebar_typedef(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item) {
     sidebar_assoc_items(cx, &mut sidebar, it);
 
     if !sidebar.is_empty() {
-        write!(buf, "<div class=\"block items\">{}</div>", sidebar.into_inner());
+        write!(buf, "<section>{}</section>", sidebar.into_inner());
     }
 }
 
@@ -2355,22 +2343,13 @@ fn sidebar_union(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, u: &clean
     let fields = get_struct_fields_name(&u.fields);
 
     if !fields.is_empty() {
-        sidebar.push_str(
-            "<h3 class=\"sidebar-title\"><a href=\"#fields\">Fields</a></h3>\
-            <div class=\"sidebar-links\">",
-        );
-
-        for field in fields {
-            sidebar.push_str(&field);
-        }
-
-        sidebar.push_str("</div>");
+        print_sidebar_block(&mut sidebar, "fields", "Fields", fields.iter());
     }
 
     sidebar_assoc_items(cx, &mut sidebar, it);
 
     if !sidebar.is_empty() {
-        write!(buf, "<div class=\"block items\">{}</div>", sidebar.into_inner());
+        write!(buf, "<section>{}</section>", sidebar.into_inner());
     }
 }
 
@@ -2388,17 +2367,13 @@ fn sidebar_enum(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, e: &clean:
         .collect::<Vec<_>>();
     if !variants.is_empty() {
         variants.sort_unstable();
-        sidebar.push_str(&format!(
-            "<h3 class=\"sidebar-title\"><a href=\"#variants\">Variants</a></h3>\
-             <div class=\"sidebar-links\">{}</div>",
-            variants.join(""),
-        ));
+        print_sidebar_block(&mut sidebar, "variants", "Variants", variants.iter());
     }
 
     sidebar_assoc_items(cx, &mut sidebar, it);
 
     if !sidebar.is_empty() {
-        write!(buf, "<div class=\"block items\">{}</div>", sidebar.into_inner());
+        write!(buf, "<section>{}</section>", sidebar.into_inner());
     }
 }
 
@@ -2569,7 +2544,15 @@ fn sidebar_module(buf: &mut Buffer, items: &[clean::Item]) {
     }
 
     if !sidebar.is_empty() {
-        write!(buf, "<div class=\"block items\"><ul>{}</ul></div>", sidebar);
+        write!(
+            buf,
+            "<section>\
+                 <div class=\"block\">\
+                     <ul>{}</ul>\
+                 </div>\
+             </section>",
+            sidebar
+        );
     }
 }
 
@@ -2578,7 +2561,7 @@ fn sidebar_foreign_type(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item) {
     sidebar_assoc_items(cx, &mut sidebar, it);
 
     if !sidebar.is_empty() {
-        write!(buf, "<div class=\"block items\">{}</div>", sidebar.into_inner());
+        write!(buf, "<section>{}</section>", sidebar.into_inner());
     }
 }
 
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 2ae7626b886..e84dc6c7240 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1752,9 +1752,7 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
                             <ul>",
                     );
 
-                    let adt = if let Adt(adt, _) = ty_layout.ty.kind() {
-                        adt
-                    } else {
+                    let Adt(adt, _) = ty_layout.ty.kind() else {
                         span_bug!(tcx.def_span(ty_def_id), "not an adt")
                     };
 
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 662221ae773..f1e0a89883a 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -484,10 +484,6 @@ h2.location a {
 	overflow: hidden;
 }
 
-.sidebar-links a {
-	white-space: nowrap;
-}
-
 .sidebar h2 {
 	border-bottom: none;
 	font-weight: 500;
@@ -504,11 +500,14 @@ h2.location a {
 	margin: 0;
 }
 
-.sidebar-links,
-.block {
+.sidebar-elems .block {
 	margin-bottom: 2em;
 }
 
+.sidebar-elems .block li a {
+	white-space: nowrap;
+}
+
 .mobile-topbar {
 	display: none;
 }
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index f9e9fe0d3cf..52980e07b8c 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -8,6 +8,7 @@ mod conversions;
 
 use std::cell::RefCell;
 use std::fs::{create_dir_all, File};
+use std::io::{BufWriter, Write};
 use std::path::PathBuf;
 use std::rc::Rc;
 
@@ -213,7 +214,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
         let mut index = (*self.index).clone().into_inner();
         index.extend(self.get_trait_items());
         // This needs to be the default HashMap for compatibility with the public interface for
-        // rustdoc-json
+        // rustdoc-json-types
         #[allow(rustc::default_hash_types)]
         let output = types::Crate {
             root: types::Id(String::from("0:0")),
@@ -263,8 +264,10 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
         let mut p = out_dir;
         p.push(output.index.get(&output.root).unwrap().name.clone().unwrap());
         p.set_extension("json");
-        let file = try_err!(File::create(&p), p);
-        serde_json::ser::to_writer(&file, &output).unwrap();
+        let mut file = BufWriter::new(try_err!(File::create(&p), p));
+        serde_json::ser::to_writer(&mut file, &output).unwrap();
+        try_err!(file.flush(), p);
+
         Ok(())
     }
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 170f166db50..7eff725989c 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -596,6 +596,9 @@ fn opts() -> Vec<RustcOptGroup> {
                 "collect function call information for functions from the target crate",
             )
         }),
+        unstable("scrape-tests", |o| {
+            o.optflag("", "scrape-tests", "Include test code when scraping examples")
+        }),
         unstable("with-examples", |o| {
             o.optmulti(
                 "",
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 8621fe6ba1b..33a1530d588 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1226,9 +1226,7 @@ impl LinkCollector<'_, '_> {
         let base_node =
             if item.is_mod() && inner_docs { self.mod_ids.last().copied() } else { parent_node };
 
-        let mut module_id = if let Some(id) = base_node {
-            id
-        } else {
+        let Some(mut module_id) = base_node else {
             // This is a bug.
             debug!("attempting to resolve item without parent module: {}", path_str);
             resolution_failure(
@@ -1977,9 +1975,7 @@ fn resolution_failure(
                     // If so, report it and say the first which failed; if not, say the first path segment didn't resolve.
                     let mut name = path_str;
                     'outer: loop {
-                        let (start, end) = if let Some(x) = split(name) {
-                            x
-                        } else {
+                        let Some((start, end)) = split(name) else {
                             // avoid bug that marked [Quux::Z] as missing Z, not Quux
                             if partial_res.is_none() {
                                 *unresolved = name.into();
diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs
index e28034b2b0d..5c11ab1d3be 100644
--- a/src/librustdoc/passes/collect_intra_doc_links/early.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs
@@ -118,6 +118,7 @@ impl IntraLinkCrateLoader<'_, '_> {
                 Vec::from_iter(self.resolver.cstore().trait_impls_in_crate_untracked(cnum));
             let all_inherent_impls =
                 Vec::from_iter(self.resolver.cstore().inherent_impls_in_crate_untracked(cnum));
+            let all_lang_items = Vec::from_iter(self.resolver.cstore().lang_items_untracked(cnum));
 
             // Querying traits in scope is expensive so we try to prune the impl and traits lists
             // using privacy, private traits and impls from other crates are never documented in
@@ -141,6 +142,9 @@ impl IntraLinkCrateLoader<'_, '_> {
                     self.add_traits_in_parent_scope(impl_def_id);
                 }
             }
+            for def_id in all_lang_items {
+                self.add_traits_in_parent_scope(def_id);
+            }
 
             self.all_traits.extend(all_traits);
             self.all_trait_impls.extend(all_trait_impls.into_iter().map(|(_, def_id, _)| def_id));
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index 16882cf83d0..7cf0ea9e84e 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -34,6 +34,7 @@ use std::path::PathBuf;
 crate struct ScrapeExamplesOptions {
     output_path: PathBuf,
     target_crates: Vec<String>,
+    crate scrape_tests: bool,
 }
 
 impl ScrapeExamplesOptions {
@@ -43,16 +44,22 @@ impl ScrapeExamplesOptions {
     ) -> Result<Option<Self>, i32> {
         let output_path = matches.opt_str("scrape-examples-output-path");
         let target_crates = matches.opt_strs("scrape-examples-target-crate");
-        match (output_path, !target_crates.is_empty()) {
-            (Some(output_path), true) => Ok(Some(ScrapeExamplesOptions {
+        let scrape_tests = matches.opt_present("scrape-tests");
+        match (output_path, !target_crates.is_empty(), scrape_tests) {
+            (Some(output_path), true, _) => Ok(Some(ScrapeExamplesOptions {
                 output_path: PathBuf::from(output_path),
                 target_crates,
+                scrape_tests,
             })),
-            (Some(_), false) | (None, true) => {
+            (Some(_), false, _) | (None, true, _) => {
                 diag.err("must use --scrape-examples-output-path and --scrape-examples-target-crate together");
                 Err(1)
             }
-            (None, false) => Ok(None),
+            (None, false, true) => {
+                diag.err("must use --scrape-examples-output-path and --scrape-examples-target-crate with --scrape-tests");
+                Err(1)
+            }
+            (None, false, false) => Ok(None),
         }
     }
 }
@@ -152,9 +159,7 @@ where
             }
             hir::ExprKind::MethodCall(_, _, span) => {
                 let types = tcx.typeck(ex.hir_id.owner);
-                let def_id = if let Some(def_id) = types.type_dependent_def_id(ex.hir_id) {
-                    def_id
-                } else {
+                let Some(def_id) = types.type_dependent_def_id(ex.hir_id) else {
                     trace!("type_dependent_def_id({}) = None", ex.hir_id);
                     return;
                 };
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 2cbb3324a5e..e8b3a0929db 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -188,9 +188,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         debug!("maybe_inline_local res: {:?}", res);
 
         let tcx = self.cx.tcx;
-        let res_did = if let Some(did) = res.opt_def_id() {
-            did
-        } else {
+        let Some(res_did) = res.opt_def_id() else {
             return false;
         };
 
diff --git a/src/test/codegen/sanitizer_memtag_attr_check.rs b/src/test/codegen/sanitizer_memtag_attr_check.rs
new file mode 100644
index 00000000000..2fd362656d4
--- /dev/null
+++ b/src/test/codegen/sanitizer_memtag_attr_check.rs
@@ -0,0 +1,12 @@
+// This tests that the sanitize_memtag attribute is
+// applied when enabling the memtag sanitizer.
+//
+// needs-sanitizer-memtag
+// compile-flags: -Zsanitizer=memtag -Ctarget-feature=+mte
+
+#![crate_type = "lib"]
+
+// CHECK: ; Function Attrs:{{.*}}sanitize_memtag
+pub fn tagged() {}
+
+// CHECK: attributes #0 = {{.*}}sanitize_memtag
diff --git a/src/test/debuginfo/unsized.rs b/src/test/debuginfo/unsized.rs
index ebd40f9dda2..7ccc88ef940 100644
--- a/src/test/debuginfo/unsized.rs
+++ b/src/test/debuginfo/unsized.rs
@@ -16,6 +16,14 @@
 // gdbg-check:$3 = {pointer = [...], vtable = [...]}
 // gdbr-check:$3 = &unsized::Foo<dyn core::fmt::Debug> {pointer: [...], vtable: [...]}
 
+// gdb-command:print tuple_slice
+// gdbg-check:$4 = {data_ptr = [...], length = 2}
+// gdbr-check:$4 = &(i32, i32, [i32]) {data_ptr: [...], length: 2}
+
+// gdb-command:print tuple_dyn
+// gdbg-check:$5 = {pointer = [...], vtable = [...]}
+// gdbr-check:$5 = &(i32, i32, dyn core::fmt::Debug) {pointer: [...], vtable: [...]}
+
 // === CDB TESTS ===================================================================================
 
 // cdb-command: g
@@ -34,6 +42,17 @@
 // cdb-check:    [+0x000] pointer          : 0x[...] [Type: unsized::Foo<dyn$<core::fmt::Debug> > *]
 // cdb-check:    [...] vtable           : 0x[...] [Type: unsigned [...]int[...] (*)[3]]
 
+// cdb-command:dx tuple_slice
+// cdb-check:tuple_slice      [Type: ref$<tuple$<i32,i32,slice$<i32> > >]
+// cdb-check:    [+0x000] data_ptr         : 0x[...] [Type: tuple$<i32,i32,slice$<i32> > *]
+// cdb-check:    [...] length           : 0x2 [Type: unsigned [...]int[...]
+
+// cdb-command:dx tuple_dyn
+// cdb-check:tuple_dyn        [Type: ref$<tuple$<i32,i32,dyn$<core::fmt::Debug> > >]
+// cdb-check:    [+0x000] pointer          : 0x[...] [Type: tuple$<i32,i32,dyn$<core::fmt::Debug> > *]
+// cdb-check:    [...] vtable           : 0x[...] [Type: unsigned [...]int[...] (*)[3]]
+
+#![feature(unsized_tuple_coercion)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -51,6 +70,10 @@ fn main() {
     let b: &Foo<Foo<[u8]>> = &foo;
     let c: &Foo<dyn std::fmt::Debug> = &Foo { value: 7i32 };
 
+    // Also check unsized tuples
+    let tuple_slice: &(i32, i32, [i32]) = &(0, 1, [2, 3]);
+    let tuple_dyn: &(i32, i32, dyn std::fmt::Debug) = &(0, 1, &3u64);
+
     zzz(); // #break
 }
 
diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs
index 9172d08eff9..fd294b018af 100644
--- a/src/test/run-make-fulldeps/issue-19371/foo.rs
+++ b/src/test/run-make-fulldeps/issue-19371/foo.rs
@@ -49,6 +49,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
     let config = interface::Config {
         opts,
         crate_cfg: Default::default(),
+        crate_check_cfg: Default::default(),
         input,
         input_path: None,
         output_file: Some(output),
diff --git a/src/test/run-make-fulldeps/libs-and-bins/Makefile b/src/test/run-make-fulldeps/libs-and-bins/Makefile
deleted file mode 100644
index cc3b257a5c5..00000000000
--- a/src/test/run-make-fulldeps/libs-and-bins/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
--include ../tools.mk
-
-all:
-	$(RUSTC) foo.rs
-	$(call RUN,foo)
-	rm $(TMPDIR)/$(call DYLIB_GLOB,foo)
diff --git a/src/test/run-make-fulldeps/libs-and-bins/foo.rs b/src/test/run-make-fulldeps/libs-and-bins/foo.rs
deleted file mode 100644
index ae166b17840..00000000000
--- a/src/test/run-make-fulldeps/libs-and-bins/foo.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-#![crate_type = "dylib"]
-#![crate_type = "bin"]
-
-fn main() {}
diff --git a/src/test/run-make-fulldeps/output-with-hyphens/Makefile b/src/test/run-make-fulldeps/output-with-hyphens/Makefile
index 783d826a53d..69a286f0b74 100644
--- a/src/test/run-make-fulldeps/output-with-hyphens/Makefile
+++ b/src/test/run-make-fulldeps/output-with-hyphens/Makefile
@@ -1,6 +1,7 @@
 -include ../tools.mk
 
 all:
-	$(RUSTC) foo-bar.rs
+	$(RUSTC) foo-bar.rs --crate-type bin
 	[ -f $(TMPDIR)/$(call BIN,foo-bar) ]
+	$(RUSTC) foo-bar.rs --crate-type lib
 	[ -f $(TMPDIR)/libfoo_bar.rlib ]
diff --git a/src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs b/src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs
index 3f1a70458e3..f328e4d9d04 100644
--- a/src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs
+++ b/src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs
@@ -1,4 +1 @@
-#![crate_type = "lib"]
-#![crate_type = "bin"]
-
 fn main() {}
diff --git a/src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk b/src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk
index 1fa1fae1a0b..d49b6c1f290 100644
--- a/src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk
+++ b/src/test/run-make/rustdoc-scrape-examples-multiple/scrape.mk
@@ -7,7 +7,8 @@ $(TMPDIR)/%.calls: $(TMPDIR)/libfoobar.rmeta
 	  --extern foobar=$(TMPDIR)/libfoobar.rmeta \
 		-Z unstable-options \
 		--scrape-examples-output-path $@ \
-		--scrape-examples-target-crate foobar
+		--scrape-examples-target-crate foobar \
+		$(extra_flags)
 
 $(TMPDIR)/lib%.rmeta: src/lib.rs
 	$(RUSTC) src/lib.rs --crate-name $* --crate-type lib --emit=metadata
diff --git a/src/test/run-make/rustdoc-scrape-examples-test/Makefile b/src/test/run-make/rustdoc-scrape-examples-test/Makefile
new file mode 100644
index 00000000000..9f80a8d9602
--- /dev/null
+++ b/src/test/run-make/rustdoc-scrape-examples-test/Makefile
@@ -0,0 +1,6 @@
+extra_flags := --scrape-tests
+deps := ex
+
+-include ../rustdoc-scrape-examples-multiple/scrape.mk
+
+all: scrape
diff --git a/src/test/run-make/rustdoc-scrape-examples-test/examples/ex.rs b/src/test/run-make/rustdoc-scrape-examples-test/examples/ex.rs
new file mode 100644
index 00000000000..d1a9a74e782
--- /dev/null
+++ b/src/test/run-make/rustdoc-scrape-examples-test/examples/ex.rs
@@ -0,0 +1,6 @@
+fn main() {}
+
+#[test]
+fn a_test() {
+  foobar::ok();
+}
diff --git a/src/test/run-make/rustdoc-scrape-examples-test/src/lib.rs b/src/test/run-make/rustdoc-scrape-examples-test/src/lib.rs
new file mode 100644
index 00000000000..22be1ad4101
--- /dev/null
+++ b/src/test/run-make/rustdoc-scrape-examples-test/src/lib.rs
@@ -0,0 +1,3 @@
+// @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]' ''
+
+pub fn ok() {}
diff --git a/src/test/rustdoc-gui/hash-item-expansion.goml b/src/test/rustdoc-gui/hash-item-expansion.goml
index 2885978ce1f..a680635ef8a 100644
--- a/src/test/rustdoc-gui/hash-item-expansion.goml
+++ b/src/test/rustdoc-gui/hash-item-expansion.goml
@@ -5,7 +5,7 @@ assert-attribute: ("#blanket-implementations-list > details:nth-child(2)", {"ope
 // We first check that the impl block is open by default.
 assert-attribute: ("#implementations + details", {"open": ""})
 // To ensure that we will click on the currently hidden method.
-assert-text: (".sidebar-links > a", "must_use")
-click: ".sidebar-links > a"
+assert-text: (".sidebar-elems section .block li > a", "must_use")
+click: ".sidebar-elems section .block li > a"
 // We check that the impl block was opened as expected so that we can see the method.
 assert-attribute: ("#implementations + details", {"open": ""})
diff --git a/src/test/rustdoc-gui/sidebar-mobile.goml b/src/test/rustdoc-gui/sidebar-mobile.goml
index 9581aa74b0f..79f18db8fc7 100644
--- a/src/test/rustdoc-gui/sidebar-mobile.goml
+++ b/src/test/rustdoc-gui/sidebar-mobile.goml
@@ -33,7 +33,7 @@ assert-property: (".mobile-topbar", {"clientHeight": "45"})
 // Check that clicking an element from the sidebar scrolls to the right place
 // so the target is not obscured by the topbar.
 click: ".sidebar-menu-toggle"
-click: ".sidebar-links a"
+click: ".sidebar-elems section .block li > a"
 assert-position: ("#method\.must_use", {"y": 45})
 
 // Check that the bottom-most item on the sidebar menu can be scrolled fully into view.
diff --git a/src/test/rustdoc-gui/sidebar.goml b/src/test/rustdoc-gui/sidebar.goml
index 9505e00512f..6b79b00d3f7 100644
--- a/src/test/rustdoc-gui/sidebar.goml
+++ b/src/test/rustdoc-gui/sidebar.goml
@@ -13,15 +13,15 @@ assert-css: ("#all-types", {"color": "rgb(53, 109, 164)"})
 // We check that we have the crates list and that the "current" on is "test_docs".
 assert-text: (".sidebar-elems .crate > ul > li > a.current", "test_docs")
 // And we're also supposed to have the list of items in the current module.
-assert-text: (".sidebar-elems .items > ul > li:nth-child(1)", "Modules")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(2)", "Macros")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(3)", "Structs")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(4)", "Enums")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(5)", "Traits")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(6)", "Functions")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(7)", "Type Definitions")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(8)", "Unions")
-assert-text: (".sidebar-elems .items > ul > li:nth-child(9)", "Keywords")
+assert-text: (".sidebar-elems section ul > li:nth-child(1)", "Modules")
+assert-text: (".sidebar-elems section ul > li:nth-child(2)", "Macros")
+assert-text: (".sidebar-elems section ul > li:nth-child(3)", "Structs")
+assert-text: (".sidebar-elems section ul > li:nth-child(4)", "Enums")
+assert-text: (".sidebar-elems section ul > li:nth-child(5)", "Traits")
+assert-text: (".sidebar-elems section ul > li:nth-child(6)", "Functions")
+assert-text: (".sidebar-elems section ul > li:nth-child(7)", "Type Definitions")
+assert-text: (".sidebar-elems section ul > li:nth-child(8)", "Unions")
+assert-text: (".sidebar-elems section ul > li:nth-child(9)", "Keywords")
 assert-text: ("#structs + .item-table .item-left > a", "Foo")
 click: "#structs + .item-table .item-left > a"
 
@@ -30,7 +30,7 @@ assert-count: (".sidebar .location", 2)
 // We check that there is no crate listed outside of the top level.
 assert-false: ".sidebar-elems > .crate"
 
-click: ".sidebar-links a"
+click: ".sidebar-elems section .block li > a"
 assert-property-false: ("html", {"scrollTop": "0"})
 
 click: ".sidebar h2.location a"
@@ -47,11 +47,11 @@ assert-text: (".sidebar > .location", "Crate lib2")
 // We check that we have the crates list and that the "current" on is now "lib2".
 assert-text: (".sidebar-elems .crate > ul > li > a.current", "lib2")
 // We now go to the "foobar" function page.
-assert-text: (".sidebar-elems > .items > ul > li:nth-child(1)", "Modules")
-assert-text: (".sidebar-elems > .items > ul > li:nth-child(2)", "Structs")
-assert-text: (".sidebar-elems > .items > ul > li:nth-child(3)", "Traits")
-assert-text: (".sidebar-elems > .items > ul > li:nth-child(4)", "Functions")
-assert-text: (".sidebar-elems > .items > ul > li:nth-child(5)", "Type Definitions")
+assert-text: (".sidebar-elems > section .block ul > li:nth-child(1)", "Modules")
+assert-text: (".sidebar-elems > section .block ul > li:nth-child(2)", "Structs")
+assert-text: (".sidebar-elems > section .block ul > li:nth-child(3)", "Traits")
+assert-text: (".sidebar-elems > section .block ul > li:nth-child(4)", "Functions")
+assert-text: (".sidebar-elems > section .block ul > li:nth-child(5)", "Type Definitions")
 assert-text: ("#functions + .item-table .item-left > a", "foobar")
 click: "#functions + .item-table .item-left > a"
 
@@ -72,12 +72,12 @@ goto: ./sub_module/sub_sub_module/index.html
 assert-text: (".sidebar > .location", "Module sub_sub_module")
 // We check that we don't have the crate list.
 assert-false: ".sidebar-elems .crate"
-assert-text: (".sidebar-elems .items > ul > li:nth-child(1)", "Functions")
+assert-text: (".sidebar-elems > section ul > li:nth-child(1)", "Functions")
 assert-text: ("#functions + .item-table .item-left > a", "foo")
 
 // Links to trait implementations in the sidebar should not wrap even if they are long.
 goto: file://|DOC_PATH|/lib2/struct.HasALongTraitWithParams.html
-assert-property: (".sidebar-links a", {"offsetHeight": 29})
+assert-property: (".sidebar-elems section .block li > a", {"offsetHeight": 29})
 
 // Test that clicking on of the "In <module>" headings in the sidebar links to the
 // appropriate anchor in index.html.
diff --git a/src/test/rustdoc-gui/trait-sidebar-item-order.goml b/src/test/rustdoc-gui/trait-sidebar-item-order.goml
index 38942baa0b5..d77d1dca483 100644
--- a/src/test/rustdoc-gui/trait-sidebar-item-order.goml
+++ b/src/test/rustdoc-gui/trait-sidebar-item-order.goml
@@ -1,8 +1,8 @@
 // Checks that the elements in the sidebar are alphabetically sorted.
 goto: file://|DOC_PATH|/test_docs/trait.AnotherOne.html
-assert-text: (".sidebar-links a:nth-of-type(1)", "another")
-assert-text: (".sidebar-links a:nth-of-type(2)", "func1")
-assert-text: (".sidebar-links a:nth-of-type(3)", "func2")
-assert-text: (".sidebar-links a:nth-of-type(4)", "func3")
-assert-text: (".sidebar-links a:nth-of-type(5)", "hello")
-assert-text: (".sidebar-links a:nth-of-type(6)", "why_not")
+assert-text: (".sidebar-elems section .block li:nth-of-type(1) > a", "another")
+assert-text: (".sidebar-elems section .block li:nth-of-type(2) > a", "func1")
+assert-text: (".sidebar-elems section .block li:nth-of-type(3) > a", "func2")
+assert-text: (".sidebar-elems section .block li:nth-of-type(4) > a", "func3")
+assert-text: (".sidebar-elems section .block li:nth-of-type(5) > a", "hello")
+assert-text: (".sidebar-elems section .block li:nth-of-type(6) > a", "why_not")
diff --git a/src/test/rustdoc/associated-consts.rs b/src/test/rustdoc/associated-consts.rs
index 6ae5e20632e..da50fb86cd5 100644
--- a/src/test/rustdoc/associated-consts.rs
+++ b/src/test/rustdoc/associated-consts.rs
@@ -10,7 +10,7 @@ pub struct Bar;
 
 // @has 'foo/struct.Bar.html'
 // @has - '//h3[@class="sidebar-title"]' 'Associated Constants'
-// @has - '//div[@class="sidebar-elems"]//div[@class="sidebar-links"]/a' 'FOO'
+// @has - '//div[@class="sidebar-elems"]//a' 'FOO'
 impl Trait for Bar {
     const FOO: u32 = 1;
 
@@ -23,7 +23,7 @@ pub enum Foo {
 
 // @has 'foo/enum.Foo.html'
 // @has - '//h3[@class="sidebar-title"]' 'Associated Constants'
-// @has - '//div[@class="sidebar-elems"]//div[@class="sidebar-links"]/a' 'FOO'
+// @has - '//div[@class="sidebar-elems"]//a' 'FOO'
 impl Trait for Foo {
     const FOO: u32 = 1;
 
diff --git a/src/test/rustdoc/deref-mut-methods.rs b/src/test/rustdoc/deref-mut-methods.rs
index 0e27fc90b69..fdf8434224f 100644
--- a/src/test/rustdoc/deref-mut-methods.rs
+++ b/src/test/rustdoc/deref-mut-methods.rs
@@ -9,7 +9,7 @@ impl Foo {
 }
 
 // @has foo/struct.Bar.html
-// @has - '//div[@class="sidebar-links"]/a[@href="#method.foo"]' 'foo'
+// @has - '//*[@class="sidebar-elems"]//*[@class="block"]//a[@href="#method.foo"]' 'foo'
 pub struct Bar {
     foo: Foo,
 }
diff --git a/src/test/rustdoc/deref-recursive-pathbuf.rs b/src/test/rustdoc/deref-recursive-pathbuf.rs
index 9ab338ca9b1..746df9c804e 100644
--- a/src/test/rustdoc/deref-recursive-pathbuf.rs
+++ b/src/test/rustdoc/deref-recursive-pathbuf.rs
@@ -8,9 +8,9 @@
 // @has '-' '//*[@id="deref-methods-Path"]' 'Methods from Deref<Target = Path>'
 // @has '-' '//*[@class="impl-items"]//*[@id="method.exists"]' 'pub fn exists(&self)'
 // @has '-' '//*[@class="sidebar-title"]/a[@href="#deref-methods-PathBuf"]' 'Methods from Deref<Target=PathBuf>'
-// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.as_path"]' 'as_path'
+// @has '-' '//*[@class="sidebar-elems"]//*[@class="block"]//a[@href="#method.as_path"]' 'as_path'
 // @has '-' '//*[@class="sidebar-title"]/a[@href="#deref-methods-Path"]' 'Methods from Deref<Target=Path>'
-// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.exists"]' 'exists'
+// @has '-' '//*[@class="sidebar-elems"]//*[@class="block"]//a[@href="#method.exists"]' 'exists'
 
 #![crate_name = "foo"]
 
diff --git a/src/test/rustdoc/deref-recursive.rs b/src/test/rustdoc/deref-recursive.rs
index c07e048b065..d5f8473f284 100644
--- a/src/test/rustdoc/deref-recursive.rs
+++ b/src/test/rustdoc/deref-recursive.rs
@@ -8,9 +8,9 @@
 // @has '-' '//*[@id="deref-methods-Baz"]' 'Methods from Deref<Target = Baz>'
 // @has '-' '//*[@class="impl-items"]//*[@id="method.baz"]' 'pub fn baz(&self)'
 // @has '-' '//*[@class="sidebar-title"]/a[@href="#deref-methods-Bar"]' 'Methods from Deref<Target=Bar>'
-// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.bar"]' 'bar'
+// @has '-' '//*[@class="sidebar-elems"]//section//a[@href="#method.bar"]' 'bar'
 // @has '-' '//*[@class="sidebar-title"]/a[@href="#deref-methods-Baz"]' 'Methods from Deref<Target=Baz>'
-// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.baz"]' 'baz'
+// @has '-' '//*[@class="sidebar-elems"]//section//a[@href="#method.baz"]' 'baz'
 
 #![crate_name = "foo"]
 
diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs
index ad7a96c5dad..28f977e315a 100644
--- a/src/test/rustdoc/deref-typedef.rs
+++ b/src/test/rustdoc/deref-typedef.rs
@@ -7,10 +7,10 @@
 // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)'
 // @has '-' '//*[@class="impl-items"]//*[@id="method.foo_j"]' 'pub fn foo_j(&self)'
 // @has '-' '//*[@class="sidebar-title"]/a[@href="#deref-methods-FooJ"]' 'Methods from Deref<Target=FooJ>'
-// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a'
-// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b'
-// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c'
-// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_j"]' 'foo_j'
+// @has '-' '//*[@class="sidebar-elems"]//section//a[@href="#method.foo_a"]' 'foo_a'
+// @has '-' '//*[@class="sidebar-elems"]//section//a[@href="#method.foo_b"]' 'foo_b'
+// @has '-' '//*[@class="sidebar-elems"]//section//a[@href="#method.foo_c"]' 'foo_c'
+// @has '-' '//*[@class="sidebar-elems"]//section//a[@href="#method.foo_j"]' 'foo_j'
 
 pub struct FooA;
 pub type FooB = FooA;
diff --git a/src/test/rustdoc/double-quote-escape.rs b/src/test/rustdoc/double-quote-escape.rs
index 546af2c121a..b7bbf140cfd 100644
--- a/src/test/rustdoc/double-quote-escape.rs
+++ b/src/test/rustdoc/double-quote-escape.rs
@@ -8,5 +8,5 @@ pub trait Foo<T> {
 pub struct Bar;
 
 // @has foo/struct.Bar.html
-// @has - '//*[@class="sidebar-links"]/a[@href="#impl-Foo%3Cunsafe%20extern%20%22C%22%20fn()%3E"]' 'Foo<unsafe extern "C" fn()>'
+// @has - '//*[@class="sidebar-elems"]//section//a[@href="#impl-Foo%3Cunsafe%20extern%20%22C%22%20fn()%3E"]' 'Foo<unsafe extern "C" fn()>'
 impl Foo<unsafe extern "C" fn()> for Bar {}
diff --git a/src/test/rustdoc/generic-impl.rs b/src/test/rustdoc/generic-impl.rs
index 0f6cba93f95..1268c9587f8 100644
--- a/src/test/rustdoc/generic-impl.rs
+++ b/src/test/rustdoc/generic-impl.rs
@@ -7,7 +7,7 @@ pub struct Bar;
 
 // @has foo/struct.Foo.html '//*[@id="impl-ToString"]//h3[@class="code-header in-band"]' 'impl<T> ToString for T'
 pub struct Foo;
-// @has foo/struct.Foo.html '//div[@class="sidebar-links"]/a[@href="#impl-ToString"]' 'ToString'
+// @has foo/struct.Foo.html '//*[@class="sidebar-elems"]//section//a[@href="#impl-ToString"]' 'ToString'
 
 impl fmt::Display for Foo {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/src/test/rustdoc/intra-doc/auxiliary/extern-lang-item-impl-dep.rs b/src/test/rustdoc/intra-doc/auxiliary/extern-lang-item-impl-dep.rs
new file mode 100644
index 00000000000..87ae2f096bb
--- /dev/null
+++ b/src/test/rustdoc/intra-doc/auxiliary/extern-lang-item-impl-dep.rs
@@ -0,0 +1,29 @@
+// no-prefer-dynamic
+
+#![feature(lang_items)]
+
+#![crate_type = "rlib"]
+#![no_std]
+
+pub struct DerefsToF64(f64);
+
+impl core::ops::Deref for DerefsToF64 {
+    type Target = f64;
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+mod inner {
+    #[lang = "f64_runtime"]
+    impl f64 {
+        /// [f64::clone]
+        pub fn method() {}
+    }
+}
+
+#[lang = "eh_personality"]
+fn foo() {}
+
+#[panic_handler]
+fn bar(_: &core::panic::PanicInfo) -> ! { loop {} }
diff --git a/src/test/rustdoc/intra-doc/extern-lang-item-impl.rs b/src/test/rustdoc/intra-doc/extern-lang-item-impl.rs
new file mode 100644
index 00000000000..f64f886f076
--- /dev/null
+++ b/src/test/rustdoc/intra-doc/extern-lang-item-impl.rs
@@ -0,0 +1,11 @@
+// Reexport of a structure that derefs to a type with lang item impls having doc links in their
+// comments. The doc link points to an associated item, so we check that traits in scope for that
+// link are populated.
+
+// aux-build:extern-lang-item-impl-dep.rs
+
+#![no_std]
+
+extern crate extern_lang_item_impl_dep;
+
+pub use extern_lang_item_impl_dep::DerefsToF64;
diff --git a/src/test/rustdoc/method-list.rs b/src/test/rustdoc/method-list.rs
index 9f24e817fd3..50f4af3aaaf 100644
--- a/src/test/rustdoc/method-list.rs
+++ b/src/test/rustdoc/method-list.rs
@@ -1,8 +1,8 @@
 #![crate_name = "foo"]
 
 // @has foo/struct.Foo.html
-// @has - '//*[@class="sidebar-links"]/a' 'super_long_name'
-// @has - '//*[@class="sidebar-links"]/a' 'Disp'
+// @has - '//*[@class="sidebar-elems"]//section//a' 'super_long_name'
+// @has - '//*[@class="sidebar-elems"]//section//a' 'Disp'
 pub struct Foo(usize);
 
 impl Foo {
diff --git a/src/test/rustdoc/negative-impl-sidebar.rs b/src/test/rustdoc/negative-impl-sidebar.rs
index d63ab346045..b995fff1f9a 100644
--- a/src/test/rustdoc/negative-impl-sidebar.rs
+++ b/src/test/rustdoc/negative-impl-sidebar.rs
@@ -5,5 +5,5 @@ pub struct Foo;
 
 // @has foo/struct.Foo.html
 // @has - '//*[@class="sidebar-title"]/a[@href="#trait-implementations"]' 'Trait Implementations'
-// @has - '//*[@class="sidebar-links"]/a' '!Sync'
+// @has - '//*[@class="sidebar-elems"]//section//a' '!Sync'
 impl !Sync for Foo {}
diff --git a/src/test/rustdoc/recursive-deref-sidebar.rs b/src/test/rustdoc/recursive-deref-sidebar.rs
index 65a7debc253..619f40eff89 100644
--- a/src/test/rustdoc/recursive-deref-sidebar.rs
+++ b/src/test/rustdoc/recursive-deref-sidebar.rs
@@ -9,13 +9,13 @@ impl B { pub fn foo_b(&self) {} }
 pub struct C {}
 impl C { pub fn foo_c(&self) {} }
 
-// @has recursive_deref_sidebar/struct.A.html '//div[@class="sidebar-links"]' 'foo_b'
+// @has recursive_deref_sidebar/struct.A.html '//*[@class="sidebar-elems"]//section' 'foo_b'
 impl Deref for A {
     type Target = B;
     fn deref(&self) -> &B { todo!() }
 }
 
-// @has recursive_deref_sidebar/struct.A.html '//div[@class="sidebar-links"]' 'foo_c'
+// @has recursive_deref_sidebar/struct.A.html '//*[@class="sidebar-elems"]//section' 'foo_c'
 impl Deref for B {
     type Target = C;
     fn deref(&self) -> &C { todo!() }
diff --git a/src/test/rustdoc/sidebar-items.rs b/src/test/rustdoc/sidebar-items.rs
index ee670e88b5c..375cad9da7f 100644
--- a/src/test/rustdoc/sidebar-items.rs
+++ b/src/test/rustdoc/sidebar-items.rs
@@ -2,13 +2,13 @@
 
 // @has foo/trait.Foo.html
 // @has - '//*[@class="sidebar-title"]/a[@href="#required-methods"]' 'Required Methods'
-// @has - '//*[@class="sidebar-links"]/a' 'bar'
+// @has - '//*[@class="sidebar-elems"]//section//a' 'bar'
 // @has - '//*[@class="sidebar-title"]/a[@href="#provided-methods"]' 'Provided Methods'
-// @has - '//*[@class="sidebar-links"]/a' 'foo'
+// @has - '//*[@class="sidebar-elems"]//section//a' 'foo'
 // @has - '//*[@class="sidebar-title"]/a[@href="#associated-const"]' 'Associated Constants'
-// @has - '//*[@class="sidebar-links"]/a' 'BAR'
+// @has - '//*[@class="sidebar-elems"]//section//a' 'BAR'
 // @has - '//*[@class="sidebar-title"]/a[@href="#associated-types"]' 'Associated Types'
-// @has - '//*[@class="sidebar-links"]/a' 'Output'
+// @has - '//*[@class="sidebar-elems"]//section//a' 'Output'
 pub trait Foo {
     const BAR: u32 = 0;
     type Output: ?Sized;
@@ -19,9 +19,9 @@ pub trait Foo {
 
 // @has foo/struct.Bar.html
 // @has - '//*[@class="sidebar-title"]/a[@href="#fields"]' 'Fields'
-// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f"]' 'f'
-// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.u"]' 'u'
-// @!has - '//*[@class="sidebar-links"]/a' 'waza'
+// @has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f"]' 'f'
+// @has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.u"]' 'u'
+// @!has - '//*[@class="sidebar-elems"]//section//a' 'waza'
 pub struct Bar {
     pub f: u32,
     pub u: u32,
@@ -30,8 +30,8 @@ pub struct Bar {
 
 // @has foo/enum.En.html
 // @has - '//*[@class="sidebar-title"]/a[@href="#variants"]' 'Variants'
-// @has - '//*[@class="sidebar-links"]/a' 'Foo'
-// @has - '//*[@class="sidebar-links"]/a' 'Bar'
+// @has - '//*[@class="sidebar-elems"]//section//a' 'Foo'
+// @has - '//*[@class="sidebar-elems"]//section//a' 'Bar'
 pub enum En {
     Foo,
     Bar,
@@ -39,9 +39,9 @@ pub enum En {
 
 // @has foo/union.MyUnion.html
 // @has - '//*[@class="sidebar-title"]/a[@href="#fields"]' 'Fields'
-// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f1"]' 'f1'
-// @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f2"]' 'f2'
-// @!has - '//*[@class="sidebar-links"]/a' 'waza'
+// @has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f1"]' 'f1'
+// @has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f2"]' 'f2'
+// @!has - '//*[@class="sidebar-elems"]//section//a' 'waza'
 pub union MyUnion {
     pub f1: u32,
     pub f2: f32,
diff --git a/src/test/rustdoc/sidebar-link-generation.rs b/src/test/rustdoc/sidebar-link-generation.rs
index 76b77b9bcbb..7858f35a261 100644
--- a/src/test/rustdoc/sidebar-link-generation.rs
+++ b/src/test/rustdoc/sidebar-link-generation.rs
@@ -1,6 +1,6 @@
 #![crate_name = "foo"]
 
-// @has foo/struct.SomeStruct.html '//*[@class="sidebar-links"]/a[@href="#method.some_fn-1"]' \
+// @has foo/struct.SomeStruct.html '//*[@class="sidebar-elems"]//section//li/a[@href="#method.some_fn-1"]' \
 //          "some_fn"
 pub struct SomeStruct<T> { _inner: T }
 
diff --git a/src/test/rustdoc/sidebar-links-to-foreign-impl.rs b/src/test/rustdoc/sidebar-links-to-foreign-impl.rs
index 63e486b8834..15515039659 100644
--- a/src/test/rustdoc/sidebar-links-to-foreign-impl.rs
+++ b/src/test/rustdoc/sidebar-links-to-foreign-impl.rs
@@ -5,9 +5,9 @@
 // @has foo/trait.Foo.html
 // @has - '//*[@class="sidebar-title"]/a[@href="#foreign-impls"]' 'Implementations on Foreign Types'
 // @has - '//h2[@id="foreign-impls"]' 'Implementations on Foreign Types'
-// @has - '//*[@class="sidebar-links"]/a[@href="#impl-Foo-for-u32"]' 'u32'
+// @has - '//*[@class="sidebar-elems"]//section//a[@href="#impl-Foo-for-u32"]' 'u32'
 // @has - '//*[@id="impl-Foo-for-u32"]//h3[@class="code-header in-band"]' 'impl Foo for u32'
-// @has - '//*[@class="sidebar-links"]/a[@href="#impl-Foo-for-%26%27a%20str"]' "&'a str"
+// @has - '//*[@class="sidebar-elems"]//section//a[@href="#impl-Foo-for-%26%27a%20str"]' "&'a str"
 // @has - '//*[@id="impl-Foo-for-%26%27a%20str"]//h3[@class="code-header in-band"]' "impl<'a> Foo for &'a str"
 pub trait Foo {}
 
diff --git a/src/test/ui/async-await/issue-61949-self-return-type.rs b/src/test/ui/async-await/issue-61949-self-return-type.rs
index 42133d51041..43429ba2329 100644
--- a/src/test/ui/async-await/issue-61949-self-return-type.rs
+++ b/src/test/ui/async-await/issue-61949-self-return-type.rs
@@ -8,6 +8,7 @@ pub struct Foo<'a> {
 
 impl<'a> Foo<'a> {
     pub async fn new(_bar: &'a i32) -> Self {
+    //~^ ERROR `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
         Foo {
             bar: &22
         }
@@ -18,7 +19,6 @@ async fn foo() {
     let x = {
         let bar = 22;
         Foo::new(&bar).await
-        //~^ ERROR `bar` does not live long enough [E0597]
     };
     drop(x);
 }
diff --git a/src/test/ui/async-await/issue-61949-self-return-type.stderr b/src/test/ui/async-await/issue-61949-self-return-type.stderr
index f86844e1a9c..52b726e186e 100644
--- a/src/test/ui/async-await/issue-61949-self-return-type.stderr
+++ b/src/test/ui/async-await/issue-61949-self-return-type.stderr
@@ -1,15 +1,9 @@
-error[E0597]: `bar` does not live long enough
-  --> $DIR/issue-61949-self-return-type.rs:20:18
+error[E0760]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+  --> $DIR/issue-61949-self-return-type.rs:10:40
    |
-LL |     let x = {
-   |         - borrow later stored here
-LL |         let bar = 22;
-LL |         Foo::new(&bar).await
-   |                  ^^^^ borrowed value does not live long enough
-LL |
-LL |     };
-   |     - `bar` dropped here while still borrowed
+LL |     pub async fn new(_bar: &'a i32) -> Self {
+   |                                        ^^^^ help: consider spelling out the type instead: `Foo<'a>`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0597`.
+For more information about this error, try `rustc --explain E0760`.
diff --git a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr
index 80504613eb4..b96cab9f0f5 100644
--- a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr
+++ b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr
@@ -1,10 +1,14 @@
 error[E0506]: cannot assign to `*x` because it is borrowed
   --> $DIR/issue-74072-lifetime-name-annotations.rs:9:5
    |
+LL | pub async fn async_fn(x: &mut i32) -> &i32 {
+   |                          - let's call the lifetime of this reference `'1`
 LL |     let y = &*x;
    |             --- borrow of `*x` occurs here
 LL |     *x += 1;
    |     ^^^^^^^ assignment to borrowed `*x` occurs here
+LL |     y
+   |     - returning this value requires that `*x` is borrowed for `'1`
 
 error[E0506]: cannot assign to `*x` because it is borrowed
   --> $DIR/issue-74072-lifetime-name-annotations.rs:16:9
diff --git a/src/test/ui/async-await/issue-75785-confusing-named-region.stderr b/src/test/ui/async-await/issue-75785-confusing-named-region.stderr
index 06660b7c182..3b731d9c60a 100644
--- a/src/test/ui/async-await/issue-75785-confusing-named-region.stderr
+++ b/src/test/ui/async-await/issue-75785-confusing-named-region.stderr
@@ -1,10 +1,14 @@
 error[E0506]: cannot assign to `*x` because it is borrowed
   --> $DIR/issue-75785-confusing-named-region.rs:9:5
    |
+LL | pub async fn async_fn(x: &mut i32) -> (&i32, &i32) {
+   |                          - let's call the lifetime of this reference `'1`
 LL |     let y = &*x;
    |             --- borrow of `*x` occurs here
 LL |     *x += 1;
    |     ^^^^^^^ assignment to borrowed `*x` occurs here
+LL |     (&32, y)
+   |     -------- returning this value requires that `*x` is borrowed for `'1`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/issues/issue-63388-1.stderr b/src/test/ui/async-await/issues/issue-63388-1.stderr
index ee270d36979..8f602a1492a 100644
--- a/src/test/ui/async-await/issues/issue-63388-1.stderr
+++ b/src/test/ui/async-await/issues/issue-63388-1.stderr
@@ -2,10 +2,12 @@ error[E0623]: lifetime mismatch
   --> $DIR/issue-63388-1.rs:14:9
    |
 LL |         &'a self, foo: &dyn Foo
-   |         --------       -------- these two types are declared with different lifetimes...
-...
+   |                        -------- this parameter and the return type are declared with different lifetimes...
+LL |     ) -> &dyn Foo
+   |          --------
+LL |     {
 LL |         foo
-   |         ^^^ ...but data from `foo` flows into `self` here
+   |         ^^^ ...but data from `foo` is returned here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/issues/issue-78600.rs b/src/test/ui/async-await/issues/issue-78600.rs
index 4303fc7952f..8aaeaecf3e1 100644
--- a/src/test/ui/async-await/issues/issue-78600.rs
+++ b/src/test/ui/async-await/issues/issue-78600.rs
@@ -1,10 +1,10 @@
-// check-pass
 // edition:2018
 
 struct S<'a>(&'a i32);
 
 impl<'a> S<'a> {
     async fn new(i: &'a i32) -> Result<Self, ()> {
+        //~^ ERROR: `async fn`
         Ok(S(&22))
     }
 }
diff --git a/src/test/ui/async-await/issues/issue-78600.stderr b/src/test/ui/async-await/issues/issue-78600.stderr
new file mode 100644
index 00000000000..92b66147106
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-78600.stderr
@@ -0,0 +1,11 @@
+error[E0760]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+  --> $DIR/issue-78600.rs:6:33
+   |
+LL |     async fn new(i: &'a i32) -> Result<Self, ()> {
+   |                                 ^^^^^^^----^^^^^
+   |                                        |
+   |                                        help: consider spelling out the type instead: `S<'a>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0760`.
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
index b0ea6af0050..2722c72c20a 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
@@ -1,13 +1,15 @@
 error: lifetime may not live long enough
-  --> $DIR/ret-impl-trait-one.rs:12:5
+  --> $DIR/ret-impl-trait-one.rs:10:85
    |
-LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
-   |                                --  -- lifetime `'b` defined here
-   |                                |
-   |                                lifetime `'a` defined here
-LL |
-LL |     (a, b)
-   |     ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+LL |   async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
+   |  ________________________________--__--_______________________________________________^
+   | |                                |   |
+   | |                                |   lifetime `'b` defined here
+   | |                                lifetime `'a` defined here
+LL | |
+LL | |     (a, b)
+LL | | }
+   | |_^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
    |
    = help: consider adding the following bound: `'a: 'b`
 
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr
index 6f79d9e9b5f..149692a2c69 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr
@@ -2,9 +2,10 @@ error[E0623]: lifetime mismatch
   --> $DIR/ret-impl-trait-one.rs:10:65
    |
 LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
-   |                                           ------     ------     ^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here
-   |                                           |
-   |                                           these two types are declared with different lifetimes...
+   |                                                      ------     ^^^^^^^^^^^^^^^^^^^
+   |                                                      |          |
+   |                                                      |          ...but data from `a` is returned here
+   |                                                      this parameter and the return type are declared with different lifetimes...
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/ret-impl-trait-one.rs:16:65
diff --git a/src/test/ui/async-await/unused-lifetime.rs b/src/test/ui/async-await/unused-lifetime.rs
index a0504927254..5bd6ae8d3a4 100644
--- a/src/test/ui/async-await/unused-lifetime.rs
+++ b/src/test/ui/async-await/unused-lifetime.rs
@@ -10,13 +10,10 @@
 // Even wrong cases don't cause errors because async functions are desugared with all lifetimes
 // involved in the signature. So, we cannot predict what lifetimes are unused in async function.
 async fn async_wrong_without_args<'a>() {}
-//~^ ERROR lifetime parameter `'a` never used [unused_lifetimes]
 
 async fn async_wrong_1_lifetime<'a>(_: &i32) {}
-//~^ ERROR lifetime parameter `'a` never used [unused_lifetimes]
 
 async fn async_wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {}
-//~^ ERROR lifetime parameter `'b` never used [unused_lifetimes]
 
 async fn async_right_1_lifetime<'a>(_: &'a i32) {}
 
diff --git a/src/test/ui/async-await/unused-lifetime.stderr b/src/test/ui/async-await/unused-lifetime.stderr
index 85304b9cb9e..4e90f43fdd0 100644
--- a/src/test/ui/async-await/unused-lifetime.stderr
+++ b/src/test/ui/async-await/unused-lifetime.stderr
@@ -1,8 +1,8 @@
 error: lifetime parameter `'a` never used
-  --> $DIR/unused-lifetime.rs:12:35
+  --> $DIR/unused-lifetime.rs:31:23
    |
-LL | async fn async_wrong_without_args<'a>() {}
-   |                                  -^^- help: elide the unused lifetime
+LL | fn wrong_without_args<'a>() {}
+   |                      -^^- help: elide the unused lifetime
    |
 note: the lint level is defined here
   --> $DIR/unused-lifetime.rs:5:9
@@ -11,40 +11,18 @@ LL | #![deny(unused_lifetimes)]
    |         ^^^^^^^^^^^^^^^^
 
 error: lifetime parameter `'a` never used
-  --> $DIR/unused-lifetime.rs:15:33
-   |
-LL | async fn async_wrong_1_lifetime<'a>(_: &i32) {}
-   |                                 ^^-----
-   |                                 |
-   |                                 help: elide the unused lifetime
-
-error: lifetime parameter `'b` never used
-  --> $DIR/unused-lifetime.rs:18:38
-   |
-LL | async fn async_wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {}
-   |                                      ^^-----------------
-   |                                      |
-   |                                      help: elide the unused lifetime
-
-error: lifetime parameter `'a` never used
-  --> $DIR/unused-lifetime.rs:34:23
-   |
-LL | fn wrong_without_args<'a>() {}
-   |                      -^^- help: elide the unused lifetime
-
-error: lifetime parameter `'a` never used
-  --> $DIR/unused-lifetime.rs:36:21
+  --> $DIR/unused-lifetime.rs:33:21
    |
 LL | fn wrong_1_lifetime<'a>(_: &i32) {}
    |                    -^^- help: elide the unused lifetime
 
 error: lifetime parameter `'b` never used
-  --> $DIR/unused-lifetime.rs:38:26
+  --> $DIR/unused-lifetime.rs:35:26
    |
 LL | fn wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {}
    |                        --^^
    |                        |
    |                        help: elide the unused lifetime
 
-error: aborting due to 6 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/box/issue-78459-ice.rs b/src/test/ui/box/issue-78459-ice.rs
new file mode 100644
index 00000000000..89f75fea15b
--- /dev/null
+++ b/src/test/ui/box/issue-78459-ice.rs
@@ -0,0 +1,6 @@
+// check-pass
+#![feature(allocator_api)]
+
+fn main() {
+    Box::new_in((), &std::alloc::Global);
+}
diff --git a/src/test/ui/cfg/cfg-panic-abort.rs b/src/test/ui/cfg/cfg-panic-abort.rs
index 9b88eff12ed..3853b598a7a 100644
--- a/src/test/ui/cfg/cfg-panic-abort.rs
+++ b/src/test/ui/cfg/cfg-panic-abort.rs
@@ -1,7 +1,7 @@
 // build-pass
 // compile-flags: -C panic=abort
 // no-prefer-dynamic
-#![feature(cfg_panic)]
+
 
 #[cfg(panic = "unwind")]
 pub fn bad() -> i32 { }
diff --git a/src/test/ui/cfg/cfg-panic.rs b/src/test/ui/cfg/cfg-panic.rs
index d2113e4f5ec..fb3e5059c81 100644
--- a/src/test/ui/cfg/cfg-panic.rs
+++ b/src/test/ui/cfg/cfg-panic.rs
@@ -4,7 +4,7 @@
 // ignore-emscripten no panic_unwind implementation
 // ignore-wasm32     no panic_unwind implementation
 // ignore-wasm64     no panic_unwind implementation
-#![feature(cfg_panic)]
+
 
 #[cfg(panic = "abort")]
 pub fn bad() -> i32 { }
diff --git a/src/test/ui/check-cfg/empty-names.rs b/src/test/ui/check-cfg/empty-names.rs
new file mode 100644
index 00000000000..046ff0364e2
--- /dev/null
+++ b/src/test/ui/check-cfg/empty-names.rs
@@ -0,0 +1,10 @@
+// Check warning for unexpected cfg
+//
+// check-pass
+// compile-flags: --check-cfg=names() -Z unstable-options
+
+#[cfg(unknown_key = "value")]
+//~^ WARNING unexpected `cfg` condition name
+pub fn f() {}
+
+fn main() {}
diff --git a/src/test/ui/check-cfg/empty-names.stderr b/src/test/ui/check-cfg/empty-names.stderr
new file mode 100644
index 00000000000..f926d1133cc
--- /dev/null
+++ b/src/test/ui/check-cfg/empty-names.stderr
@@ -0,0 +1,10 @@
+warning: unexpected `cfg` condition name
+  --> $DIR/empty-names.rs:6:7
+   |
+LL | #[cfg(unknown_key = "value")]
+   |       ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/check-cfg/empty-values.rs b/src/test/ui/check-cfg/empty-values.rs
new file mode 100644
index 00000000000..38ef9e51c7a
--- /dev/null
+++ b/src/test/ui/check-cfg/empty-values.rs
@@ -0,0 +1,6 @@
+// Check that a an empty values() is rejected
+//
+// check-fail
+// compile-flags: --check-cfg=values() -Z unstable-options
+
+fn main() {}
diff --git a/src/test/ui/check-cfg/empty-values.stderr b/src/test/ui/check-cfg/empty-values.stderr
new file mode 100644
index 00000000000..106d5b7b47f
--- /dev/null
+++ b/src/test/ui/check-cfg/empty-values.stderr
@@ -0,0 +1,2 @@
+error: invalid `--check-cfg` argument: `values()` (expected `names(name1, name2, ... nameN)` or `values(name, "value1", "value2", ... "valueN")`)
+
diff --git a/src/test/ui/check-cfg/invalid-arguments.anything_else.stderr b/src/test/ui/check-cfg/invalid-arguments.anything_else.stderr
new file mode 100644
index 00000000000..850924d993a
--- /dev/null
+++ b/src/test/ui/check-cfg/invalid-arguments.anything_else.stderr
@@ -0,0 +1,2 @@
+error: invalid `--check-cfg` argument: `anything_else(...)` (expected `names(name1, name2, ... nameN)` or `values(name, "value1", "value2", ... "valueN")`)
+
diff --git a/src/test/ui/check-cfg/invalid-arguments.names_simple_ident.stderr b/src/test/ui/check-cfg/invalid-arguments.names_simple_ident.stderr
new file mode 100644
index 00000000000..bdfbc3d54a2
--- /dev/null
+++ b/src/test/ui/check-cfg/invalid-arguments.names_simple_ident.stderr
@@ -0,0 +1,2 @@
+error: invalid `--check-cfg` argument: `names("NOT_IDENT")` (`names()` arguments must be simple identifers)
+
diff --git a/src/test/ui/check-cfg/invalid-arguments.rs b/src/test/ui/check-cfg/invalid-arguments.rs
new file mode 100644
index 00000000000..5090ce3e845
--- /dev/null
+++ b/src/test/ui/check-cfg/invalid-arguments.rs
@@ -0,0 +1,10 @@
+// Check that invalid --check-cfg are rejected
+//
+// check-fail
+// revisions: anything_else names_simple_ident values_simple_ident values_string_literals
+// [anything_else]compile-flags: -Z unstable-options --check-cfg=anything_else(...)
+// [names_simple_ident]compile-flags: -Z unstable-options --check-cfg=names("NOT_IDENT")
+// [values_simple_ident]compile-flags: -Z unstable-options --check-cfg=values("NOT_IDENT")
+// [values_string_literals]compile-flags: -Z unstable-options --check-cfg=values(test,12)
+
+fn main() {}
diff --git a/src/test/ui/check-cfg/invalid-arguments.values_simple_ident.stderr b/src/test/ui/check-cfg/invalid-arguments.values_simple_ident.stderr
new file mode 100644
index 00000000000..b25882baaf3
--- /dev/null
+++ b/src/test/ui/check-cfg/invalid-arguments.values_simple_ident.stderr
@@ -0,0 +1,2 @@
+error: invalid `--check-cfg` argument: `values("NOT_IDENT")` (`values()` first argument must be a simple identifer)
+
diff --git a/src/test/ui/check-cfg/invalid-arguments.values_string_literals.stderr b/src/test/ui/check-cfg/invalid-arguments.values_string_literals.stderr
new file mode 100644
index 00000000000..5853b4741a6
--- /dev/null
+++ b/src/test/ui/check-cfg/invalid-arguments.values_string_literals.stderr
@@ -0,0 +1,2 @@
+error: invalid `--check-cfg` argument: `values(test,12)` (`values()` arguments must be string literals)
+
diff --git a/src/test/ui/check-cfg/invalid-cfg-name.rs b/src/test/ui/check-cfg/invalid-cfg-name.rs
new file mode 100644
index 00000000000..8499d3d4448
--- /dev/null
+++ b/src/test/ui/check-cfg/invalid-cfg-name.rs
@@ -0,0 +1,14 @@
+// Check warning for invalid configuration name
+//
+// edition:2018
+// check-pass
+// compile-flags: --check-cfg=names() -Z unstable-options
+
+#[cfg(widnows)]
+//~^ WARNING unexpected `cfg` condition name
+pub fn f() {}
+
+#[cfg(windows)]
+pub fn g() {}
+
+pub fn main() {}
diff --git a/src/test/ui/check-cfg/invalid-cfg-name.stderr b/src/test/ui/check-cfg/invalid-cfg-name.stderr
new file mode 100644
index 00000000000..2587685afa0
--- /dev/null
+++ b/src/test/ui/check-cfg/invalid-cfg-name.stderr
@@ -0,0 +1,10 @@
+warning: unexpected `cfg` condition name
+  --> $DIR/invalid-cfg-name.rs:7:7
+   |
+LL | #[cfg(widnows)]
+   |       ^^^^^^^
+   |
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/check-cfg/invalid-cfg-value.rs b/src/test/ui/check-cfg/invalid-cfg-value.rs
new file mode 100644
index 00000000000..a60095a5aae
--- /dev/null
+++ b/src/test/ui/check-cfg/invalid-cfg-value.rs
@@ -0,0 +1,17 @@
+// Check warning for invalid configuration value
+//
+// edition:2018
+// check-pass
+// compile-flags: --check-cfg=values(feature,"serde","full") --cfg=feature="rand" -Z unstable-options
+
+#[cfg(feature = "sedre")]
+//~^ WARNING unexpected `cfg` condition value
+pub fn f() {}
+
+#[cfg(feature = "serde")]
+pub fn g() {}
+
+#[cfg(feature = "rand")]
+pub fn h() {}
+
+pub fn main() {}
diff --git a/src/test/ui/check-cfg/invalid-cfg-value.stderr b/src/test/ui/check-cfg/invalid-cfg-value.stderr
new file mode 100644
index 00000000000..c591d8474a2
--- /dev/null
+++ b/src/test/ui/check-cfg/invalid-cfg-value.stderr
@@ -0,0 +1,10 @@
+warning: unexpected `cfg` condition value
+  --> $DIR/invalid-cfg-value.rs:7:7
+   |
+LL | #[cfg(feature = "sedre")]
+   |       ^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/const-generics/defaults/doesnt_infer.rs b/src/test/ui/const-generics/defaults/doesnt_infer.rs
index cd533b57bc3..9c59e672d8e 100644
--- a/src/test/ui/const-generics/defaults/doesnt_infer.rs
+++ b/src/test/ui/const-generics/defaults/doesnt_infer.rs
@@ -9,5 +9,5 @@ impl<const N: u32> Foo<N> {
 fn main() {
     let foo = Foo::<1>::foo();
     let foo = Foo::foo();
-    //~^ error: type annotations needed for `Foo<{_: u32}>`
+    //~^ error: type annotations needed for `Foo<N>`
 }
diff --git a/src/test/ui/const-generics/defaults/doesnt_infer.stderr b/src/test/ui/const-generics/defaults/doesnt_infer.stderr
index 1551e81ea75..cccf433e328 100644
--- a/src/test/ui/const-generics/defaults/doesnt_infer.stderr
+++ b/src/test/ui/const-generics/defaults/doesnt_infer.stderr
@@ -1,4 +1,4 @@
-error[E0282]: type annotations needed for `Foo<{_: u32}>`
+error[E0282]: type annotations needed for `Foo<N>`
   --> $DIR/doesnt_infer.rs:11:15
    |
 LL |     let foo = Foo::foo();
diff --git a/src/test/ui/const-generics/generic_arg_infer/issue-91614.rs b/src/test/ui/const-generics/generic_arg_infer/issue-91614.rs
index 413cc153924..b45e2cbc737 100644
--- a/src/test/ui/const-generics/generic_arg_infer/issue-91614.rs
+++ b/src/test/ui/const-generics/generic_arg_infer/issue-91614.rs
@@ -4,5 +4,5 @@ use std::simd::Mask;
 
 fn main() {
     let y = Mask::<_, _>::splat(false);
-    //~^ error: type annotations needed for `Mask<_, {_: usize}>`
+    //~^ ERROR: type annotations needed for
 }
diff --git a/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr b/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr
index 71a5ff79280..347cd2364b2 100644
--- a/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr
+++ b/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr
@@ -1,4 +1,4 @@
-error[E0283]: type annotations needed for `Mask<_, {_: usize}>`
+error[E0283]: type annotations needed for `Mask<_, LANES>`
   --> $DIR/issue-91614.rs:6:13
    |
 LL |     let y = Mask::<_, _>::splat(false);
diff --git a/src/test/ui/dropck/drop-with-active-borrows-2.stderr b/src/test/ui/dropck/drop-with-active-borrows-2.stderr
index d5b747d42fb..24650dfac02 100644
--- a/src/test/ui/dropck/drop-with-active-borrows-2.stderr
+++ b/src/test/ui/dropck/drop-with-active-borrows-2.stderr
@@ -1,9 +1,10 @@
 error[E0515]: cannot return value referencing local variable `raw_lines`
-  --> $DIR/drop-with-active-borrows-2.rs:3:30
+  --> $DIR/drop-with-active-borrows-2.rs:3:5
    |
 LL |     raw_lines.iter().map(|l| l.trim()).collect()
-   |     ----------------         ^^^^^^^^ returns a value referencing data owned by the current function
+   |     ----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |     |
+   |     returns a value referencing data owned by the current function
    |     `raw_lines` is borrowed here
 
 error: aborting due to previous error
diff --git a/src/test/ui/feature-gates/feature-gate-asm_const.stderr b/src/test/ui/feature-gates/feature-gate-asm_const.stderr
index 2851a9b0ae6..0202ccbe5a2 100644
--- a/src/test/ui/feature-gates/feature-gate-asm_const.stderr
+++ b/src/test/ui/feature-gates/feature-gate-asm_const.stderr
@@ -4,7 +4,7 @@ error[E0658]: const operands for inline assembly are unstable
 LL |         asm!("mov eax, {}", const 123);
    |                             ^^^^^^^^^
    |
-   = note: see issue #72016 <https://github.com/rust-lang/rust/issues/72016> for more information
+   = note: see issue #93332 <https://github.com/rust-lang/rust/issues/93332> for more information
    = help: add `#![feature(asm_const)]` to the crate attributes to enable
 
 error: aborting due to previous error
diff --git a/src/test/ui/feature-gates/feature-gate-asm_experimental_arch.stderr b/src/test/ui/feature-gates/feature-gate-asm_experimental_arch.stderr
index 1b4188ae1ad..4a859430e04 100644
--- a/src/test/ui/feature-gates/feature-gate-asm_experimental_arch.stderr
+++ b/src/test/ui/feature-gates/feature-gate-asm_experimental_arch.stderr
@@ -4,7 +4,7 @@ error[E0658]: inline assembly is not stable yet on this architecture
 LL |     asm!("");
    |     ^^^^^^^^
    |
-   = note: see issue #72016 <https://github.com/rust-lang/rust/issues/72016> for more information
+   = note: see issue #93335 <https://github.com/rust-lang/rust/issues/93335> for more information
    = help: add `#![feature(asm_experimental_arch)]` to the crate attributes to enable
 
 error: aborting due to previous error
diff --git a/src/test/ui/feature-gates/feature-gate-asm_sym.stderr b/src/test/ui/feature-gates/feature-gate-asm_sym.stderr
index 99b61b829fb..68f2d0f6c18 100644
--- a/src/test/ui/feature-gates/feature-gate-asm_sym.stderr
+++ b/src/test/ui/feature-gates/feature-gate-asm_sym.stderr
@@ -4,7 +4,7 @@ error[E0658]: sym operands for inline assembly are unstable
 LL |         asm!("mov eax, {}", sym main);
    |                             ^^^^^^^^
    |
-   = note: see issue #72016 <https://github.com/rust-lang/rust/issues/72016> for more information
+   = note: see issue #93333 <https://github.com/rust-lang/rust/issues/93333> for more information
    = help: add `#![feature(asm_sym)]` to the crate attributes to enable
 
 error: aborting due to previous error
diff --git a/src/test/ui/feature-gates/feature-gate-asm_unwind.stderr b/src/test/ui/feature-gates/feature-gate-asm_unwind.stderr
index 6b5bf286e7b..05e66acb556 100644
--- a/src/test/ui/feature-gates/feature-gate-asm_unwind.stderr
+++ b/src/test/ui/feature-gates/feature-gate-asm_unwind.stderr
@@ -4,7 +4,7 @@ error[E0658]: the `may_unwind` option is unstable
 LL |         asm!("", options(may_unwind));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: see issue #72016 <https://github.com/rust-lang/rust/issues/72016> for more information
+   = note: see issue #93334 <https://github.com/rust-lang/rust/issues/93334> for more information
    = help: add `#![feature(asm_unwind)]` to the crate attributes to enable
 
 error: aborting due to previous error
diff --git a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs
index 1e48996acb8..a93fb797713 100644
--- a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs
+++ b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs
@@ -57,20 +57,20 @@ fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
 
 const _cdef: impl Tr1<As1: Copy> = S1;
 //~^ ERROR associated type bounds are unstable
-//~| ERROR `impl Trait` not allowed outside of function and method return types [E0562]
+//~| ERROR `impl Trait` only allowed in function and inherent method return types
 // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
 // const _cdef_dyn: &dyn Tr1<As1: Copy> = &S1;
 
 static _sdef: impl Tr1<As1: Copy> = S1;
 //~^ ERROR associated type bounds are unstable
-//~| ERROR `impl Trait` not allowed outside of function and method return types [E0562]
+//~| ERROR `impl Trait` only allowed in function and inherent method return types
 // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
 // static _sdef_dyn: &dyn Tr1<As1: Copy> = &S1;
 
 fn main() {
     let _: impl Tr1<As1: Copy> = S1;
     //~^ ERROR associated type bounds are unstable
-    //~| ERROR `impl Trait` not allowed outside of function and method return types [E0562]
+    //~| ERROR `impl Trait` only allowed in function and inherent method return types
     // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
     // let _: &dyn Tr1<As1: Copy> = &S1;
 }
diff --git a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr
index 8c5d72d7efe..5be1d97a059 100644
--- a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr
+++ b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr
@@ -115,19 +115,19 @@ LL |     let _: impl Tr1<As1: Copy> = S1;
    = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
    = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/feature-gate-associated_type_bounds.rs:58:14
    |
 LL | const _cdef: impl Tr1<As1: Copy> = S1;
    |              ^^^^^^^^^^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/feature-gate-associated_type_bounds.rs:64:15
    |
 LL | static _sdef: impl Tr1<As1: Copy> = S1;
    |               ^^^^^^^^^^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
   --> $DIR/feature-gate-associated_type_bounds.rs:71:12
    |
 LL |     let _: impl Tr1<As1: Copy> = S1;
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-panic.rs b/src/test/ui/feature-gates/feature-gate-cfg-panic.rs
deleted file mode 100644
index 1508374d942..00000000000
--- a/src/test/ui/feature-gates/feature-gate-cfg-panic.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-#[cfg(panic = "unwind")]
-//~^ ERROR `cfg(panic)` is experimental and subject to change
-fn foo() -> bool { true }
-#[cfg(not(panic = "unwind"))]
-//~^ ERROR `cfg(panic)` is experimental and subject to change
-fn foo() -> bool { false }
-
-
-fn main() {
-    assert!(foo());
-}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-panic.stderr b/src/test/ui/feature-gates/feature-gate-cfg-panic.stderr
deleted file mode 100644
index ea5cd54fa90..00000000000
--- a/src/test/ui/feature-gates/feature-gate-cfg-panic.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0658]: `cfg(panic)` is experimental and subject to change
-  --> $DIR/feature-gate-cfg-panic.rs:1:7
-   |
-LL | #[cfg(panic = "unwind")]
-   |       ^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #77443 <https://github.com/rust-lang/rust/issues/77443> for more information
-   = help: add `#![feature(cfg_panic)]` to the crate attributes to enable
-
-error[E0658]: `cfg(panic)` is experimental and subject to change
-  --> $DIR/feature-gate-cfg-panic.rs:4:11
-   |
-LL | #[cfg(not(panic = "unwind"))]
-   |           ^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #77443 <https://github.com/rust-lang/rust/issues/77443> for more information
-   = help: add `#![feature(cfg_panic)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-check-cfg.rs b/src/test/ui/feature-gates/feature-gate-check-cfg.rs
new file mode 100644
index 00000000000..4012a3b04b5
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-check-cfg.rs
@@ -0,0 +1,3 @@
+// compile-flags: --check-cfg "names()"
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-check-cfg.stderr b/src/test/ui/feature-gates/feature-gate-check-cfg.stderr
new file mode 100644
index 00000000000..9b27c2bc058
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-check-cfg.stderr
@@ -0,0 +1,2 @@
+error: the `-Z unstable-options` flag must also be passed to enable the flag `check-cfg`
+
diff --git a/src/test/ui/fmt/format-args-capture.rs b/src/test/ui/fmt/format-args-capture.rs
index d31d2a6c336..560352b5cb9 100644
--- a/src/test/ui/fmt/format-args-capture.rs
+++ b/src/test/ui/fmt/format-args-capture.rs
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(cfg_panic)]
 
 fn main() {
     named_argument_takes_precedence_to_captured();
diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.rs b/src/test/ui/generic-associated-types/bugs/issue-80626.rs
index aea8aaf4bb3..a637da6cf6f 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-80626.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-80626.rs
@@ -1,4 +1,5 @@
 // check-fail
+// known-bug
 
 // This should pass, but it requires `Sized` to be coinductive.
 
@@ -11,7 +12,6 @@ trait Allocator {
 enum LinkedList<A: Allocator> {
     Head,
     Next(A::Allocated<Self>)
-    //~^ overflow
 }
 
 fn main() {}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
index e18af9c257f..8b0cc78e999 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
@@ -1,5 +1,5 @@
 error[E0275]: overflow evaluating the requirement `LinkedList<A>: Sized`
-  --> $DIR/issue-80626.rs:13:10
+  --> $DIR/issue-80626.rs:14:10
    |
 LL |     Next(A::Allocated<Self>)
    |          ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/generic-associated-types/bugs/issue-86218.rs b/src/test/ui/generic-associated-types/bugs/issue-86218.rs
index 3f8776a3637..68cd0fd7efc 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-86218.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-86218.rs
@@ -1,4 +1,5 @@
 // check-fail
+// known-bug
 
 // This should pass, but seems to run into a TAIT issue.
 
@@ -20,7 +21,6 @@ trait Yay<AdditionalValue> {
 
 impl<'a> Yay<&'a ()> for () {
     type InnerStream<'s> = impl Stream<Item = i32> + 's;
-    //~^ the type
     fn foo<'s>() -> Self::InnerStream<'s> { todo!() }
 }
 
diff --git a/src/test/ui/generic-associated-types/bugs/issue-86218.stderr b/src/test/ui/generic-associated-types/bugs/issue-86218.stderr
index 9f4efc0addb..98a5f4254bb 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-86218.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-86218.stderr
@@ -1,11 +1,11 @@
 error[E0477]: the type `impl Stream<Item = i32>` does not fulfill the required lifetime
-  --> $DIR/issue-86218.rs:22:28
+  --> $DIR/issue-86218.rs:23:28
    |
 LL |     type InnerStream<'s> = impl Stream<Item = i32> + 's;
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: type must outlive the lifetime `'s` as defined here as required by this binding
-  --> $DIR/issue-86218.rs:22:22
+  --> $DIR/issue-86218.rs:23:22
    |
 LL |     type InnerStream<'s> = impl Stream<Item = i32> + 's;
    |                      ^^
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87735.rs b/src/test/ui/generic-associated-types/bugs/issue-87735.rs
index 5f7a42a740d..6d6063f8085 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87735.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-87735.rs
@@ -1,4 +1,5 @@
 // check-fail
+// known-bug
 
 // This should pass, but we need an extension of implied bounds (probably).
 
@@ -23,7 +24,7 @@ struct Foo<T>(T);
 #[derive(Debug)]
 struct FooRef<'a, U>(&'a [U]);
 
-impl<'b, T, U> AsRef2 for Foo<T> //~ the type parameter
+impl<'b, T, U> AsRef2 for Foo<T>
 where
     // * `for<'b, 'c> T: AsRef2<Output<'b> = &'c [U]>>` does not work
     //
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87735.stderr b/src/test/ui/generic-associated-types/bugs/issue-87735.stderr
index 31b3a9619b6..0a18b5f0cbd 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87735.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-87735.stderr
@@ -1,5 +1,5 @@
 error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/issue-87735.rs:26:13
+  --> $DIR/issue-87735.rs:27:13
    |
 LL | impl<'b, T, U> AsRef2 for Foo<T>
    |             ^ unconstrained type parameter
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87748.rs b/src/test/ui/generic-associated-types/bugs/issue-87748.rs
index 4dbaf429ead..ffcfd62cbb3 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87748.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-87748.rs
@@ -1,4 +1,5 @@
 // check-fail
+// known-bug
 
 // This should pass, but unnormalized input args aren't treated as implied.
 
@@ -14,7 +15,7 @@ struct Foo;
 impl MyTrait for Foo {
     type Assoc<'a, 'b> where 'b: 'a = u32;
 
-    fn do_sth(_: u32) {} //~ lifetime bound
+    fn do_sth(_: u32) {}
     // fn do_sth(_: Self::Assoc<'static, 'static>) {}
     // fn do_sth(_: Self::Assoc<'_, '_>) {}
 }
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87748.stderr b/src/test/ui/generic-associated-types/bugs/issue-87748.stderr
index c38d4478592..60bb48efbc8 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87748.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-87748.stderr
@@ -1,16 +1,16 @@
 error[E0478]: lifetime bound not satisfied
-  --> $DIR/issue-87748.rs:17:5
+  --> $DIR/issue-87748.rs:18:5
    |
 LL |     fn do_sth(_: u32) {}
    |     ^^^^^^^^^^^^^^^^^
    |
 note: lifetime parameter instantiated with the anonymous lifetime #2 defined here
-  --> $DIR/issue-87748.rs:17:5
+  --> $DIR/issue-87748.rs:18:5
    |
 LL |     fn do_sth(_: u32) {}
    |     ^^^^^^^^^^^^^^^^^
 note: but lifetime parameter must outlive the anonymous lifetime #1 defined here
-  --> $DIR/issue-87748.rs:17:5
+  --> $DIR/issue-87748.rs:18:5
    |
 LL |     fn do_sth(_: u32) {}
    |     ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87755.rs b/src/test/ui/generic-associated-types/bugs/issue-87755.rs
index 1cd3534ba77..31cea12a3e2 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87755.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-87755.rs
@@ -1,4 +1,5 @@
 // check-fail
+// known-bug
 
 // This should pass.
 
@@ -15,7 +16,6 @@ struct Bar;
 
 impl Foo for Bar {
     type Ass = Bar;
-    //~^ overflow
 }
 
 fn main() {}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87755.stderr b/src/test/ui/generic-associated-types/bugs/issue-87755.stderr
index d2dc991a2b6..5d1aff0117c 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87755.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-87755.stderr
@@ -1,5 +1,5 @@
 error[E0275]: overflow evaluating the requirement `<Bar as Foo>::Ass == _`
-  --> $DIR/issue-87755.rs:17:16
+  --> $DIR/issue-87755.rs:18:16
    |
 LL |     type Ass = Bar;
    |                ^^^
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87803.rs b/src/test/ui/generic-associated-types/bugs/issue-87803.rs
index 3d2ff38ab04..57a4b028d93 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87803.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-87803.rs
@@ -1,4 +1,5 @@
 // check-fail
+// known-bug
 
 // This should pass, but using a type alias vs a reference directly
 // changes late-bound -> early-bound.
@@ -18,7 +19,7 @@ impl Scanner for IdScanner {
     type Input<'a> = &'a str;
     type Token<'a> = &'a str;
 
-    fn scan<'a>(&mut self, s : &'a str) -> &'a str { //~ lifetime parameters
+    fn scan<'a>(&mut self, s : &'a str) -> &'a str {
         s
     }
 }
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87803.stderr b/src/test/ui/generic-associated-types/bugs/issue-87803.stderr
index 759c0440d07..c81c051d32a 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-87803.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-87803.stderr
@@ -1,5 +1,5 @@
 error[E0195]: lifetime parameters or bounds on method `scan` do not match the trait declaration
-  --> $DIR/issue-87803.rs:21:12
+  --> $DIR/issue-87803.rs:22:12
    |
 LL |     fn scan<'a>(&mut self, i : Self::Input<'a>) -> Self::Token<'a>;
    |            ---- lifetimes in impl do not match this method in trait
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88382.rs b/src/test/ui/generic-associated-types/bugs/issue-88382.rs
index f4633ca5169..c9f34240527 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88382.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-88382.rs
@@ -1,4 +1,5 @@
 // check-fail
+// known-bug
 
 // This should pass, but has a missed normalization due to HRTB.
 
@@ -25,7 +26,6 @@ fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>))
 fn main() {
     do_something(SomeImplementation(), |_| ());
     do_something(SomeImplementation(), test);
-    //~^ type mismatch
 }
 
 fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88382.stderr b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr
index 05bc58cbba4..d06c3ec8de7 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88382.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr
@@ -1,5 +1,5 @@
 error[E0631]: type mismatch in function arguments
-  --> $DIR/issue-88382.rs:27:40
+  --> $DIR/issue-88382.rs:28:40
    |
 LL |     do_something(SomeImplementation(), test);
    |     ------------                       ^^^^ expected signature of `for<'a> fn(&mut <SomeImplementation as Iterable>::Iterator<'a>) -> _`
@@ -10,7 +10,7 @@ LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}
    | ------------------------------------------------- found signature of `for<'r> fn(&'r mut std::iter::Empty<usize>) -> _`
    |
 note: required by a bound in `do_something`
-  --> $DIR/issue-88382.rs:21:56
+  --> $DIR/issue-88382.rs:22:56
    |
 LL | fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) {
    |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something`
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88460.rs b/src/test/ui/generic-associated-types/bugs/issue-88460.rs
index 7e62790cc50..b31d012d2fc 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88460.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-88460.rs
@@ -1,4 +1,5 @@
 // check-fail
+// known-bug
 
 // This should pass, but has a missed normalization due to HRTB.
 
@@ -27,5 +28,4 @@ impl Trait for Foo {
 
 fn main() {
     test(Foo);
-    //~^ the trait bound
 }
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88460.stderr b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr
index 604658da7d2..0b83e9da1ab 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88460.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied
-  --> $DIR/issue-88460.rs:29:5
+  --> $DIR/issue-88460.rs:30:5
    |
 LL |     test(Foo);
    |     ^^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>`
    |
 note: required by a bound in `test`
-  --> $DIR/issue-88460.rs:16:27
+  --> $DIR/issue-88460.rs:17:27
    |
 LL | fn test<T>(value: T)
    |    ---- required by a bound in this
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88526.rs b/src/test/ui/generic-associated-types/bugs/issue-88526.rs
index 90568fcb401..c72a450b926 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88526.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-88526.rs
@@ -1,4 +1,5 @@
 // check-fail
+// known-bug
 
 // This should pass, but requires more logic.
 
@@ -23,7 +24,7 @@ struct TestB<Q, F>
     f: F,
 }
 
-impl<'q, Q, I, F> A for TestB<Q, F> //~ the type parameter
+impl<'q, Q, I, F> A for TestB<Q, F>
 where
     Q: A<I<'q> = &'q I>,
     F: Fn(I),
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88526.stderr b/src/test/ui/generic-associated-types/bugs/issue-88526.stderr
index ccc5ae0b621..127c889bf71 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88526.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-88526.stderr
@@ -1,5 +1,5 @@
 error[E0207]: the type parameter `I` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/issue-88526.rs:26:13
+  --> $DIR/issue-88526.rs:27:13
    |
 LL | impl<'q, Q, I, F> A for TestB<Q, F>
    |             ^ unconstrained type parameter
diff --git a/src/test/ui/generic-associated-types/bugs/issue-89008.rs b/src/test/ui/generic-associated-types/bugs/issue-89008.rs
index 5d850849fd2..1581b7105a8 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-89008.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-89008.rs
@@ -1,5 +1,6 @@
 // check-fail
 // edition:2021
+// known-bug
 
 // This should pass, but seems to run into a TAIT bug.
 
@@ -31,11 +32,11 @@ trait X {
 struct Y;
 
 impl X for Y {
-    type LineStream<'a, Repr> = impl Stream<Item = Repr>; //~ could not find
+    type LineStream<'a, Repr> = impl Stream<Item = Repr>;
 
     type LineStreamFut<'a, Repr> = impl Future<Output = Self::LineStream<'a, Repr>> ;
 
-    fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> { //~ type mismatch
+    fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
         async {empty()}
     }
 }
diff --git a/src/test/ui/generic-associated-types/bugs/issue-89008.stderr b/src/test/ui/generic-associated-types/bugs/issue-89008.stderr
index 48745fe0fbd..c2687ca5401 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-89008.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-89008.stderr
@@ -1,5 +1,5 @@
 error[E0271]: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == impl Stream<Item = Repr>`
-  --> $DIR/issue-89008.rs:38:43
+  --> $DIR/issue-89008.rs:39:43
    |
 LL |     type LineStream<'a, Repr> = impl Stream<Item = Repr>;
    |                                 ------------------------ the expected opaque type
@@ -11,7 +11,7 @@ LL |     fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
                    found struct `Empty<_>`
 
 error: could not find defining uses
-  --> $DIR/issue-89008.rs:34:33
+  --> $DIR/issue-89008.rs:35:33
    |
 LL |     type LineStream<'a, Repr> = impl Stream<Item = Repr>;
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr
index 5be431f2933..bd0dea37219 100644
--- a/src/test/ui/generic-associated-types/impl_bounds.stderr
+++ b/src/test/ui/generic-associated-types/impl_bounds.stderr
@@ -19,8 +19,13 @@ LL |     type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
 error[E0478]: lifetime bound not satisfied
   --> $DIR/impl_bounds.rs:17:35
    |
+LL |     type B<'a, 'b> where 'a: 'b;
+   |     ---------------------------- definition of `B` from trait
+...
 LL |     type B<'a, 'b> where 'b: 'a = (&'a(), &'b ());
-   |                                   ^^^^^^^^^^^^^^^
+   |                                -  ^^^^^^^^^^^^^^^
+   |                                |
+   |                                help: try copying this clause from the trait: `, 'a: 'b`
    |
 note: lifetime parameter instantiated with the lifetime `'a` as defined here
   --> $DIR/impl_bounds.rs:17:12
diff --git a/src/test/ui/generic-associated-types/issue-74824.rs b/src/test/ui/generic-associated-types/issue-74824.rs
index 01f99fa4487..1bbf7aac5cd 100644
--- a/src/test/ui/generic-associated-types/issue-74824.rs
+++ b/src/test/ui/generic-associated-types/issue-74824.rs
@@ -17,7 +17,6 @@ impl<T> UnsafeCopy for T {}
 fn main() {
     let b = Box::new(42usize);
     let copy = <()>::copy(&b);
-    //~^ type annotations needed
 
     let raw_b = Box::deref(&b) as *const _;
     let raw_copy = Box::deref(&copy) as *const _;
diff --git a/src/test/ui/generic-associated-types/issue-74824.stderr b/src/test/ui/generic-associated-types/issue-74824.stderr
index e7ebf5964ba..8517eb9fa21 100644
--- a/src/test/ui/generic-associated-types/issue-74824.stderr
+++ b/src/test/ui/generic-associated-types/issue-74824.stderr
@@ -27,13 +27,6 @@ help: consider restricting type parameter `T`
 LL |     type Copy<T: std::clone::Clone>: Copy = Box<T>;
    |                +++++++++++++++++++
 
-error[E0282]: type annotations needed
-  --> $DIR/issue-74824.rs:19:16
-   |
-LL |     let copy = <()>::copy(&b);
-   |                ^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated function `copy`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0277, E0282.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generic-associated-types/issue-88595.rs b/src/test/ui/generic-associated-types/issue-88595.rs
index e397390783f..c97d17811ba 100644
--- a/src/test/ui/generic-associated-types/issue-88595.rs
+++ b/src/test/ui/generic-associated-types/issue-88595.rs
@@ -8,7 +8,7 @@ trait A<'a> {
     // FIXME(generic_associated_types): Remove one of the below bounds
     // https://github.com/rust-lang/rust/pull/90678#discussion_r744976085
     where
-        'a: 'b, Self: 'a, Self: 'b;
+        Self: 'a, Self: 'b;
 
     fn a(&'a self) -> Self::B<'a>;
 }
@@ -17,8 +17,7 @@ struct C;
 
 impl<'a> A<'a> for C {
     type B<'b> = impl Clone;
-    //~^ ERROR: lifetime bound not satisfied
-    //~| ERROR: could not find defining uses
+    //~^ ERROR: could not find defining uses
 
     fn a(&'a self) -> Self::B<'a> {} //~ ERROR: non-defining opaque type use in defining scope
 }
diff --git a/src/test/ui/generic-associated-types/issue-88595.stderr b/src/test/ui/generic-associated-types/issue-88595.stderr
index cb462871ccd..4e4f86bbac8 100644
--- a/src/test/ui/generic-associated-types/issue-88595.stderr
+++ b/src/test/ui/generic-associated-types/issue-88595.stderr
@@ -1,22 +1,5 @@
-error[E0478]: lifetime bound not satisfied
-  --> $DIR/issue-88595.rs:19:18
-   |
-LL |     type B<'b> = impl Clone;
-   |                  ^^^^^^^^^^
-   |
-note: lifetime parameter instantiated with the lifetime `'a` as defined here
-  --> $DIR/issue-88595.rs:18:6
-   |
-LL | impl<'a> A<'a> for C {
-   |      ^^
-note: but lifetime parameter must outlive the lifetime `'b` as defined here
-  --> $DIR/issue-88595.rs:19:12
-   |
-LL |     type B<'b> = impl Clone;
-   |            ^^
-
 error: non-defining opaque type use in defining scope
-  --> $DIR/issue-88595.rs:23:23
+  --> $DIR/issue-88595.rs:22:23
    |
 LL |     fn a(&'a self) -> Self::B<'a> {}
    |                       ^^^^^^^^^^^
@@ -35,6 +18,5 @@ error: could not find defining uses
 LL |     type B<'b> = impl Clone;
    |                  ^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0478`.
diff --git a/src/test/ui/generic-associated-types/issue-90014.stderr b/src/test/ui/generic-associated-types/issue-90014.stderr
index 23e8d08af34..f8fb71bbddb 100644
--- a/src/test/ui/generic-associated-types/issue-90014.stderr
+++ b/src/test/ui/generic-associated-types/issue-90014.stderr
@@ -1,8 +1,13 @@
 error[E0477]: the type `&mut ()` does not fulfill the required lifetime
   --> $DIR/issue-90014.rs:14:20
    |
+LL |     type Fut<'a> where Self: 'a;
+   |     ---------------------------- definition of `Fut` from trait
+...
 LL |     type Fut<'a> = impl Future<Output = ()>;
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 -  ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 help: try copying this clause from the trait: `where Self: 'a`
    |
 note: type must outlive the lifetime `'a` as defined here
   --> $DIR/issue-90014.rs:14:14
diff --git a/src/test/ui/generic-associated-types/issue-92033.rs b/src/test/ui/generic-associated-types/issue-92033.rs
new file mode 100644
index 00000000000..1d5f7d5c009
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-92033.rs
@@ -0,0 +1,39 @@
+#![feature(generic_associated_types)]
+
+struct Texture;
+
+trait Surface {
+    type TextureIter<'a>: Iterator<Item = &'a Texture>
+    where
+        Self: 'a;
+
+    fn get_texture(&self) -> Self::TextureIter<'_>;
+}
+
+trait Swapchain {
+    type Surface<'a>: Surface
+    where
+        Self: 'a;
+
+    fn get_surface(&self) -> Self::Surface<'_>;
+}
+
+impl<'s> Surface for &'s Texture {
+    type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
+    //~^ ERROR the type
+
+    fn get_texture(&self) -> Self::TextureIter<'_> {
+        let option: Option<&Texture> = Some(self);
+        option.into_iter()
+    }
+}
+
+impl Swapchain for Texture {
+    type Surface<'a> = &'a Texture;
+
+    fn get_surface(&self) -> Self::Surface<'_> {
+        self
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-92033.stderr b/src/test/ui/generic-associated-types/issue-92033.stderr
new file mode 100644
index 00000000000..caa6618f398
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-92033.stderr
@@ -0,0 +1,22 @@
+error[E0477]: the type `&'s Texture` does not fulfill the required lifetime
+  --> $DIR/issue-92033.rs:22:28
+   |
+LL | /     type TextureIter<'a>: Iterator<Item = &'a Texture>
+LL | |     where
+LL | |         Self: 'a;
+   | |_________________- definition of `TextureIter` from trait
+...
+LL |       type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
+   |                           -  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                           |
+   |                           help: try copying this clause from the trait: `where Self: 'a`
+   |
+note: type must outlive the lifetime `'a` as defined here
+  --> $DIR/issue-92033.rs:22:22
+   |
+LL |     type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
+   |                      ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0477`.
diff --git a/src/test/ui/generic-associated-types/issue-93874.rs b/src/test/ui/generic-associated-types/issue-93874.rs
new file mode 100644
index 00000000000..f403d75167d
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-93874.rs
@@ -0,0 +1,35 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+pub trait Build {
+    type Output<O>;
+    fn build<O>(self, input: O) -> Self::Output<O>;
+}
+
+pub struct IdentityBuild;
+impl Build for IdentityBuild {
+    type Output<O> = O;
+    fn build<O>(self, input: O) -> Self::Output<O> {
+        input
+    }
+}
+
+fn a() {
+    let _x: u8 = IdentityBuild.build(10);
+}
+
+fn b() {
+    let _x: Vec<u8> = IdentityBuild.build(Vec::new());
+}
+
+fn c() {
+    let mut f = IdentityBuild.build(|| ());
+    (f)();
+}
+
+pub fn main() {
+    a();
+    b();
+    c();
+}
diff --git a/src/test/ui/impl-trait/issues/issue-54600.rs b/src/test/ui/impl-trait/issues/issue-54600.rs
index 7a647993023..3024fedf7b5 100644
--- a/src/test/ui/impl-trait/issues/issue-54600.rs
+++ b/src/test/ui/impl-trait/issues/issue-54600.rs
@@ -2,6 +2,6 @@ use std::fmt::Debug;
 
 fn main() {
     let x: Option<impl Debug> = Some(44_u32);
-    //~^ `impl Trait` not allowed outside of function and method return types
+    //~^ `impl Trait` only allowed in function and inherent method return types
     println!("{:?}", x);
 }
diff --git a/src/test/ui/impl-trait/issues/issue-54600.stderr b/src/test/ui/impl-trait/issues/issue-54600.stderr
index 4d0c32c6bb7..316566a57a8 100644
--- a/src/test/ui/impl-trait/issues/issue-54600.stderr
+++ b/src/test/ui/impl-trait/issues/issue-54600.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
   --> $DIR/issue-54600.rs:4:19
    |
 LL |     let x: Option<impl Debug> = Some(44_u32);
diff --git a/src/test/ui/impl-trait/issues/issue-54840.rs b/src/test/ui/impl-trait/issues/issue-54840.rs
index 030d5715d57..8f1e0ece03a 100644
--- a/src/test/ui/impl-trait/issues/issue-54840.rs
+++ b/src/test/ui/impl-trait/issues/issue-54840.rs
@@ -3,5 +3,5 @@ use std::ops::Add;
 fn main() {
     let i: i32 = 0;
     let j: &impl Add = &i;
-    //~^ `impl Trait` not allowed outside of function and method return types
+    //~^ `impl Trait` only allowed in function and inherent method return types
 }
diff --git a/src/test/ui/impl-trait/issues/issue-54840.stderr b/src/test/ui/impl-trait/issues/issue-54840.stderr
index b8046b7482f..8d82133ac90 100644
--- a/src/test/ui/impl-trait/issues/issue-54840.stderr
+++ b/src/test/ui/impl-trait/issues/issue-54840.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
   --> $DIR/issue-54840.rs:5:13
    |
 LL |     let j: &impl Add = &i;
diff --git a/src/test/ui/impl-trait/issues/issue-58504.rs b/src/test/ui/impl-trait/issues/issue-58504.rs
index aac33b3b3e5..e5865d0dfff 100644
--- a/src/test/ui/impl-trait/issues/issue-58504.rs
+++ b/src/test/ui/impl-trait/issues/issue-58504.rs
@@ -8,5 +8,5 @@ fn mk_gen() -> impl Generator<Return=!, Yield=()> {
 
 fn main() {
     let gens: [impl Generator<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ];
-    //~^ `impl Trait` not allowed outside of function and method return types
+    //~^ `impl Trait` only allowed in function and inherent method return types
 }
diff --git a/src/test/ui/impl-trait/issues/issue-58504.stderr b/src/test/ui/impl-trait/issues/issue-58504.stderr
index ff1010f0661..6656e9fc3fb 100644
--- a/src/test/ui/impl-trait/issues/issue-58504.stderr
+++ b/src/test/ui/impl-trait/issues/issue-58504.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
   --> $DIR/issue-58504.rs:10:16
    |
 LL |     let gens: [impl Generator<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ];
diff --git a/src/test/ui/impl-trait/issues/issue-58956.rs b/src/test/ui/impl-trait/issues/issue-58956.rs
index 5fe18b6e9b5..68cfcd9ba4f 100644
--- a/src/test/ui/impl-trait/issues/issue-58956.rs
+++ b/src/test/ui/impl-trait/issues/issue-58956.rs
@@ -5,9 +5,9 @@ impl Lam for B {}
 pub struct Wrap<T>(T);
 
 const _A: impl Lam = {
-    //~^ `impl Trait` not allowed outside of function and method return types
+    //~^ `impl Trait` only allowed in function and inherent method return types
     let x: Wrap<impl Lam> = Wrap(B);
-    //~^ `impl Trait` not allowed outside of function and method return types
+    //~^ `impl Trait` only allowed in function and inherent method return types
     x.0
 };
 
diff --git a/src/test/ui/impl-trait/issues/issue-58956.stderr b/src/test/ui/impl-trait/issues/issue-58956.stderr
index 00ebf170ab2..123fb4df4b3 100644
--- a/src/test/ui/impl-trait/issues/issue-58956.stderr
+++ b/src/test/ui/impl-trait/issues/issue-58956.stderr
@@ -1,10 +1,10 @@
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/issue-58956.rs:7:11
    |
 LL | const _A: impl Lam = {
    |           ^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
   --> $DIR/issue-58956.rs:9:17
    |
 LL |     let x: Wrap<impl Lam> = Wrap(B);
diff --git a/src/test/ui/impl-trait/issues/issue-70971.rs b/src/test/ui/impl-trait/issues/issue-70971.rs
index d4dc2fd877b..f8ae18bacd6 100644
--- a/src/test/ui/impl-trait/issues/issue-70971.rs
+++ b/src/test/ui/impl-trait/issues/issue-70971.rs
@@ -1,4 +1,4 @@
 fn main() {
     let x : (impl Copy,) = (true,);
-    //~^ `impl Trait` not allowed outside of function and method return types
+    //~^ `impl Trait` only allowed in function and inherent method return types
 }
diff --git a/src/test/ui/impl-trait/issues/issue-70971.stderr b/src/test/ui/impl-trait/issues/issue-70971.stderr
index 31993da3e32..4dda4c22aa2 100644
--- a/src/test/ui/impl-trait/issues/issue-70971.stderr
+++ b/src/test/ui/impl-trait/issues/issue-70971.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
   --> $DIR/issue-70971.rs:2:14
    |
 LL |     let x : (impl Copy,) = (true,);
diff --git a/src/test/ui/impl-trait/issues/issue-79099.rs b/src/test/ui/impl-trait/issues/issue-79099.rs
index f72533d42e1..da53594f3d0 100644
--- a/src/test/ui/impl-trait/issues/issue-79099.rs
+++ b/src/test/ui/impl-trait/issues/issue-79099.rs
@@ -1,7 +1,7 @@
 struct Bug {
     V1: [(); {
         let f: impl core::future::Future<Output = u8> = async { 1 };
-        //~^ `impl Trait` not allowed outside of function and method return types
+        //~^ `impl Trait` only allowed in function and inherent method return types
         //~| expected identifier
         1
     }],
diff --git a/src/test/ui/impl-trait/issues/issue-79099.stderr b/src/test/ui/impl-trait/issues/issue-79099.stderr
index 394b697a250..4c9ec2a83ff 100644
--- a/src/test/ui/impl-trait/issues/issue-79099.stderr
+++ b/src/test/ui/impl-trait/issues/issue-79099.stderr
@@ -9,7 +9,7 @@ LL |         let f: impl core::future::Future<Output = u8> = async { 1 };
    = help: set `edition = "2021"` in `Cargo.toml`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
   --> $DIR/issue-79099.rs:3:16
    |
 LL |         let f: impl core::future::Future<Output = u8> = async { 1 };
diff --git a/src/test/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs b/src/test/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs
index 773cd0b81cc..344f359529b 100644
--- a/src/test/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs
+++ b/src/test/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs
@@ -1,8 +1,8 @@
 struct Foo<T = impl Copy>(T);
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 type Result<T, E = impl std::error::Error> = std::result::Result<T, E>;
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // should not cause ICE
 fn x() -> Foo {
diff --git a/src/test/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr b/src/test/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr
index d44dcf1f7fa..e635e554e23 100644
--- a/src/test/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr
+++ b/src/test/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr
@@ -1,10 +1,10 @@
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/issue-83929-impl-trait-in-generic-default.rs:1:16
    |
 LL | struct Foo<T = impl Copy>(T);
    |                ^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/issue-83929-impl-trait-in-generic-default.rs:4:20
    |
 LL | type Result<T, E = impl std::error::Error> = std::result::Result<T, E>;
diff --git a/src/test/ui/impl-trait/issues/issue-84919.rs b/src/test/ui/impl-trait/issues/issue-84919.rs
index 479bad97cdf..a0b73743a2b 100644
--- a/src/test/ui/impl-trait/issues/issue-84919.rs
+++ b/src/test/ui/impl-trait/issues/issue-84919.rs
@@ -3,7 +3,7 @@ impl Trait for () {}
 
 fn foo<'a: 'a>() {
     let _x: impl Trait = ();
-    //~^ `impl Trait` not allowed outside of function and method return types
+    //~^ `impl Trait` only allowed in function and inherent method return types
 }
 
 fn main() {}
diff --git a/src/test/ui/impl-trait/issues/issue-84919.stderr b/src/test/ui/impl-trait/issues/issue-84919.stderr
index bb1bcfefe64..5abe1bd8779 100644
--- a/src/test/ui/impl-trait/issues/issue-84919.stderr
+++ b/src/test/ui/impl-trait/issues/issue-84919.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
   --> $DIR/issue-84919.rs:5:13
    |
 LL |     let _x: impl Trait = ();
diff --git a/src/test/ui/impl-trait/issues/issue-86642.rs b/src/test/ui/impl-trait/issues/issue-86642.rs
index 8953ff81581..e6e95771400 100644
--- a/src/test/ui/impl-trait/issues/issue-86642.rs
+++ b/src/test/ui/impl-trait/issues/issue-86642.rs
@@ -1,5 +1,5 @@
 static x: impl Fn(&str) -> Result<&str, ()> = move |source| {
-    //~^ `impl Trait` not allowed outside of function and method return types
+    //~^ `impl Trait` only allowed in function and inherent method return types
     let res = (move |source| Ok(source))(source);
     let res = res.or((move |source| Ok(source))(source));
     res
diff --git a/src/test/ui/impl-trait/issues/issue-86642.stderr b/src/test/ui/impl-trait/issues/issue-86642.stderr
index 2fc0a6fe1f5..0ec118d5be8 100644
--- a/src/test/ui/impl-trait/issues/issue-86642.stderr
+++ b/src/test/ui/impl-trait/issues/issue-86642.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/issue-86642.rs:1:11
    |
 LL | static x: impl Fn(&str) -> Result<&str, ()> = move |source| {
diff --git a/src/test/ui/impl-trait/issues/issue-87295.rs b/src/test/ui/impl-trait/issues/issue-87295.rs
index 2f2bfe147bd..aeb8f83326e 100644
--- a/src/test/ui/impl-trait/issues/issue-87295.rs
+++ b/src/test/ui/impl-trait/issues/issue-87295.rs
@@ -14,5 +14,5 @@ impl<F> Struct<F> {
 
 fn main() {
     let _do_not_waste: Struct<impl Trait<Output = i32>> = Struct::new(());
-    //~^ `impl Trait` not allowed outside of function and method return types
+    //~^ `impl Trait` only allowed in function and inherent method return types
 }
diff --git a/src/test/ui/impl-trait/issues/issue-87295.stderr b/src/test/ui/impl-trait/issues/issue-87295.stderr
index f5c7603ce49..0b043056b84 100644
--- a/src/test/ui/impl-trait/issues/issue-87295.stderr
+++ b/src/test/ui/impl-trait/issues/issue-87295.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
   --> $DIR/issue-87295.rs:16:31
    |
 LL |     let _do_not_waste: Struct<impl Trait<Output = i32>> = Struct::new(());
diff --git a/src/test/ui/impl-trait/nested_impl_trait.rs b/src/test/ui/impl-trait/nested_impl_trait.rs
index be2c21a7743..06a2191a017 100644
--- a/src/test/ui/impl-trait/nested_impl_trait.rs
+++ b/src/test/ui/impl-trait/nested_impl_trait.rs
@@ -7,7 +7,7 @@ fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
 
 fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
 //~^ ERROR nested `impl Trait` is not allowed
-//~^^ `impl Trait` not allowed
+//~| `impl Trait` only allowed in function and inherent method return types
 
 fn bad_in_arg_position(_: impl Into<impl Debug>) { }
 //~^ ERROR nested `impl Trait` is not allowed
@@ -23,7 +23,7 @@ fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> {
 }
 
 fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
-//~^ `impl Trait` not allowed
+//~^ `impl Trait` only allowed in function and inherent method return types
     || 5
 }
 
diff --git a/src/test/ui/impl-trait/nested_impl_trait.stderr b/src/test/ui/impl-trait/nested_impl_trait.stderr
index 59c7e4d5f4e..4444e6a454f 100644
--- a/src/test/ui/impl-trait/nested_impl_trait.stderr
+++ b/src/test/ui/impl-trait/nested_impl_trait.stderr
@@ -34,13 +34,13 @@ LL |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
    |                                  |         nested `impl Trait` here
    |                                  outer `impl Trait`
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
   --> $DIR/nested_impl_trait.rs:8:32
    |
 LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
    |                                ^^^^^^^^^^^^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
   --> $DIR/nested_impl_trait.rs:25:42
    |
 LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
diff --git a/src/test/ui/impl-trait/where-allowed.rs b/src/test/ui/impl-trait/where-allowed.rs
index 35fb42d6213..c1dd46c7ff7 100644
--- a/src/test/ui/impl-trait/where-allowed.rs
+++ b/src/test/ui/impl-trait/where-allowed.rs
@@ -13,61 +13,61 @@ fn in_adt_in_parameters(_: Vec<impl Debug>) { panic!() }
 
 // Disallowed
 fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 //~^^ ERROR nested `impl Trait` is not allowed
 
 // Disallowed
 fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 //~| ERROR nested `impl Trait` is not allowed
 
 // Disallowed
 fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 
 // Allowed
@@ -80,22 +80,22 @@ fn in_impl_Trait_in_return() -> impl IntoIterator<Item = impl IntoIterator> {
 
 // Disallowed
 struct InBraceStructField { x: impl Debug }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 struct InAdtInBraceStructField { x: Vec<impl Debug> }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 struct InTupleStructField(impl Debug);
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 enum InEnum {
     InBraceVariant { x: impl Debug },
-    //~^ ERROR `impl Trait` not allowed outside of function and method return types
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
     InTupleVariant(impl Debug),
-    //~^ ERROR `impl Trait` not allowed outside of function and method return types
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
 }
 
 // Allowed
@@ -106,7 +106,7 @@ trait InTraitDefnParameters {
 // Disallowed
 trait InTraitDefnReturn {
     fn in_return() -> impl Debug;
-    //~^ ERROR `impl Trait` not allowed outside of function and method return types
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
 }
 
 // Allowed and disallowed in trait impls
@@ -123,7 +123,7 @@ impl DummyTrait for () {
     // Allowed
 
     fn in_trait_impl_return() -> impl Debug { () }
-    //~^ ERROR `impl Trait` not allowed outside of function and method return types
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
 }
 
 // Allowed
@@ -136,10 +136,10 @@ impl DummyType {
 // Disallowed
 extern "C" {
     fn in_foreign_parameters(_: impl Debug);
-    //~^ ERROR `impl Trait` not allowed outside of function and method return types
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
     fn in_foreign_return() -> impl Debug;
-    //~^ ERROR `impl Trait` not allowed outside of function and method return types
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
 }
 
 // Allowed
@@ -155,97 +155,97 @@ type InTypeAlias<R> = impl Debug;
 //~^ ERROR `impl Trait` in type aliases is unstable
 
 type InReturnInTypeAlias<R> = fn() -> impl Debug;
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 //~| ERROR `impl Trait` in type aliases is unstable
 
 // Disallowed in impl headers
 impl PartialEq<impl Debug> for () {
-    //~^ ERROR `impl Trait` not allowed outside of function and method return types
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
 }
 
 // Disallowed in impl headers
 impl PartialEq<()> for impl Debug {
-    //~^ ERROR `impl Trait` not allowed outside of function and method return types
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
 }
 
 // Disallowed in inherent impls
 impl impl Debug {
-    //~^ ERROR `impl Trait` not allowed outside of function and method return types
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
 }
 
 // Disallowed in inherent impls
 struct InInherentImplAdt<T> { t: T }
 impl InInherentImplAdt<impl Debug> {
-    //~^ ERROR `impl Trait` not allowed outside of function and method return types
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
 }
 
 // Disallowed in where clauses
 fn in_fn_where_clause()
     where impl Debug: Debug
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 {
 }
 
 // Disallowed in where clauses
 fn in_adt_in_fn_where_clause()
     where Vec<impl Debug>: Debug
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 {
 }
 
 // Disallowed
 fn in_trait_parameter_in_fn_where_clause<T>()
     where T: PartialEq<impl Debug>
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 {
 }
 
 // Disallowed
 fn in_Fn_parameter_in_fn_where_clause<T>()
     where T: Fn(impl Debug)
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 {
 }
 
 // Disallowed
 fn in_Fn_return_in_fn_where_clause<T>()
     where T: Fn() -> impl Debug
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 {
 }
 
 // Disallowed
 struct InStructGenericParamDefault<T = impl Debug>(T);
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 trait InTraitGenericParamDefault<T = impl Debug> {}
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 type InTypeAliasGenericParamDefault<T = impl Debug> = T;
-//~^ ERROR `impl Trait` not allowed outside of function and method return types
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 // Disallowed
 impl <T = impl Debug> T {}
 //~^ ERROR defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
 //~| WARNING this was previously accepted by the compiler but is being phased out
-//~| ERROR `impl Trait` not allowed outside of function and method return types
+//~| ERROR `impl Trait` only allowed in function and inherent method return types
 //~| ERROR no nominal type found
 
 // Disallowed
 fn in_method_generic_param_default<T = impl Debug>(_: T) {}
 //~^ ERROR defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
 //~| WARNING this was previously accepted by the compiler but is being phased out
-//~| ERROR `impl Trait` not allowed outside of function and method return types
+//~| ERROR `impl Trait` only allowed in function and inherent method return types
 
 fn main() {
     let _in_local_variable: impl Fn() = || {};
-    //~^ ERROR `impl Trait` not allowed outside of function and method return types
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
     let _in_return_in_local_variable = || -> impl Fn() { || {} };
-    //~^ ERROR `impl Trait` not allowed outside of function and method return types
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
 }
diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr
index 236cf449e85..eef20c2de94 100644
--- a/src/test/ui/impl-trait/where-allowed.stderr
+++ b/src/test/ui/impl-trait/where-allowed.stderr
@@ -43,247 +43,247 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer param
   --> $DIR/where-allowed.rs:15:40
    |
 LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
   --> $DIR/where-allowed.rs:19:42
    |
 LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
    |                                          ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer param
   --> $DIR/where-allowed.rs:23:38
    |
 LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
    |                                      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
   --> $DIR/where-allowed.rs:27:40
    |
 LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
   --> $DIR/where-allowed.rs:31:49
    |
 LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
    |                                                 ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
   --> $DIR/where-allowed.rs:35:51
    |
 LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
    |                                                   ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
   --> $DIR/where-allowed.rs:39:55
    |
 LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
    |                                                       ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
   --> $DIR/where-allowed.rs:43:57
    |
 LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
    |                                                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
   --> $DIR/where-allowed.rs:47:51
    |
 LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
    |                                                   ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
   --> $DIR/where-allowed.rs:52:53
    |
 LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
    |                                                     ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
   --> $DIR/where-allowed.rs:56:57
    |
 LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
    |                                                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
   --> $DIR/where-allowed.rs:61:59
    |
 LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
    |                                                           ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
   --> $DIR/where-allowed.rs:65:38
    |
 LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
    |                                      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
   --> $DIR/where-allowed.rs:69:40
    |
 LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:82:32
    |
 LL | struct InBraceStructField { x: impl Debug }
    |                                ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in path
   --> $DIR/where-allowed.rs:86:41
    |
 LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
    |                                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:90:27
    |
 LL | struct InTupleStructField(impl Debug);
    |                           ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:95:25
    |
 LL |     InBraceVariant { x: impl Debug },
    |                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:97:20
    |
 LL |     InTupleVariant(impl Debug),
    |                    ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
   --> $DIR/where-allowed.rs:108:23
    |
 LL |     fn in_return() -> impl Debug;
    |                       ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return
   --> $DIR/where-allowed.rs:125:34
    |
 LL |     fn in_trait_impl_return() -> impl Debug { () }
    |                                  ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` param
   --> $DIR/where-allowed.rs:138:33
    |
 LL |     fn in_foreign_parameters(_: impl Debug);
    |                                 ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` return
   --> $DIR/where-allowed.rs:141:31
    |
 LL |     fn in_foreign_return() -> impl Debug;
    |                               ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
   --> $DIR/where-allowed.rs:157:39
    |
 LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait
   --> $DIR/where-allowed.rs:162:16
    |
 LL | impl PartialEq<impl Debug> for () {
    |                ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:167:24
    |
 LL | impl PartialEq<()> for impl Debug {
    |                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:172:6
    |
 LL | impl impl Debug {
    |      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:178:24
    |
 LL | impl InInherentImplAdt<impl Debug> {
    |                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:184:11
    |
 LL |     where impl Debug: Debug
    |           ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:191:15
    |
 LL |     where Vec<impl Debug>: Debug
    |               ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound
   --> $DIR/where-allowed.rs:198:24
    |
 LL |     where T: PartialEq<impl Debug>
    |                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
   --> $DIR/where-allowed.rs:205:17
    |
 LL |     where T: Fn(impl Debug)
    |                 ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
   --> $DIR/where-allowed.rs:212:22
    |
 LL |     where T: Fn() -> impl Debug
    |                      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:218:40
    |
 LL | struct InStructGenericParamDefault<T = impl Debug>(T);
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:222:36
    |
 LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
    |                                    ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:226:38
    |
 LL | trait InTraitGenericParamDefault<T = impl Debug> {}
    |                                      ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:230:41
    |
 LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T;
    |                                         ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:234:11
    |
 LL | impl <T = impl Debug> T {}
    |           ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
   --> $DIR/where-allowed.rs:241:40
    |
 LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    |                                        ^^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
   --> $DIR/where-allowed.rs:247:29
    |
 LL |     let _in_local_variable: impl Fn() = || {};
    |                             ^^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in closure return
   --> $DIR/where-allowed.rs:249:46
    |
 LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
diff --git a/src/test/ui/invalid/invalid-no-sanitize.stderr b/src/test/ui/invalid/invalid-no-sanitize.stderr
index 4c0b17c7d37..5a92555eb32 100644
--- a/src/test/ui/invalid/invalid-no-sanitize.stderr
+++ b/src/test/ui/invalid/invalid-no-sanitize.stderr
@@ -4,7 +4,7 @@ error: invalid argument for `no_sanitize`
 LL | #[no_sanitize(brontosaurus)]
    |               ^^^^^^^^^^^^
    |
-   = note: expected one of: `address`, `hwaddress`, `memory` or `thread`
+   = note: expected one of: `address`, `cfi`, `hwaddress`, `memory`, `memtag`, or `thread`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-13497-2.rs b/src/test/ui/issues/issue-13497-2.rs
index 32abe2b8543..c82da0f0096 100644
--- a/src/test/ui/issues/issue-13497-2.rs
+++ b/src/test/ui/issues/issue-13497-2.rs
@@ -1,7 +1,7 @@
 fn read_lines_borrowed<'a>() -> Vec<&'a str> {
     let rawLines: Vec<String> = vec!["foo  ".to_string(), "  bar".to_string()];
-    rawLines.iter().map(|l| l.trim()).collect()
-    //~^ ERROR cannot return value referencing local variable `rawLines`
+    rawLines //~ ERROR cannot return value referencing local variable `rawLines`
+        .iter().map(|l| l.trim()).collect()
 }
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-13497-2.stderr b/src/test/ui/issues/issue-13497-2.stderr
index 1b78e7ec1c6..6f72b79f2a5 100644
--- a/src/test/ui/issues/issue-13497-2.stderr
+++ b/src/test/ui/issues/issue-13497-2.stderr
@@ -1,10 +1,14 @@
 error[E0515]: cannot return value referencing local variable `rawLines`
-  --> $DIR/issue-13497-2.rs:3:29
+  --> $DIR/issue-13497-2.rs:3:5
    |
-LL |     rawLines.iter().map(|l| l.trim()).collect()
-   |     ---------------         ^^^^^^^^ returns a value referencing data owned by the current function
-   |     |
-   |     `rawLines` is borrowed here
+LL |        rawLines
+   |   _____^
+   |  |_____|
+   | ||
+LL | ||         .iter().map(|l| l.trim()).collect()
+   | ||_______________-___________________________^ returns a value referencing data owned by the current function
+   | |________________|
+   |                  `rawLines` is borrowed here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-14772.rs b/src/test/ui/issues/issue-14772.rs
deleted file mode 100644
index 8f6745246fd..00000000000
--- a/src/test/ui/issues/issue-14772.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-// compile-flags: --test
-
-#[test]
-mod foo {} //~ ERROR only functions may be used as tests
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-14772.stderr b/src/test/ui/issues/issue-14772.stderr
deleted file mode 100644
index 253fec5e578..00000000000
--- a/src/test/ui/issues/issue-14772.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: only functions may be used as tests
-  --> $DIR/issue-14772.rs:4:1
-   |
-LL | mod foo {}
-   | ^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-47715.rs b/src/test/ui/issues/issue-47715.rs
index 478ac6a2e89..b8088c18dad 100644
--- a/src/test/ui/issues/issue-47715.rs
+++ b/src/test/ui/issues/issue-47715.rs
@@ -7,22 +7,22 @@ trait Iterable {
 }
 
 struct Container<T: Iterable<Item = impl Foo>> {
-    //~^ ERROR `impl Trait` not allowed
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
     field: T
 }
 
 enum Enum<T: Iterable<Item = impl Foo>> {
-    //~^ ERROR `impl Trait` not allowed
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
     A(T),
 }
 
 union Union<T: Iterable<Item = impl Foo> + Copy> {
-    //~^ ERROR `impl Trait` not allowed
+    //~^ ERROR `impl Trait` only allowed in function and inherent method return types
     x: T,
 }
 
 type Type<T: Iterable<Item = impl Foo>> = T;
-//~^ ERROR `impl Trait` not allowed
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types
 
 fn main() {
 }
diff --git a/src/test/ui/issues/issue-47715.stderr b/src/test/ui/issues/issue-47715.stderr
index 63a28d997e1..0ee9388bf2b 100644
--- a/src/test/ui/issues/issue-47715.stderr
+++ b/src/test/ui/issues/issue-47715.stderr
@@ -1,22 +1,22 @@
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic
   --> $DIR/issue-47715.rs:9:37
    |
 LL | struct Container<T: Iterable<Item = impl Foo>> {
    |                                     ^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic
   --> $DIR/issue-47715.rs:14:30
    |
 LL | enum Enum<T: Iterable<Item = impl Foo>> {
    |                              ^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic
   --> $DIR/issue-47715.rs:19:32
    |
 LL | union Union<T: Iterable<Item = impl Foo> + Copy> {
    |                                ^^^^^^^^
 
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic
   --> $DIR/issue-47715.rs:24:30
    |
 LL | type Type<T: Iterable<Item = impl Foo>> = T;
diff --git a/src/test/ui/issues/issue-68696-catch-during-unwind.rs b/src/test/ui/issues/issue-68696-catch-during-unwind.rs
index f25a78f59cd..2b12a62d0eb 100644
--- a/src/test/ui/issues/issue-68696-catch-during-unwind.rs
+++ b/src/test/ui/issues/issue-68696-catch-during-unwind.rs
@@ -4,7 +4,6 @@
 // entering the catch_unwind.
 //
 // run-pass
-#![feature(cfg_panic)]
 
 use std::panic::catch_unwind;
 
diff --git a/src/test/ui/return/return-impl-trait-bad.rs b/src/test/ui/return/return-impl-trait-bad.rs
new file mode 100644
index 00000000000..e3f6ddb9a14
--- /dev/null
+++ b/src/test/ui/return/return-impl-trait-bad.rs
@@ -0,0 +1,31 @@
+trait Trait {}
+impl Trait for () {}
+
+fn bad_echo<T>(_t: T) -> T {
+    "this should not suggest impl Trait" //~ ERROR mismatched types
+}
+
+fn bad_echo_2<T: Trait>(_t: T) -> T {
+    "this will not suggest it, because that would probably be wrong" //~ ERROR mismatched types
+}
+
+fn other_bounds_bad<T>() -> T
+where
+    T: Send,
+    Option<T>: Send,
+{
+    "don't suggest this, because Option<T> places additional constraints" //~ ERROR mismatched types
+}
+
+// FIXME: implement this check
+trait GenericTrait<T> {}
+
+fn used_in_trait<T>() -> T
+where
+    T: Send,
+    (): GenericTrait<T>,
+{
+    "don't suggest this, because the generic param is used in the bound." //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/return/return-impl-trait-bad.stderr b/src/test/ui/return/return-impl-trait-bad.stderr
new file mode 100644
index 00000000000..237b85ee66a
--- /dev/null
+++ b/src/test/ui/return/return-impl-trait-bad.stderr
@@ -0,0 +1,59 @@
+error[E0308]: mismatched types
+  --> $DIR/return-impl-trait-bad.rs:5:5
+   |
+LL | fn bad_echo<T>(_t: T) -> T {
+   |             -            - expected `T` because of return type
+   |             |
+   |             this type parameter
+LL |     "this should not suggest impl Trait"
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found `&str`
+   |
+   = note: expected type parameter `T`
+                   found reference `&'static str`
+
+error[E0308]: mismatched types
+  --> $DIR/return-impl-trait-bad.rs:9:5
+   |
+LL | fn bad_echo_2<T: Trait>(_t: T) -> T {
+   |               -                   - expected `T` because of return type
+   |               |
+   |               this type parameter
+LL |     "this will not suggest it, because that would probably be wrong"
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found `&str`
+   |
+   = note: expected type parameter `T`
+                   found reference `&'static str`
+
+error[E0308]: mismatched types
+  --> $DIR/return-impl-trait-bad.rs:17:5
+   |
+LL | fn other_bounds_bad<T>() -> T
+   |                     -       - expected `T` because of return type
+   |                     |
+   |                     this type parameter
+...
+LL |     "don't suggest this, because Option<T> places additional constraints"
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found `&str`
+   |
+   = note: expected type parameter `T`
+                   found reference `&'static str`
+
+error[E0308]: mismatched types
+  --> $DIR/return-impl-trait-bad.rs:28:5
+   |
+LL | fn used_in_trait<T>() -> T
+   |                  -       -
+   |                  |       |
+   |                  |       expected `T` because of return type
+   |                  |       help: consider using an impl return type: `impl Send`
+   |                  this type parameter
+...
+LL |     "don't suggest this, because the generic param is used in the bound."
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found `&str`
+   |
+   = note: expected type parameter `T`
+                   found reference `&'static str`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/return/return-impl-trait.fixed b/src/test/ui/return/return-impl-trait.fixed
new file mode 100644
index 00000000000..ff2b02f73ea
--- /dev/null
+++ b/src/test/ui/return/return-impl-trait.fixed
@@ -0,0 +1,30 @@
+// run-rustfix
+
+trait Trait {}
+impl Trait for () {}
+
+// this works
+fn foo() -> impl Trait {
+    ()
+}
+
+fn bar<T: Trait + std::marker::Sync>() -> impl Trait + std::marker::Sync + Send
+where
+    T: Send,
+{
+    () //~ ERROR mismatched types
+}
+
+fn other_bounds<T>() -> impl Trait
+where
+    T: Trait,
+    Vec<usize>: Clone,
+{
+    () //~ ERROR mismatched types
+}
+
+fn main() {
+    foo();
+    bar::<()>();
+    other_bounds::<()>();
+}
diff --git a/src/test/ui/return/return-impl-trait.rs b/src/test/ui/return/return-impl-trait.rs
new file mode 100644
index 00000000000..e905d712f62
--- /dev/null
+++ b/src/test/ui/return/return-impl-trait.rs
@@ -0,0 +1,30 @@
+// run-rustfix
+
+trait Trait {}
+impl Trait for () {}
+
+// this works
+fn foo() -> impl Trait {
+    ()
+}
+
+fn bar<T: Trait + std::marker::Sync>() -> T
+where
+    T: Send,
+{
+    () //~ ERROR mismatched types
+}
+
+fn other_bounds<T>() -> T
+where
+    T: Trait,
+    Vec<usize>: Clone,
+{
+    () //~ ERROR mismatched types
+}
+
+fn main() {
+    foo();
+    bar::<()>();
+    other_bounds::<()>();
+}
diff --git a/src/test/ui/return/return-impl-trait.stderr b/src/test/ui/return/return-impl-trait.stderr
new file mode 100644
index 00000000000..43d40972fca
--- /dev/null
+++ b/src/test/ui/return/return-impl-trait.stderr
@@ -0,0 +1,34 @@
+error[E0308]: mismatched types
+  --> $DIR/return-impl-trait.rs:15:5
+   |
+LL | fn bar<T: Trait + std::marker::Sync>() -> T
+   |        -                                  -
+   |        |                                  |
+   |        |                                  expected `T` because of return type
+   |        this type parameter                help: consider using an impl return type: `impl Trait + std::marker::Sync + Send`
+...
+LL |     ()
+   |     ^^ expected type parameter `T`, found `()`
+   |
+   = note: expected type parameter `T`
+                   found unit type `()`
+
+error[E0308]: mismatched types
+  --> $DIR/return-impl-trait.rs:23:5
+   |
+LL | fn other_bounds<T>() -> T
+   |                 -       -
+   |                 |       |
+   |                 |       expected `T` because of return type
+   |                 |       help: consider using an impl return type: `impl Trait`
+   |                 this type parameter
+...
+LL |     ()
+   |     ^^ expected type parameter `T`, found `()`
+   |
+   = note: expected type parameter `T`
+                   found unit type `()`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
index aaed3665149..57374b7e3bb 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
@@ -20,8 +20,9 @@ error: lifetime may not live long enough
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
    |
 LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
-   |                  --  ---- has type `Pin<&'1 Foo>`              ^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
-   |                  |
+   |                  --              -                             ^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
+   |                  |               |
+   |                  |               let's call the lifetime of this reference `'1`
    |                  lifetime `'a` defined here
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
index 042ae53dba1..299a2d2f2d3 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
@@ -2,25 +2,25 @@ error[E0623]: lifetime mismatch
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52
    |
 LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
-   |                          ----      ----            ^ ...but data from `f` flows into `self` here
+   |                                    ----     ----   ^ ...but data from `f` is returned here
    |                                    |
-   |                                    these two types are declared with different lifetimes...
+   |                                    this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:82
    |
 LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
-   |                          -----      ----                                         ^ ...but data from `f` flows into `self` here
+   |                                     ----              -----------------          ^ ...but data from `f` is returned here
    |                                     |
-   |                                     these two types are declared with different lifetimes...
+   |                                     this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
    |
 LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
-   |                                  -----        ------           ^^^ ...but data from `arg` flows into `self` here
+   |                                               ------     ---   ^^^ ...but data from `arg` is returned here
    |                                               |
-   |                                               these two types are declared with different lifetimes...
+   |                                               this parameter and the return type are declared with different lifetimes...
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/self/elision/lt-ref-self-async.stderr b/src/test/ui/self/elision/lt-ref-self-async.stderr
index ae484670213..7448e8484b4 100644
--- a/src/test/ui/self/elision/lt-ref-self-async.stderr
+++ b/src/test/ui/self/elision/lt-ref-self-async.stderr
@@ -2,49 +2,61 @@ error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self-async.rs:13:9
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
-   |                       -----     ---- these two types are declared with different lifetimes...
+   |                                 ----     ----
+   |                                 |
+   |                                 this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self-async.rs:19:9
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
-   |                             -----     ---- these two types are declared with different lifetimes...
+   |                                       ----     ----
+   |                                       |
+   |                                       this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self-async.rs:23:9
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
-   |                                     -----      ---- these two types are declared with different lifetimes...
+   |                                                ----     ----
+   |                                                |
+   |                                                this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self-async.rs:27:9
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
-   |                                     -----      ---- these two types are declared with different lifetimes...
+   |                                                ----     ----
+   |                                                |
+   |                                                this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self-async.rs:31:9
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
-   |                                             -----       ---- these two types are declared with different lifetimes...
+   |                                                         ----     ----
+   |                                                         |
+   |                                                         this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self-async.rs:35:9
    |
 LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
-   |                                         -----       ---- these two types are declared with different lifetimes...
+   |                                                     ----     ----
+   |                                                     |
+   |                                                     this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/self/elision/ref-mut-self-async.stderr b/src/test/ui/self/elision/ref-mut-self-async.stderr
index 7b984b343d6..6056cc46d3d 100644
--- a/src/test/ui/self/elision/ref-mut-self-async.stderr
+++ b/src/test/ui/self/elision/ref-mut-self-async.stderr
@@ -2,49 +2,61 @@ error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self-async.rs:13:9
    |
 LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
-   |                       ---------     ---- these two types are declared with different lifetimes...
+   |                                     ----     ----
+   |                                     |
+   |                                     this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self-async.rs:19:9
    |
 LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
-   |                             ---------     ---- these two types are declared with different lifetimes...
+   |                                           ----     ----
+   |                                           |
+   |                                           this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self-async.rs:23:9
    |
 LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
-   |                                     ---------      ---- these two types are declared with different lifetimes...
+   |                                                    ----     ----
+   |                                                    |
+   |                                                    this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self-async.rs:27:9
    |
 LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
-   |                                     ---------      ---- these two types are declared with different lifetimes...
+   |                                                    ----     ----
+   |                                                    |
+   |                                                    this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self-async.rs:31:9
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
-   |                                             ---------       ---- these two types are declared with different lifetimes...
+   |                                                             ----     ----
+   |                                                             |
+   |                                                             this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self-async.rs:35:9
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
-   |                                             ---------       ---- these two types are declared with different lifetimes...
+   |                                                             ----     ----
+   |                                                             |
+   |                                                             this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.stderr b/src/test/ui/self/elision/ref-mut-struct-async.stderr
index 87a144f62f6..61034ae4d47 100644
--- a/src/test/ui/self/elision/ref-mut-struct-async.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr
@@ -2,41 +2,51 @@ error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct-async.rs:13:9
    |
 LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
-   |                               -----------     ---- these two types are declared with different lifetimes...
+   |                                               ----     ----
+   |                                               |
+   |                                               this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct-async.rs:17:9
    |
 LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
-   |                                       -----------      ---- these two types are declared with different lifetimes...
+   |                                                        ----     ----
+   |                                                        |
+   |                                                        this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct-async.rs:21:9
    |
 LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
-   |                                       -----------      ---- these two types are declared with different lifetimes...
+   |                                                        ----     ----
+   |                                                        |
+   |                                                        this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct-async.rs:25:9
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
-   |                                               -----------       ---- these two types are declared with different lifetimes...
+   |                                                                 ----     ----
+   |                                                                 |
+   |                                                                 this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct-async.rs:29:9
    |
 LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
-   |                                               -----------       ---- these two types are declared with different lifetimes...
+   |                                                                 ----     ----
+   |                                                                 |
+   |                                                                 this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr
index 15c20c1bc4d..0eab16e685d 100644
--- a/src/test/ui/self/elision/ref-self-async.stderr
+++ b/src/test/ui/self/elision/ref-self-async.stderr
@@ -2,57 +2,71 @@ error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:23:9
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
-   |                       -----     ---- these two types are declared with different lifetimes...
+   |                                 ----     ----
+   |                                 |
+   |                                 this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:29:9
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
-   |                             -----     ---- these two types are declared with different lifetimes...
+   |                                       ----     ----
+   |                                       |
+   |                                       this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:33:9
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
-   |                                     -----      ---- these two types are declared with different lifetimes...
+   |                                                ----     ----
+   |                                                |
+   |                                                this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:37:9
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
-   |                                     -----      ---- these two types are declared with different lifetimes...
+   |                                                ----     ----
+   |                                                |
+   |                                                this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:41:9
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
-   |                                             -----       ---- these two types are declared with different lifetimes...
+   |                                                         ----     ----
+   |                                                         |
+   |                                                         this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:45:9
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
-   |                                             -----       ---- these two types are declared with different lifetimes...
+   |                                                         ----     ----
+   |                                                         |
+   |                                                         this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:49:9
    |
 LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
-   |                                            -----            --- these two types are declared with different lifetimes...
+   |                                                             ---     ---
+   |                                                             |
+   |                                                             this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.stderr
index f24be3b58a7..aa1d7453e83 100644
--- a/src/test/ui/self/elision/ref-struct-async.stderr
+++ b/src/test/ui/self/elision/ref-struct-async.stderr
@@ -2,41 +2,51 @@ error[E0623]: lifetime mismatch
   --> $DIR/ref-struct-async.rs:13:9
    |
 LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
-   |                               -------     ---- these two types are declared with different lifetimes...
+   |                                           ----     ----
+   |                                           |
+   |                                           this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-struct-async.rs:17:9
    |
 LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
-   |                                       -------      ---- these two types are declared with different lifetimes...
+   |                                                    ----     ----
+   |                                                    |
+   |                                                    this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-struct-async.rs:21:9
    |
 LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
-   |                                       -------      ---- these two types are declared with different lifetimes...
+   |                                                    ----     ----
+   |                                                    |
+   |                                                    this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-struct-async.rs:25:9
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
-   |                                               -------       ---- these two types are declared with different lifetimes...
+   |                                                             ----     ----
+   |                                                             |
+   |                                                             this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-struct-async.rs:29:9
    |
 LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
-   |                                           -------       ---- these two types are declared with different lifetimes...
+   |                                                         ----     ----
+   |                                                         |
+   |                                                         this parameter and the return type are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` flows into `self` here
+   |         ^ ...but data from `f` is returned here
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/test-attrs/test-on-macro.rs b/src/test/ui/test-attrs/test-on-macro.rs
deleted file mode 100644
index 0667364d13c..00000000000
--- a/src/test/ui/test-attrs/test-on-macro.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// check-pass
-// compile-flags:--test
-
-#![deny(warnings)]
-
-macro_rules! foo {
-    () => (fn foo(){})
-}
-
-#[test]
-foo!(); //~ WARNING `#[test]` attribute should not be used on macros
-
-fn main(){}
diff --git a/src/test/ui/test-attrs/test-on-macro.stderr b/src/test/ui/test-attrs/test-on-macro.stderr
deleted file mode 100644
index 98190b060ce..00000000000
--- a/src/test/ui/test-attrs/test-on-macro.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: `#[test]` attribute should not be used on macros. Use `#[cfg(test)]` instead.
-  --> $DIR/test-on-macro.rs:11:1
-   |
-LL | foo!();
-   | ^^^^^^^
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/test-attrs/test-on-not-fn.rs b/src/test/ui/test-attrs/test-on-not-fn.rs
new file mode 100644
index 00000000000..b2f681c01d1
--- /dev/null
+++ b/src/test/ui/test-attrs/test-on-not-fn.rs
@@ -0,0 +1,80 @@
+// compile-flags: --test
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+mod test {}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+mod loooooooooooooong_teeeeeeeeeest {
+    /*
+    this is a comment
+    this comment goes on for a very long time
+    this is to pad out the span for this module for a long time
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
+    labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
+    laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
+    voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
+    non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+    */
+}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+extern "C" {}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+trait Foo {}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+impl Foo for i32 {}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+const FOO: i32 = -1_i32;
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+static BAR: u64 = 10_000_u64;
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+enum MyUnit {
+    Unit,
+}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+struct NewI32(i32);
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+union Spooky {
+    x: i32,
+    y: u32,
+}
+
+#[repr(C, align(64))]
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+#[derive(Copy, Clone, Debug)]
+struct MoreAttrs {
+    a: i32,
+    b: u64,
+}
+
+macro_rules! foo {
+    () => {};
+}
+
+#[test] //~ ERROR: the `#[test]` attribute may only be used on a non-associated function
+foo!();
+
+// make sure it doesn't erroneously trigger on a real test
+#[test]
+fn real_test() {
+    assert_eq!(42_i32, 42_i32);
+}
+
+// make sure it works with cfg test
+#[cfg(test)]
+mod real_tests {
+    #[cfg(test)]
+    fn foo() {}
+
+    #[test]
+    fn bar() {
+        foo();
+    }
+}
diff --git a/src/test/ui/test-attrs/test-on-not-fn.stderr b/src/test/ui/test-attrs/test-on-not-fn.stderr
new file mode 100644
index 00000000000..dd693cf316d
--- /dev/null
+++ b/src/test/ui/test-attrs/test-on-not-fn.stderr
@@ -0,0 +1,185 @@
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:3:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | mod test {}
+   | ----------- expected a non-associated function, found a module
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:6:1
+   |
+LL |   #[test]
+   |   ^^^^^^^
+LL | / mod loooooooooooooong_teeeeeeeeeest {
+LL | |     /*
+LL | |     this is a comment
+LL | |     this comment goes on for a very long time
+...  |
+LL | |     */
+LL | | }
+   | |_- expected a non-associated function, found a module
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:20:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | extern "C" {}
+   | ------------- expected a non-associated function, found an extern block
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:23:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | trait Foo {}
+   | ------------ expected a non-associated function, found a trait
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:26:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | impl Foo for i32 {}
+   | ------------------- expected a non-associated function, found an implementation
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:29:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | const FOO: i32 = -1_i32;
+   | ------------------------ expected a non-associated function, found a constant item
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:32:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | static BAR: u64 = 10_000_u64;
+   | ----------------------------- expected a non-associated function, found a static item
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:35:1
+   |
+LL |   #[test]
+   |   ^^^^^^^
+LL | / enum MyUnit {
+LL | |     Unit,
+LL | | }
+   | |_- expected a non-associated function, found an enum
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:40:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | struct NewI32(i32);
+   | ------------------- expected a non-associated function, found a struct
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:43:1
+   |
+LL |   #[test]
+   |   ^^^^^^^
+LL | / union Spooky {
+LL | |     x: i32,
+LL | |     y: u32,
+LL | | }
+   | |_- expected a non-associated function, found a union
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:50:1
+   |
+LL |   #[test]
+   |   ^^^^^^^
+LL |   #[derive(Copy, Clone, Debug)]
+LL | / struct MoreAttrs {
+LL | |     a: i32,
+LL | |     b: u64,
+LL | | }
+   | |_- expected a non-associated function, found a struct
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: the `#[test]` attribute may only be used on a non-associated function
+  --> $DIR/test-on-not-fn.rs:61:1
+   |
+LL | #[test]
+   | ^^^^^^^
+LL | foo!();
+   | ------- expected a non-associated function, found an item macro invocation
+   |
+   = note: the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions
+help: replace with conditional compilation to make the item only exist when tests are being run
+   |
+LL | #[cfg(test)]
+   | ~~~~~~~~~~~~
+
+error: aborting due to 12 previous errors
+
diff --git a/src/test/ui/trait-bounds/issue-93008.rs b/src/test/ui/trait-bounds/issue-93008.rs
new file mode 100644
index 00000000000..1b010566cbc
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-93008.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Zmir-opt-level=4
+
+pub fn bar<T>(s: &'static mut ())
+where
+    &'static mut (): Clone, //~ ERROR the trait bound
+{
+    <&'static mut () as Clone>::clone(&s);
+}
+
+fn main() {}
diff --git a/src/test/ui/trait-bounds/issue-93008.stderr b/src/test/ui/trait-bounds/issue-93008.stderr
new file mode 100644
index 00000000000..10f80f8de0c
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-93008.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the trait bound `&'static mut (): Clone` is not satisfied
+  --> $DIR/issue-93008.rs:5:5
+   |
+LL |     &'static mut (): Clone,
+   |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `&'static mut ()`
+   |
+   = help: see issue #48214
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs
index 299bdf562dc..857066c78c9 100644
--- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs
@@ -4,7 +4,7 @@
 // FIXME: this is ruled out for now but should work
 
 type Foo = fn() -> impl Send;
-//~^ ERROR: `impl Trait` not allowed outside of function and method return types
+//~^ ERROR: `impl Trait` only allowed in function and inherent method return types
 
 fn make_foo() -> Foo {
     || 15
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr
index 1c5d57d4af7..a31cf1a51cc 100644
--- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr
@@ -1,4 +1,4 @@
-error[E0562]: `impl Trait` not allowed outside of function and method return types
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
   --> $DIR/type-alias-impl-trait-fn-type.rs:6:20
    |
 LL | type Foo = fn() -> impl Send;
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 6d0851d804c..fe391198342 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -528,7 +528,7 @@ fn is_auto_reborrow_position(parent: Option<Node<'_>>) -> bool {
 fn is_auto_borrow_position(parent: Option<Node<'_>>, child_id: HirId) -> bool {
     if let Some(Node::Expr(parent)) = parent {
         match parent.kind {
-            ExprKind::MethodCall(_, [self_arg, ..], _) => self_arg.hir_id == child_id,
+            // ExprKind::MethodCall(_, [self_arg, ..], _) => self_arg.hir_id == child_id,
             ExprKind::Field(..) => true,
             ExprKind::Call(f, _) => f.hir_id == child_id,
             _ => false,
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.fixed b/src/tools/clippy/tests/ui/manual_async_fn.fixed
index e9ca66f125d..136cc96be70 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.fixed
+++ b/src/tools/clippy/tests/ui/manual_async_fn.fixed
@@ -80,7 +80,6 @@ fn elided_not_bound(_: &i32) -> impl Future<Output = i32> {
     async { 42 }
 }
 
-#[allow(clippy::needless_lifetimes)]
 async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 }
 
 // should be ignored
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.rs b/src/tools/clippy/tests/ui/manual_async_fn.rs
index c3fa846485b..ddc453ffdb7 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.rs
+++ b/src/tools/clippy/tests/ui/manual_async_fn.rs
@@ -98,7 +98,6 @@ fn elided_not_bound(_: &i32) -> impl Future<Output = i32> {
     async { 42 }
 }
 
-#[allow(clippy::needless_lifetimes)]
 fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
     async { 42 }
 }
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.stderr b/src/tools/clippy/tests/ui/manual_async_fn.stderr
index b83abfccd4e..7435f46074c 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.stderr
+++ b/src/tools/clippy/tests/ui/manual_async_fn.stderr
@@ -140,7 +140,7 @@ LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ { 42 }
    |                                                      ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> $DIR/manual_async_fn.rs:102:1
+  --> $DIR/manual_async_fn.rs:101:1
    |
 LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed
index b856f1375d3..efeb5cf5b2b 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrow.fixed
@@ -64,9 +64,9 @@ fn main() {
     *x = 5;
 
     let s = String::new();
-    let _ = s.len();
-    let _ = s.capacity();
-    let _ = s.capacity();
+    // let _ = (&s).len();
+    // let _ = (&s).capacity();
+    // let _ = (&&s).capacity();
 
     let x = (1, 2);
     let _ = x.0;
diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs
index 0bfe222a3dc..3e416a0eb84 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.rs
+++ b/src/tools/clippy/tests/ui/needless_borrow.rs
@@ -64,9 +64,9 @@ fn main() {
     *x = 5;
 
     let s = String::new();
-    let _ = (&s).len();
-    let _ = (&s).capacity();
-    let _ = (&&s).capacity();
+    // let _ = (&s).len();
+    // let _ = (&s).capacity();
+    // let _ = (&&s).capacity();
 
     let x = (1, 2);
     let _ = (&x).0;
diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr
index b90e8448db0..05591ce4117 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow.stderr
@@ -85,24 +85,6 @@ LL |     let y: &mut i32 = &mut &mut x;
    |                       ^^^^^^^^^^^ help: change this to: `x`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:67:13
-   |
-LL |     let _ = (&s).len();
-   |             ^^^^ help: change this to: `s`
-
-error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:68:13
-   |
-LL |     let _ = (&s).capacity();
-   |             ^^^^ help: change this to: `s`
-
-error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:69:13
-   |
-LL |     let _ = (&&s).capacity();
-   |             ^^^^^ help: change this to: `s`
-
-error: this expression borrows a value the compiler would automatically borrow
   --> $DIR/needless_borrow.rs:72:13
    |
 LL |     let _ = (&x).0;
@@ -114,5 +96,5 @@ error: this expression borrows a value the compiler would automatically borrow
 LL |     let _ = unsafe { (&*x).0 };
    |                      ^^^^^ help: change this to: `(*x)`
 
-error: aborting due to 19 previous errors
+error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.stderr b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
index 8df50d79ca5..ffa152427a9 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
@@ -19,12 +19,6 @@ LL | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
-  --> $DIR/needless_lifetimes.rs:37:1
-   |
-LL | async fn func<'a>(args: &[&'a str]) -> Option<&'a str> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
   --> $DIR/needless_lifetimes.rs:56:1
    |
 LL | fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> {
@@ -198,5 +192,5 @@ error: explicit lifetimes given in parameter types where they could be elided (o
 LL |         fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 33 previous errors
+error: aborting due to 32 previous errors
 
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index da7a19139c6..887d27fd6dc 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -41,12 +41,15 @@ impl EarlyProps {
     pub fn from_reader<R: Read>(config: &Config, testfile: &Path, rdr: R) -> Self {
         let mut props = EarlyProps::default();
         iter_header(testfile, rdr, &mut |_, ln| {
-            if let Some(s) = config.parse_aux_build(ln) {
-                props.aux.push(s);
-            }
-            if let Some(ac) = config.parse_aux_crate(ln) {
-                props.aux_crate.push(ac);
-            }
+            config.push_name_value_directive(ln, directives::AUX_BUILD, &mut props.aux, |r| {
+                r.trim().to_string()
+            });
+            config.push_name_value_directive(
+                ln,
+                directives::AUX_CRATE,
+                &mut props.aux_crate,
+                Config::parse_aux_crate,
+            );
             config.parse_and_update_revisions(ln, &mut props.revisions);
         });
         return props;
@@ -126,6 +129,12 @@ pub struct TestProps {
     // empty before the test starts. Incremental mode tests will reuse the
     // incremental directory between passes in the same test.
     pub incremental: bool,
+    // If `true`, this test is a known bug.
+    //
+    // When set, some requirements are relaxed. Currently, this only means no
+    // error annotations are needed, but this may be updated in the future to
+    // include other relaxations.
+    pub known_bug: bool,
     // How far should the test proceed while still passing.
     pass_mode: Option<PassMode>,
     // Ignore `--pass` overrides from the command line for this test.
@@ -150,6 +159,38 @@ pub struct TestProps {
     pub stderr_per_bitwidth: bool,
 }
 
+mod directives {
+    pub const ERROR_PATTERN: &'static str = "error-pattern";
+    pub const COMPILE_FLAGS: &'static str = "compile-flags";
+    pub const RUN_FLAGS: &'static str = "run-flags";
+    pub const SHOULD_ICE: &'static str = "should-ice";
+    pub const BUILD_AUX_DOCS: &'static str = "build-aux-docs";
+    pub const FORCE_HOST: &'static str = "force-host";
+    pub const CHECK_STDOUT: &'static str = "check-stdout";
+    pub const CHECK_RUN_RESULTS: &'static str = "check-run-results";
+    pub const DONT_CHECK_COMPILER_STDOUT: &'static str = "dont-check-compiler-stdout";
+    pub const DONT_CHECK_COMPILER_STDERR: &'static str = "dont-check-compiler-stderr";
+    pub const NO_PREFER_DYNAMIC: &'static str = "no-prefer-dynamic";
+    pub const PRETTY_EXPANDED: &'static str = "pretty-expanded";
+    pub const PRETTY_MODE: &'static str = "pretty-mode";
+    pub const PRETTY_COMPARE_ONLY: &'static str = "pretty-compare-only";
+    pub const AUX_BUILD: &'static str = "aux-build";
+    pub const AUX_CRATE: &'static str = "aux-crate";
+    pub const EXEC_ENV: &'static str = "exec-env";
+    pub const RUSTC_ENV: &'static str = "rustc-env";
+    pub const UNSET_RUSTC_ENV: &'static str = "unset-rustc-env";
+    pub const FORBID_OUTPUT: &'static str = "forbid-output";
+    pub const CHECK_TEST_LINE_NUMBERS_MATCH: &'static str = "check-test-line-numbers-match";
+    pub const IGNORE_PASS: &'static str = "ignore-pass";
+    pub const FAILURE_STATUS: &'static str = "failure-status";
+    pub const RUN_RUSTFIX: &'static str = "run-rustfix";
+    pub const RUSTFIX_ONLY_MACHINE_APPLICABLE: &'static str = "rustfix-only-machine-applicable";
+    pub const ASSEMBLY_OUTPUT: &'static str = "assembly-output";
+    pub const STDERR_PER_BITWIDTH: &'static str = "stderr-per-bitwidth";
+    pub const INCREMENTAL: &'static str = "incremental";
+    pub const KNOWN_BUG: &'static str = "known-bug";
+}
+
 impl TestProps {
     pub fn new() -> Self {
         TestProps {
@@ -176,6 +217,7 @@ impl TestProps {
             forbid_output: vec![],
             incremental_dir: None,
             incremental: false,
+            known_bug: false,
             pass_mode: None,
             fail_mode: None,
             ignore_pass: false,
@@ -228,11 +270,16 @@ impl TestProps {
                     return;
                 }
 
-                if let Some(ep) = config.parse_error_pattern(ln) {
-                    self.error_patterns.push(ep);
-                }
+                use directives::*;
 
-                if let Some(flags) = config.parse_compile_flags(ln) {
+                config.push_name_value_directive(
+                    ln,
+                    ERROR_PATTERN,
+                    &mut self.error_patterns,
+                    |r| r,
+                );
+
+                if let Some(flags) = config.parse_name_value_directive(ln, COMPILE_FLAGS) {
                     self.compile_flags.extend(flags.split_whitespace().map(|s| s.to_owned()));
                 }
 
@@ -243,93 +290,73 @@ impl TestProps {
 
                 config.parse_and_update_revisions(ln, &mut self.revisions);
 
-                if self.run_flags.is_none() {
-                    self.run_flags = config.parse_run_flags(ln);
-                }
+                config.set_name_value_directive(ln, RUN_FLAGS, &mut self.run_flags, |r| r);
 
                 if self.pp_exact.is_none() {
                     self.pp_exact = config.parse_pp_exact(ln, testfile);
                 }
 
-                if !self.should_ice {
-                    self.should_ice = config.parse_should_ice(ln);
-                }
-
-                if !self.build_aux_docs {
-                    self.build_aux_docs = config.parse_build_aux_docs(ln);
-                }
-
-                if !self.force_host {
-                    self.force_host = config.parse_force_host(ln);
-                }
-
-                if !self.check_stdout {
-                    self.check_stdout = config.parse_check_stdout(ln);
-                }
-
-                if !self.check_run_results {
-                    self.check_run_results = config.parse_check_run_results(ln);
-                }
-
-                if !self.dont_check_compiler_stdout {
-                    self.dont_check_compiler_stdout = config.parse_dont_check_compiler_stdout(ln);
-                }
-
-                if !self.dont_check_compiler_stderr {
-                    self.dont_check_compiler_stderr = config.parse_dont_check_compiler_stderr(ln);
-                }
-
-                if !self.no_prefer_dynamic {
-                    self.no_prefer_dynamic = config.parse_no_prefer_dynamic(ln);
-                }
-
-                if !self.pretty_expanded {
-                    self.pretty_expanded = config.parse_pretty_expanded(ln);
-                }
-
-                if let Some(m) = config.parse_pretty_mode(ln) {
+                config.set_name_directive(ln, SHOULD_ICE, &mut self.should_ice);
+                config.set_name_directive(ln, BUILD_AUX_DOCS, &mut self.build_aux_docs);
+                config.set_name_directive(ln, FORCE_HOST, &mut self.force_host);
+                config.set_name_directive(ln, CHECK_STDOUT, &mut self.check_stdout);
+                config.set_name_directive(ln, CHECK_RUN_RESULTS, &mut self.check_run_results);
+                config.set_name_directive(
+                    ln,
+                    DONT_CHECK_COMPILER_STDOUT,
+                    &mut self.dont_check_compiler_stdout,
+                );
+                config.set_name_directive(
+                    ln,
+                    DONT_CHECK_COMPILER_STDERR,
+                    &mut self.dont_check_compiler_stderr,
+                );
+                config.set_name_directive(ln, NO_PREFER_DYNAMIC, &mut self.no_prefer_dynamic);
+                config.set_name_directive(ln, PRETTY_EXPANDED, &mut self.pretty_expanded);
+
+                if let Some(m) = config.parse_name_value_directive(ln, PRETTY_MODE) {
                     self.pretty_mode = m;
                 }
 
-                if !self.pretty_compare_only {
-                    self.pretty_compare_only = config.parse_pretty_compare_only(ln);
-                }
-
-                if let Some(ab) = config.parse_aux_build(ln) {
-                    self.aux_builds.push(ab);
-                }
-
-                if let Some(ac) = config.parse_aux_crate(ln) {
-                    self.aux_crates.push(ac);
-                }
-
-                if let Some(ee) = config.parse_env(ln, "exec-env") {
-                    self.exec_env.push(ee);
-                }
-
-                if let Some(ee) = config.parse_env(ln, "rustc-env") {
-                    self.rustc_env.push(ee);
-                }
-
-                if let Some(ev) = config.parse_name_value_directive(ln, "unset-rustc-env") {
-                    self.unset_rustc_env.push(ev);
-                }
-
-                if let Some(of) = config.parse_forbid_output(ln) {
-                    self.forbid_output.push(of);
-                }
-
-                if !self.check_test_line_numbers_match {
-                    self.check_test_line_numbers_match =
-                        config.parse_check_test_line_numbers_match(ln);
-                }
+                config.set_name_directive(ln, PRETTY_COMPARE_ONLY, &mut self.pretty_compare_only);
+                config.push_name_value_directive(ln, AUX_BUILD, &mut self.aux_builds, |r| {
+                    r.trim().to_string()
+                });
+                config.push_name_value_directive(
+                    ln,
+                    AUX_CRATE,
+                    &mut self.aux_crates,
+                    Config::parse_aux_crate,
+                );
+                config.push_name_value_directive(
+                    ln,
+                    EXEC_ENV,
+                    &mut self.exec_env,
+                    Config::parse_env,
+                );
+                config.push_name_value_directive(
+                    ln,
+                    RUSTC_ENV,
+                    &mut self.rustc_env,
+                    Config::parse_env,
+                );
+                config.push_name_value_directive(
+                    ln,
+                    UNSET_RUSTC_ENV,
+                    &mut self.unset_rustc_env,
+                    |r| r,
+                );
+                config.push_name_value_directive(ln, FORBID_OUTPUT, &mut self.forbid_output, |r| r);
+                config.set_name_directive(
+                    ln,
+                    CHECK_TEST_LINE_NUMBERS_MATCH,
+                    &mut self.check_test_line_numbers_match,
+                );
 
                 self.update_pass_mode(ln, cfg, config);
                 self.update_fail_mode(ln, config);
 
-                if !self.ignore_pass {
-                    self.ignore_pass = config.parse_ignore_pass(ln);
-                }
+                config.set_name_directive(ln, IGNORE_PASS, &mut self.ignore_pass);
 
                 if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stdout") {
                     self.normalize_stdout.push(rule);
@@ -338,30 +365,28 @@ impl TestProps {
                     self.normalize_stderr.push(rule);
                 }
 
-                if let Some(code) = config.parse_failure_status(ln) {
+                if let Some(code) = config
+                    .parse_name_value_directive(ln, FAILURE_STATUS)
+                    .and_then(|code| code.trim().parse::<i32>().ok())
+                {
                     self.failure_status = code;
                 }
 
-                if !self.run_rustfix {
-                    self.run_rustfix = config.parse_run_rustfix(ln);
-                }
-
-                if !self.rustfix_only_machine_applicable {
-                    self.rustfix_only_machine_applicable =
-                        config.parse_rustfix_only_machine_applicable(ln);
-                }
-
-                if self.assembly_output.is_none() {
-                    self.assembly_output = config.parse_assembly_output(ln);
-                }
-
-                if !self.stderr_per_bitwidth {
-                    self.stderr_per_bitwidth = config.parse_stderr_per_bitwidth(ln);
-                }
-
-                if !self.incremental {
-                    self.incremental = config.parse_incremental(ln);
-                }
+                config.set_name_directive(ln, RUN_RUSTFIX, &mut self.run_rustfix);
+                config.set_name_directive(
+                    ln,
+                    RUSTFIX_ONLY_MACHINE_APPLICABLE,
+                    &mut self.rustfix_only_machine_applicable,
+                );
+                config.set_name_value_directive(
+                    ln,
+                    ASSEMBLY_OUTPUT,
+                    &mut self.assembly_output,
+                    |r| r.trim().to_string(),
+                );
+                config.set_name_directive(ln, STDERR_PER_BITWIDTH, &mut self.stderr_per_bitwidth);
+                config.set_name_directive(ln, INCREMENTAL, &mut self.incremental);
+                config.set_name_directive(ln, KNOWN_BUG, &mut self.known_bug);
             });
         }
 
@@ -503,33 +528,12 @@ fn iter_header<R: Read>(testfile: &Path, rdr: R, it: &mut dyn FnMut(Option<&str>
 }
 
 impl Config {
-    fn parse_should_ice(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "should-ice")
-    }
-    fn parse_error_pattern(&self, line: &str) -> Option<String> {
-        self.parse_name_value_directive(line, "error-pattern")
-    }
-
-    fn parse_forbid_output(&self, line: &str) -> Option<String> {
-        self.parse_name_value_directive(line, "forbid-output")
-    }
-
-    fn parse_aux_build(&self, line: &str) -> Option<String> {
-        self.parse_name_value_directive(line, "aux-build").map(|r| r.trim().to_string())
-    }
-
-    fn parse_aux_crate(&self, line: &str) -> Option<(String, String)> {
-        self.parse_name_value_directive(line, "aux-crate").map(|r| {
-            let mut parts = r.trim().splitn(2, '=');
-            (
-                parts.next().expect("missing aux-crate name (e.g. log=log.rs)").to_string(),
-                parts.next().expect("missing aux-crate value (e.g. log=log.rs)").to_string(),
-            )
-        })
-    }
-
-    fn parse_compile_flags(&self, line: &str) -> Option<String> {
-        self.parse_name_value_directive(line, "compile-flags")
+    fn parse_aux_crate(r: String) -> (String, String) {
+        let mut parts = r.trim().splitn(2, '=');
+        (
+            parts.next().expect("missing aux-crate name (e.g. log=log.rs)").to_string(),
+            parts.next().expect("missing aux-crate value (e.g. log=log.rs)").to_string(),
+        )
     }
 
     fn parse_and_update_revisions(&self, line: &str, existing: &mut Vec<String>) {
@@ -544,87 +548,18 @@ impl Config {
         }
     }
 
-    fn parse_run_flags(&self, line: &str) -> Option<String> {
-        self.parse_name_value_directive(line, "run-flags")
-    }
-
-    fn parse_force_host(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "force-host")
-    }
-
-    fn parse_build_aux_docs(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "build-aux-docs")
-    }
-
-    fn parse_check_stdout(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "check-stdout")
-    }
-
-    fn parse_check_run_results(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "check-run-results")
-    }
-
-    fn parse_dont_check_compiler_stdout(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "dont-check-compiler-stdout")
-    }
-
-    fn parse_dont_check_compiler_stderr(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "dont-check-compiler-stderr")
-    }
-
-    fn parse_no_prefer_dynamic(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "no-prefer-dynamic")
-    }
-
-    fn parse_pretty_expanded(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "pretty-expanded")
-    }
-
-    fn parse_pretty_mode(&self, line: &str) -> Option<String> {
-        self.parse_name_value_directive(line, "pretty-mode")
-    }
-
-    fn parse_pretty_compare_only(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "pretty-compare-only")
-    }
-
-    fn parse_failure_status(&self, line: &str) -> Option<i32> {
-        match self.parse_name_value_directive(line, "failure-status") {
-            Some(code) => code.trim().parse::<i32>().ok(),
-            _ => None,
-        }
-    }
-
-    fn parse_check_test_line_numbers_match(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "check-test-line-numbers-match")
-    }
-
-    fn parse_ignore_pass(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "ignore-pass")
-    }
-
-    fn parse_stderr_per_bitwidth(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "stderr-per-bitwidth")
-    }
-
-    fn parse_assembly_output(&self, line: &str) -> Option<String> {
-        self.parse_name_value_directive(line, "assembly-output").map(|r| r.trim().to_string())
-    }
-
-    fn parse_env(&self, line: &str, name: &str) -> Option<(String, String)> {
-        self.parse_name_value_directive(line, name).map(|nv| {
-            // nv is either FOO or FOO=BAR
-            let mut strs: Vec<String> = nv.splitn(2, '=').map(str::to_owned).collect();
+    fn parse_env(nv: String) -> (String, String) {
+        // nv is either FOO or FOO=BAR
+        let mut strs: Vec<String> = nv.splitn(2, '=').map(str::to_owned).collect();
 
-            match strs.len() {
-                1 => (strs.pop().unwrap(), String::new()),
-                2 => {
-                    let end = strs.pop().unwrap();
-                    (strs.pop().unwrap(), end)
-                }
-                n => panic!("Expected 1 or 2 strings, not {}", n),
+        match strs.len() {
+            1 => (strs.pop().unwrap(), String::new()),
+            2 => {
+                let end = strs.pop().unwrap();
+                (strs.pop().unwrap(), end)
             }
-        })
+            n => panic!("Expected 1 or 2 strings, not {}", n),
+        }
     }
 
     fn parse_pp_exact(&self, line: &str, testfile: &Path) -> Option<PathBuf> {
@@ -736,20 +671,38 @@ impl Config {
         None
     }
 
-    fn parse_run_rustfix(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "run-rustfix")
+    fn parse_edition(&self, line: &str) -> Option<String> {
+        self.parse_name_value_directive(line, "edition")
     }
 
-    fn parse_rustfix_only_machine_applicable(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "rustfix-only-machine-applicable")
+    fn set_name_directive(&self, line: &str, directive: &str, value: &mut bool) {
+        if !*value {
+            *value = self.parse_name_directive(line, directive)
+        }
     }
 
-    fn parse_edition(&self, line: &str) -> Option<String> {
-        self.parse_name_value_directive(line, "edition")
+    fn set_name_value_directive<T>(
+        &self,
+        line: &str,
+        directive: &str,
+        value: &mut Option<T>,
+        parse: impl FnOnce(String) -> T,
+    ) {
+        if value.is_none() {
+            *value = self.parse_name_value_directive(line, directive).map(parse);
+        }
     }
 
-    fn parse_incremental(&self, line: &str) -> bool {
-        self.parse_name_directive(line, "incremental")
+    fn push_name_value_directive<T>(
+        &self,
+        line: &str,
+        directive: &str,
+        values: &mut Vec<T>,
+        parse: impl FnOnce(String) -> T,
+    ) {
+        if let Some(value) = self.parse_name_value_directive(line, directive).map(parse) {
+            values.push(value);
+        }
     }
 }
 
@@ -863,6 +816,7 @@ pub fn make_test_description<R: Read>(
     let has_msan = util::MSAN_SUPPORTED_TARGETS.contains(&&*config.target);
     let has_tsan = util::TSAN_SUPPORTED_TARGETS.contains(&&*config.target);
     let has_hwasan = util::HWASAN_SUPPORTED_TARGETS.contains(&&*config.target);
+    let has_memtag = util::MEMTAG_SUPPORTED_TARGETS.contains(&&*config.target);
     // for `-Z gcc-ld=lld`
     let has_rust_lld = config
         .compile_lib_path
@@ -899,9 +853,11 @@ pub fn make_test_description<R: Read>(
         ignore |= !has_msan && config.parse_name_directive(ln, "needs-sanitizer-memory");
         ignore |= !has_tsan && config.parse_name_directive(ln, "needs-sanitizer-thread");
         ignore |= !has_hwasan && config.parse_name_directive(ln, "needs-sanitizer-hwaddress");
+        ignore |= !has_memtag && config.parse_name_directive(ln, "needs-sanitizer-memtag");
         ignore |= config.target_panic == PanicStrategy::Abort
             && config.parse_name_directive(ln, "needs-unwind");
-        ignore |= config.target == "wasm32-unknown-unknown" && config.parse_check_run_results(ln);
+        ignore |= config.target == "wasm32-unknown-unknown"
+            && config.parse_name_directive(ln, directives::CHECK_RUN_RESULTS);
         ignore |= config.debugger == Some(Debugger::Cdb) && ignore_cdb(config, ln);
         ignore |= config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln);
         ignore |= config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln);
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index f6ddac3a65e..7fe7db0801b 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1274,6 +1274,16 @@ impl<'test> TestCx<'test> {
             self.fatal_proc_rec("process did not return an error status", proc_res);
         }
 
+        if self.props.known_bug {
+            if !expected_errors.is_empty() {
+                self.fatal_proc_rec(
+                    "`known_bug` tests should not have an expected errors",
+                    proc_res,
+                );
+            }
+            return;
+        }
+
         // On Windows, keep all '\' path separators to match the paths reported in the JSON output
         // from the compiler
         let os_file_name = self.testpaths.file.display().to_string();
@@ -1310,6 +1320,7 @@ impl<'test> TestCx<'test> {
                 }
 
                 None => {
+                    // If the test is a known bug, don't require that the error is annotated
                     if self.is_unexpected_compiler_message(actual_error, expect_help, expect_note) {
                         self.error(&format!(
                             "{}:{}: unexpected {}: '{}'",
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 6ca145a58e9..bed509d77be 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -117,6 +117,9 @@ pub const TSAN_SUPPORTED_TARGETS: &[&str] = &[
 pub const HWASAN_SUPPORTED_TARGETS: &[&str] =
     &["aarch64-linux-android", "aarch64-unknown-linux-gnu"];
 
+pub const MEMTAG_SUPPORTED_TARGETS: &[&str] =
+    &["aarch64-linux-android", "aarch64-unknown-linux-gnu"];
+
 const BIG_ENDIAN: &[&str] = &[
     "aarch64_be",
     "armebv7r",
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 203e33e8b1f..95847dcd46b 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -7,7 +7,7 @@ use std::path::Path;
 
 const ENTRY_LIMIT: usize = 1000;
 // FIXME: The following limits should be reduced eventually.
-const ROOT_ENTRY_LIMIT: usize = 982;
+const ROOT_ENTRY_LIMIT: usize = 983;
 const ISSUES_ENTRY_LIMIT: usize = 2310;
 
 fn check_entries(path: &Path, bad: &mut bool) {