about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe Miri Cronjob Bot <miri@cron.bot>2024-03-09 05:01:38 +0000
committerThe Miri Cronjob Bot <miri@cron.bot>2024-03-09 05:01:38 +0000
commite720147bf527dfe837ec1161853b3e28a238202d (patch)
treed597a7cbe6c865a5b289dc559e06fadd054124a3
parent52db5f6cdc8d1e7c6270f9d2ce926d70ac706431 (diff)
parent4d4bb491b65c300835442f6cb4f34fc9a5685c26 (diff)
downloadrust-e720147bf527dfe837ec1161853b3e28a238202d.tar.gz
rust-e720147bf527dfe837ec1161853b3e28a238202d.zip
Merge from rustc
-rw-r--r--compiler/rustc_ast/src/ast.rs5
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs1
-rw-r--r--compiler/rustc_ast/src/visit.rs1
-rw-r--r--compiler/rustc_ast_lowering/messages.ftl3
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs27
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs10
-rw-r--r--compiler/rustc_ast_lowering/src/format.rs19
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs16
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs58
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs76
-rw-r--r--compiler/rustc_borrowck/src/lib.rs6
-rw-r--r--compiler/rustc_borrowck/src/polonius/loan_invalidations.rs5
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs19
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs4
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl2
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs66
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs18
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/main.yml17
-rw-r--r--compiler/rustc_codegen_cranelift/.gitignore23
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.lock56
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.toml12
-rw-r--r--compiler/rustc_codegen_cranelift/Readme.md5
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/prepare.rs27
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/tests.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch2
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0023-coretests-Ignore-failing-tests.patch26
-rw-r--r--compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml9
-rw-r--r--compiler/rustc_codegen_cranelift/rust-toolchain2
-rw-r--r--compiler/rustc_codegen_cranelift/rustfmt.toml1
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh26
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs16
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs17
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/src/global_asm.rs3
-rw-r--r--compiler/rustc_codegen_cranelift/src/inline_asm.rs3
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs175
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs5
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs8
-rwxr-xr-xcompiler/rustc_codegen_cranelift/y.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/asm.rs31
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs30
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs52
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs40
-rw-r--r--compiler/rustc_codegen_ssa/src/mono_item.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/asm.rs6
-rw-r--r--compiler/rustc_const_eval/messages.ftl3
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/discriminant.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs82
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs6
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0657.md59
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs16
-rw-r--r--compiler/rustc_hir/src/intravisit.rs1
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl4
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs36
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs25
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs146
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs10
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs23
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs21
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs21
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs69
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/suggest.rs88
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs2
-rw-r--r--compiler/rustc_infer/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/internal.rs10
-rw-r--r--compiler/rustc_lint/src/unused.rs18
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp16
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp25
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs6
-rw-r--r--compiler/rustc_middle/src/mir/patch.rs27
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs26
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs11
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs118
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs5
-rw-r--r--compiler/rustc_middle/src/query/mod.rs7
-rw-r--r--compiler/rustc_middle/src/thir.rs3
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs1
-rw-r--r--compiler/rustc_middle/src/traits/solve/inspect/format.rs47
-rw-r--r--compiler/rustc_middle/src/ty/context.rs28
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs12
-rw-r--r--compiler/rustc_middle/src/ty/util.rs8
-rw-r--r--compiler/rustc_middle/src/values.rs21
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs32
-rw-r--r--compiler/rustc_mir_build/src/lints.rs7
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs3
-rw-r--r--compiler/rustc_mir_build/src/thir/print.rs6
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs13
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/graphviz.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs5
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs18
-rw-r--r--compiler/rustc_mir_transform/src/coverage/tests.rs5
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs3
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs4
-rw-r--r--compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs84
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs3
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs16
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs2
-rw-r--r--compiler/rustc_passes/src/liveness.rs59
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs3
-rw-r--r--compiler/rustc_resolve/src/late.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs8
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/spec/mod.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs19
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs27
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs2
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs2
-rw-r--r--library/alloc/src/collections/btree/map.rs1
-rw-r--r--library/core/src/fmt/mod.rs36
-rw-r--r--library/core/src/ptr/const_ptr.rs13
-rw-r--r--library/core/src/ptr/mod.rs28
-rw-r--r--library/core/src/ptr/mut_ptr.rs13
-rw-r--r--library/core/src/slice/mod.rs14
-rw-r--r--library/std/src/fs.rs8
-rw-r--r--library/std/src/io/buffered/bufwriter.rs51
-rw-r--r--library/std/src/io/buffered/linewritershim.rs15
-rw-r--r--library/std/src/io/stdio.rs15
-rw-r--r--rustfmt.toml1
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/unstable-book/src/language-features/asm-goto.md30
-rw-r--r--src/librustdoc/core.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs1
-rw-r--r--src/tools/miri/src/bin/miri.rs6
-rw-r--r--src/tools/miri/src/machine.rs15
-rw-r--r--src/tools/tidy/src/issues.txt194
-rw-r--r--src/tools/tidy/src/ui_tests.rs15
-rw-r--r--tests/assembly/targets/targets-elf.rs3
-rw-r--r--tests/codegen/asm-goto.rs51
-rw-r--r--tests/codegen/enum/uninhabited_enum_default_branch.rs24
-rw-r--r--tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-abort.diff6
-rw-r--r--tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-unwind.diff6
-rw-r--r--tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir22
-rw-r--r--tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir22
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff26
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff20
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff26
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff20
-rw-r--r--tests/mir-opt/separate_const_switch.identity.JumpThreading.diff28
-rw-r--r--tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff34
-rw-r--r--tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff8
-rw-r--r--tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff8
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.diff)8
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-unwind.diff115
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.diff)7
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-unwind.diff43
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-abort.diff53
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-unwind.diff53
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-abort.diff44
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-unwind.diff44
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-abort.diff53
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-unwind.diff53
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-abort.diff48
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-unwind.diff48
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff62
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff62
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-abort.diff75
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-unwind.diff75
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff66
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff70
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.rs139
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.diff)6
-rw-r--r--tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-unwind.diff53
-rw-r--r--tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff2
-rw-r--r--tests/rustdoc-ui/issue-110629-private-type-cycle-dyn.stderr12
-rw-r--r--tests/rustdoc-ui/issues/issue-105742.stderr64
-rw-r--r--tests/ui/asm/aarch64/parse-error.stderr8
-rw-r--r--tests/ui/asm/parse-error.rs2
-rw-r--r--tests/ui/asm/parse-error.stderr16
-rw-r--r--tests/ui/asm/x86_64/bad-options.rs4
-rw-r--r--tests/ui/asm/x86_64/bad-options.stderr38
-rw-r--r--tests/ui/asm/x86_64/goto.mirunsafeck.stderr23
-rw-r--r--tests/ui/asm/x86_64/goto.rs111
-rw-r--r--tests/ui/asm/x86_64/goto.thirunsafeck.stderr23
-rw-r--r--tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr14
-rw-r--r--tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr30
-rw-r--r--tests/ui/associated-inherent-types/issue-109071.no_gate.stderr20
-rw-r--r--tests/ui/associated-type-bounds/duplicate.stderr186
-rw-r--r--tests/ui/associated-types/associated-types-in-ambiguous-context.stderr34
-rw-r--r--tests/ui/const-generics/generic_arg_infer/in-signature.stderr40
-rw-r--r--tests/ui/const-generics/issues/issue-71202.rs2
-rw-r--r--tests/ui/const-generics/issues/issue-71202.stderr27
-rw-r--r--tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr (renamed from tests/ui/consts/const-eval/infinite_loop.stderr)4
-rw-r--r--tests/ui/consts/const-eval/infinite_loop.no_ice.stderr27
-rw-r--r--tests/ui/consts/const-eval/infinite_loop.rs5
-rw-r--r--tests/ui/consts/different-fn-ptr-binders-during-ctfe.rs6
-rw-r--r--tests/ui/consts/different-fn-ptr-binders-during-ctfe.stderr10
-rw-r--r--tests/ui/consts/issue-103790.stderr14
-rw-r--r--tests/ui/consts/issue-36163.stderr14
-rw-r--r--tests/ui/cycle-trait/cycle-trait-default-type-trait.stderr10
-rw-r--r--tests/ui/cycle-trait/cycle-trait-supertrait-direct.stderr2
-rw-r--r--tests/ui/cycle-trait/issue-12511.stderr2
-rw-r--r--tests/ui/delegation/not-supported.stderr42
-rw-r--r--tests/ui/did_you_mean/bad-assoc-ty.stderr44
-rw-r--r--tests/ui/error-codes/E0657.rs4
-rw-r--r--tests/ui/error-codes/E0657.stderr16
-rw-r--r--tests/ui/error-codes/E0719.stderr16
-rw-r--r--tests/ui/feature-gates/feature-gate-asm_goto.rs10
-rw-r--r--tests/ui/feature-gates/feature-gate-asm_goto.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr16
-rw-r--r--tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr76
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr40
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr32
-rw-r--r--tests/ui/generic-associated-types/issue-80433.stderr22
-rw-r--r--tests/ui/generic-associated-types/missing_lifetime_args.stderr72
-rw-r--r--tests/ui/generic-associated-types/unknown-lifetime-ice-119827.rs8
-rw-r--r--tests/ui/generic-associated-types/unknown-lifetime-ice-119827.stderr115
-rw-r--r--tests/ui/impl-trait/impl-fn-hrtb-bounds.rs6
-rw-r--r--tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr45
-rw-r--r--tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs2
-rw-r--r--tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr3
-rw-r--r--tests/ui/impl-trait/implicit-capture-late.stderr8
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs18
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr67
-rw-r--r--tests/ui/impl-trait/issues/issue-54895.rs2
-rw-r--r--tests/ui/impl-trait/issues/issue-54895.stderr3
-rw-r--r--tests/ui/impl-trait/issues/issue-67830.rs2
-rw-r--r--tests/ui/impl-trait/issues/issue-67830.stderr3
-rw-r--r--tests/ui/impl-trait/issues/issue-88236-2.rs6
-rw-r--r--tests/ui/impl-trait/issues/issue-88236-2.stderr29
-rw-r--r--tests/ui/impl-trait/issues/issue-88236.rs2
-rw-r--r--tests/ui/impl-trait/issues/issue-88236.stderr3
-rw-r--r--tests/ui/impl-trait/nested-rpit-hrtb.rs8
-rw-r--r--tests/ui/impl-trait/nested-rpit-hrtb.stderr28
-rw-r--r--tests/ui/impl-trait/where-allowed.stderr38
-rw-r--r--tests/ui/infinite/infinite-trait-alias-recursion.stderr2
-rw-r--r--tests/ui/infinite/infinite-type-alias-mutual-recursion.gated.stderr14
-rw-r--r--tests/ui/infinite/infinite-vec-type-recursion.gated.stderr14
-rw-r--r--tests/ui/issues/issue-20831-debruijn.stderr6
-rw-r--r--tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-1.stderr10
-rw-r--r--tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-2.stderr11
-rw-r--r--tests/ui/issues/issue-34373.stderr16
-rw-r--r--tests/ui/layout/issue-84108.rs1
-rw-r--r--tests/ui/layout/issue-84108.stderr12
-rw-r--r--tests/ui/lifetimes/issue-95023.stderr12
-rw-r--r--tests/ui/lifetimes/missing-lifetime-in-alias.stderr32
-rw-r--r--tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr36
-rw-r--r--tests/ui/resolve/auxiliary/proc_macro_generate_packed.rs27
-rw-r--r--tests/ui/resolve/multiple_definitions_attribute_merging.rs19
-rw-r--r--tests/ui/resolve/multiple_definitions_attribute_merging.stderr26
-rw-r--r--tests/ui/resolve/proc_macro_generated_packed.rs20
-rw-r--r--tests/ui/resolve/proc_macro_generated_packed.stderr16
-rw-r--r--tests/ui/resolve/resolve-self-in-impl.stderr34
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr18
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr12
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr20
-rw-r--r--tests/ui/span/issue-35987.rs1
-rw-r--r--tests/ui/span/issue-35987.stderr18
-rw-r--r--tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr32
-rw-r--r--tests/ui/suggestions/suggest-blanket-impl-local-trait.stderr74
-rw-r--r--tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs5
-rw-r--r--tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr63
-rw-r--r--tests/ui/suggestions/suggest-swapping-self-ty-and-trait.rs7
-rw-r--r--tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr66
-rw-r--r--tests/ui/tag-type-args.stderr18
-rw-r--r--tests/ui/target-feature/invalid-attribute.stderr18
-rw-r--r--tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs16
-rw-r--r--tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr45
-rw-r--r--tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr36
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-static.rs1
-rw-r--r--tests/ui/traits/bound/on-structs-and-enums-static.stderr22
-rw-r--r--tests/ui/traits/issue-28576.stderr40
-rw-r--r--tests/ui/traits/next-solver/assembly/param-env-alias-bound-conflict.rs26
-rw-r--r--tests/ui/traits/next-solver/env-shadows-impls/param-env-impl-conflict.rs23
-rw-r--r--tests/ui/traits/trait-upcasting/cyclic-trait-resolution.rs1
-rw-r--r--tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr18
-rw-r--r--tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/escaping-bound-var.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/escaping-bound-var.stderr13
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/variance.rs30
-rw-r--r--tests/ui/type-alias-impl-trait/variance.stderr57
-rw-r--r--tests/ui/typeck/type-placeholder-fn-in-const.stderr12
-rw-r--r--tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr20
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.stderr356
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item_help.stderr8
-rw-r--r--tests/ui/wf/wf-const-type.rs1
-rw-r--r--tests/ui/wf/wf-const-type.stderr21
-rw-r--r--tests/ui/wf/wf-static-type.rs1
-rw-r--r--tests/ui/wf/wf-static-type.stderr21
312 files changed, 5042 insertions, 2396 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 13b1a589d9b..d522c285e3e 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2302,6 +2302,9 @@ pub enum InlineAsmOperand {
     Sym {
         sym: InlineAsmSym,
     },
+    Label {
+        block: P<Block>,
+    },
 }
 
 impl InlineAsmOperand {
@@ -2311,7 +2314,7 @@ impl InlineAsmOperand {
             | Self::Out { reg, .. }
             | Self::InOut { reg, .. }
             | Self::SplitInOut { reg, .. } => Some(reg),
-            Self::Const { .. } | Self::Sym { .. } => None,
+            Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
         }
     }
 }
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index c517c6138ce..9ec92c9d4ed 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1331,6 +1331,7 @@ pub fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) {
             }
             InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const),
             InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym),
+            InlineAsmOperand::Label { block } => vis.visit_block(block),
         }
     }
 }
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 9efb87e53cd..7296e29301f 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -823,6 +823,7 @@ pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm)
                 try_visit!(visitor.visit_anon_const(anon_const))
             }
             InlineAsmOperand::Sym { sym } => try_visit!(visitor.visit_inline_asm_sym(sym)),
+            InlineAsmOperand::Label { block } => try_visit!(visitor.visit_block(block)),
         }
     }
     V::Result::output()
diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl
index e87cf05713c..d91d65497e1 100644
--- a/compiler/rustc_ast_lowering/messages.ftl
+++ b/compiler/rustc_ast_lowering/messages.ftl
@@ -88,6 +88,9 @@ ast_lowering_invalid_abi_suggestion = did you mean
 ast_lowering_invalid_asm_template_modifier_const =
     asm template modifiers are not allowed for `const` arguments
 
+ast_lowering_invalid_asm_template_modifier_label =
+    asm template modifiers are not allowed for `label` arguments
+
 ast_lowering_invalid_asm_template_modifier_reg_class =
     invalid asm template modifier for this register class
 
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 7fd419f62e4..cef50a70534 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -3,9 +3,9 @@ use crate::{ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringE
 use super::errors::{
     AbiSpecifiedMultipleTimes, AttSyntaxOnlyX86, ClobberAbiNotSupported,
     InlineAsmUnsupportedTarget, InvalidAbiClobberAbi, InvalidAsmTemplateModifierConst,
-    InvalidAsmTemplateModifierRegClass, InvalidAsmTemplateModifierRegClassSub,
-    InvalidAsmTemplateModifierSym, InvalidRegister, InvalidRegisterClass, RegisterClassOnlyClobber,
-    RegisterConflict,
+    InvalidAsmTemplateModifierLabel, InvalidAsmTemplateModifierRegClass,
+    InvalidAsmTemplateModifierRegClassSub, InvalidAsmTemplateModifierSym, InvalidRegister,
+    InvalidRegisterClass, RegisterClassOnlyClobber, RegisterConflict,
 };
 use super::LoweringContext;
 
@@ -237,6 +237,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             }
                         }
                     }
+                    InlineAsmOperand::Label { block } => {
+                        if !self.tcx.features().asm_goto {
+                            feature_err(
+                                sess,
+                                sym::asm_goto,
+                                *op_sp,
+                                "label operands for inline assembly are unstable",
+                            )
+                            .emit();
+                        }
+                        hir::InlineAsmOperand::Label { block: self.lower_block(block, false) }
+                    }
                 };
                 (op, self.lower_span(*op_sp))
             })
@@ -296,6 +308,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             op_span: op_sp,
                         });
                     }
+                    hir::InlineAsmOperand::Label { .. } => {
+                        self.dcx().emit_err(InvalidAsmTemplateModifierLabel {
+                            placeholder_span,
+                            op_span: op_sp,
+                        });
+                    }
                 }
             }
         }
@@ -335,7 +353,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
                         hir::InlineAsmOperand::Const { .. }
                         | hir::InlineAsmOperand::SymFn { .. }
-                        | hir::InlineAsmOperand::SymStatic { .. } => {
+                        | hir::InlineAsmOperand::SymStatic { .. }
+                        | hir::InlineAsmOperand::Label { .. } => {
                             unreachable!("{op:?} is not a register operand");
                         }
                     };
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 570449513bf..76744ae6264 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -262,6 +262,16 @@ pub struct InvalidAsmTemplateModifierSym {
 }
 
 #[derive(Diagnostic, Clone, Copy)]
+#[diag(ast_lowering_invalid_asm_template_modifier_label)]
+pub struct InvalidAsmTemplateModifierLabel {
+    #[primary_span]
+    #[label(ast_lowering_template_modifier)]
+    pub placeholder_span: Span,
+    #[label(ast_lowering_argument)]
+    pub op_span: Span,
+}
+
+#[derive(Diagnostic, Clone, Copy)]
 #[diag(ast_lowering_register_class_only_clobber)]
 pub struct RegisterClassOnlyClobber {
     #[primary_span]
diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs
index 00cb09d7a54..3f84e6b100d 100644
--- a/compiler/rustc_ast_lowering/src/format.rs
+++ b/compiler/rustc_ast_lowering/src/format.rs
@@ -1,4 +1,5 @@
 use super::LoweringContext;
+use core::ops::ControlFlow;
 use rustc_ast as ast;
 use rustc_ast::visit::Visitor;
 use rustc_ast::*;
@@ -594,30 +595,32 @@ fn expand_format_args<'hir>(
 }
 
 fn may_contain_yield_point(e: &ast::Expr) -> bool {
-    struct MayContainYieldPoint(bool);
+    struct MayContainYieldPoint;
 
     impl Visitor<'_> for MayContainYieldPoint {
-        fn visit_expr(&mut self, e: &ast::Expr) {
+        type Result = ControlFlow<()>;
+
+        fn visit_expr(&mut self, e: &ast::Expr) -> ControlFlow<()> {
             if let ast::ExprKind::Await(_, _) | ast::ExprKind::Yield(_) = e.kind {
-                self.0 = true;
+                ControlFlow::Break(())
             } else {
                 visit::walk_expr(self, e);
+                ControlFlow::Continue(())
             }
         }
 
-        fn visit_mac_call(&mut self, _: &ast::MacCall) {
+        fn visit_mac_call(&mut self, _: &ast::MacCall) -> ControlFlow<()> {
             // Macros should be expanded at this point.
             unreachable!("unexpanded macro in ast lowering");
         }
 
-        fn visit_item(&mut self, _: &ast::Item) {
+        fn visit_item(&mut self, _: &ast::Item) -> ControlFlow<()> {
             // Do not recurse into nested items.
+            ControlFlow::Continue(())
         }
     }
 
-    let mut visitor = MayContainYieldPoint(false);
-    visitor.visit_expr(e);
-    visitor.0
+    MayContainYieldPoint.visit_expr(e).is_break()
 }
 
 fn for_all_argument_indexes(template: &mut [FormatArgsPiece], mut f: impl FnMut(&mut usize)) {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 01b1e6fcaff..52300138186 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -275,7 +275,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         }
                         Some(ty) => this.lower_ty(
                             ty,
-                            ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false },
+                            ImplTraitContext::OpaqueTy {
+                                origin: hir::OpaqueTyOrigin::TyAlias {
+                                    parent: this.local_def_id(id),
+                                    in_assoc_ty: false,
+                                },
+                                fn_kind: None,
+                            },
                         ),
                     },
                 );
@@ -936,7 +942,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         Some(ty) => {
                             let ty = this.lower_ty(
                                 ty,
-                                ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true },
+                                ImplTraitContext::OpaqueTy {
+                                    origin: hir::OpaqueTyOrigin::TyAlias {
+                                        parent: this.local_def_id(i.id),
+                                        in_assoc_ty: true,
+                                    },
+                                    fn_kind: None,
+                                },
                             );
                             hir::ImplItemKind::Type(ty)
                         }
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 03ad75ca8b4..94e1e06a954 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -265,13 +265,12 @@ enum ImplTraitContext {
     /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
     /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
     ///
-    ReturnPositionOpaqueTy {
-        /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
+    OpaqueTy {
         origin: hir::OpaqueTyOrigin,
-        fn_kind: FnDeclKind,
+        /// Only used to change the lifetime capture rules, since
+        /// RPITIT captures all in scope, RPIT does not.
+        fn_kind: Option<FnDeclKind>,
     },
-    /// Impl trait in type aliases.
-    TypeAliasesOpaqueTy { in_assoc_ty: bool },
     /// `impl Trait` is unstably accepted in this position.
     FeatureGated(ImplTraitPosition, Symbol),
     /// `impl Trait` is not accepted in this position.
@@ -1075,9 +1074,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 // Disallow ATB in dyn types
                 if self.is_in_dyn_type {
                     let suggestion = match itctx {
-                        ImplTraitContext::ReturnPositionOpaqueTy { .. }
-                        | ImplTraitContext::TypeAliasesOpaqueTy { .. }
-                        | ImplTraitContext::Universal => {
+                        ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {
                             let bound_end_span = constraint
                                 .gen_args
                                 .as_ref()
@@ -1417,24 +1414,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             TyKind::ImplTrait(def_node_id, bounds) => {
                 let span = t.span;
                 match itctx {
-                    ImplTraitContext::ReturnPositionOpaqueTy { origin, fn_kind } => self
-                        .lower_opaque_impl_trait(
-                            span,
-                            origin,
-                            *def_node_id,
-                            bounds,
-                            Some(fn_kind),
-                            itctx,
-                        ),
-                    ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self
-                        .lower_opaque_impl_trait(
-                            span,
-                            hir::OpaqueTyOrigin::TyAlias { in_assoc_ty },
-                            *def_node_id,
-                            bounds,
-                            None,
-                            itctx,
-                        ),
+                    ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait(
+                        span,
+                        origin,
+                        *def_node_id,
+                        bounds,
+                        fn_kind,
+                        itctx,
+                    ),
                     ImplTraitContext::Universal => {
                         let span = t.span;
 
@@ -1553,9 +1540,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         let captured_lifetimes_to_duplicate = match origin {
             hir::OpaqueTyOrigin::TyAlias { .. } => {
-                // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't duplicate any
-                // lifetimes, since we don't have the issue that any are late-bound.
-                Vec::new()
+                // type alias impl trait and associated type position impl trait were
+                // decided to capture all in-scope lifetimes, which we collect for
+                // all opaques during resolution.
+                self.resolver
+                    .take_extra_lifetime_params(opaque_ty_node_id)
+                    .into_iter()
+                    .map(|(ident, id, _)| Lifetime { id, ident })
+                    .collect()
             }
             hir::OpaqueTyOrigin::FnReturn(..) => {
                 if matches!(
@@ -1823,9 +1815,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         FnDeclKind::Fn
                         | FnDeclKind::Inherent
                         | FnDeclKind::Trait
-                        | FnDeclKind::Impl => ImplTraitContext::ReturnPositionOpaqueTy {
+                        | FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
                             origin: hir::OpaqueTyOrigin::FnReturn(self.local_def_id(fn_node_id)),
-                            fn_kind: kind,
+                            fn_kind: Some(kind),
                         },
                         FnDeclKind::ExternFn => {
                             ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
@@ -1919,9 +1911,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     output,
                     coro,
                     opaque_ty_span,
-                    ImplTraitContext::ReturnPositionOpaqueTy {
+                    ImplTraitContext::OpaqueTy {
                         origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
-                        fn_kind,
+                        fn_kind: Some(fn_kind),
                     },
                 );
                 arena_vec![this; bound]
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 48941a232c2..aeeb4bf9e76 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -423,7 +423,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             // fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug
             // //      disallowed --^^^^^^^^^^        allowed --^^^^^^^^^^
             // ```
-            FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. }) => {
+            FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::OpaqueTy { .. }) => {
                 if self.tcx.features().impl_trait_in_fn_trait_return {
                     self.lower_ty(ty, itctx)
                 } else {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 6119c6c84f8..e5d7b848903 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1452,6 +1452,10 @@ impl<'a> State<'a> {
                             s.print_path(&sym.path, true, 0);
                         }
                     }
+                    InlineAsmOperand::Label { block } => {
+                        s.head("label");
+                        s.print_block(block);
+                    }
                 }
             }
             AsmArg::ClobberAbi(abi) => {
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index c327e591f3c..ebc9f1d109e 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -1,6 +1,7 @@
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
 
+use core::ops::ControlFlow;
 use hir::ExprKind;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir as hir;
@@ -727,30 +728,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             _ => local_decl.source_info.span,
         };
 
-        struct BindingFinder {
-            span: Span,
-            hir_id: Option<hir::HirId>,
-        }
-
-        impl<'tcx> Visitor<'tcx> for BindingFinder {
-            fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
-                if let hir::StmtKind::Local(local) = s.kind {
-                    if local.pat.span == self.span {
-                        self.hir_id = Some(local.hir_id);
-                    }
-                }
-                hir::intravisit::walk_stmt(self, s);
-            }
-        }
-
         let def_id = self.body.source.def_id();
         let hir_id = if let Some(local_def_id) = def_id.as_local()
             && let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
         {
             let body = self.infcx.tcx.hir().body(body_id);
-            let mut v = BindingFinder { span: pat_span, hir_id: None };
-            v.visit_body(body);
-            v.hir_id
+            BindingFinder { span: pat_span }.visit_body(body).break_value()
         } else {
             None
         };
@@ -859,17 +842,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         };
 
         let hir_map = self.infcx.tcx.hir();
-        struct Finder<'tcx> {
+        struct Finder {
             span: Span,
-            expr: Option<&'tcx Expr<'tcx>>,
         }
 
-        impl<'tcx> Visitor<'tcx> for Finder<'tcx> {
-            fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
-                if e.span == self.span && self.expr.is_none() {
-                    self.expr = Some(e);
+        impl<'tcx> Visitor<'tcx> for Finder {
+            type Result = ControlFlow<&'tcx Expr<'tcx>>;
+            fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) -> Self::Result {
+                if e.span == self.span {
+                    ControlFlow::Break(e)
+                } else {
+                    hir::intravisit::walk_expr(self, e)
                 }
-                hir::intravisit::walk_expr(self, e);
             }
         }
         if let Some(body_id) = hir_map.maybe_body_owned_by(self.mir_def_id())
@@ -878,9 +862,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             // `span` corresponds to the expression being iterated, find the `for`-loop desugared
             // expression with that span in order to identify potential fixes when encountering a
             // read-only iterator that should be mutable.
-            let mut v = Finder { span, expr: None };
-            v.visit_block(block);
-            if let Some(expr) = v.expr
+            if let ControlFlow::Break(expr) = (Finder { span }).visit_block(block)
                 && let Call(_, [expr]) = expr.kind
             {
                 match expr.kind {
@@ -1179,29 +1161,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 );
             }
             Some((false, err_label_span, message)) => {
-                struct BindingFinder {
-                    span: Span,
-                    hir_id: Option<hir::HirId>,
-                }
-
-                impl<'tcx> Visitor<'tcx> for BindingFinder {
-                    fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
-                        if let hir::StmtKind::Local(local) = s.kind {
-                            if local.pat.span == self.span {
-                                self.hir_id = Some(local.hir_id);
-                            }
-                        }
-                        hir::intravisit::walk_stmt(self, s);
-                    }
-                }
                 let def_id = self.body.source.def_id();
                 let hir_id = if let Some(local_def_id) = def_id.as_local()
                     && let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
                 {
                     let body = self.infcx.tcx.hir().body(body_id);
-                    let mut v = BindingFinder { span: err_label_span, hir_id: None };
-                    v.visit_body(body);
-                    v.hir_id
+                    BindingFinder { span: err_label_span }.visit_body(body).break_value()
                 } else {
                     None
                 };
@@ -1333,6 +1298,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
     }
 }
 
+struct BindingFinder {
+    span: Span,
+}
+
+impl<'tcx> Visitor<'tcx> for BindingFinder {
+    type Result = ControlFlow<hir::HirId>;
+    fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) -> Self::Result {
+        if let hir::StmtKind::Local(local) = s.kind
+            && local.pat.span == self.span
+        {
+            ControlFlow::Break(local.hir_id)
+        } else {
+            hir::intravisit::walk_stmt(self, s)
+        }
+    }
+}
+
 pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
     debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind());
 
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index ef582033c4e..8dcfe014b65 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -6,6 +6,7 @@
 #![feature(assert_matches)]
 #![feature(associated_type_bounds)]
 #![feature(box_patterns)]
+#![feature(control_flow_enum)]
 #![feature(let_chains)]
 #![feature(min_specialization)]
 #![feature(never_type)]
@@ -723,7 +724,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
                 operands,
                 options: _,
                 line_spans: _,
-                destination: _,
+                targets: _,
                 unwind: _,
             } => {
                 for op in operands {
@@ -749,7 +750,8 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
                         }
                         InlineAsmOperand::Const { value: _ }
                         | InlineAsmOperand::SymFn { value: _ }
-                        | InlineAsmOperand::SymStatic { def_id: _ } => {}
+                        | InlineAsmOperand::SymStatic { def_id: _ }
+                        | InlineAsmOperand::Label { target_index: _ } => {}
                     }
                 }
             }
diff --git a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
index 10941cadcbb..956de1dec9b 100644
--- a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
+++ b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
@@ -161,7 +161,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'cx, 'tcx> {
                 operands,
                 options: _,
                 line_spans: _,
-                destination: _,
+                targets: _,
                 unwind: _,
             } => {
                 for op in operands {
@@ -182,7 +182,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'cx, 'tcx> {
                         }
                         InlineAsmOperand::Const { value: _ }
                         | InlineAsmOperand::SymFn { value: _ }
-                        | InlineAsmOperand::SymStatic { def_id: _ } => {}
+                        | InlineAsmOperand::SymStatic { def_id: _ }
+                        | InlineAsmOperand::Label { target_index: _ } => {}
                     }
                 }
             }
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 4b096a59234..12b02c7fcfa 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -367,14 +367,17 @@ fn check_opaque_type_parameter_valid(
     span: Span,
 ) -> Result<(), ErrorGuaranteed> {
     let opaque_ty_hir = tcx.hir().expect_item(opaque_type_key.def_id);
-    let is_ty_alias = match opaque_ty_hir.expect_opaque_ty().origin {
-        OpaqueTyOrigin::TyAlias { .. } => true,
-        OpaqueTyOrigin::AsyncFn(..) | OpaqueTyOrigin::FnReturn(..) => false,
+    let (parent, is_ty_alias) = match opaque_ty_hir.expect_opaque_ty().origin {
+        OpaqueTyOrigin::TyAlias { parent, .. } => (parent, true),
+        OpaqueTyOrigin::AsyncFn(parent) | OpaqueTyOrigin::FnReturn(parent) => (parent, false),
     };
 
-    let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
+    let parent_generics = tcx.generics_of(parent);
     let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
-    for (i, arg) in opaque_type_key.args.iter().enumerate() {
+
+    // Only check the parent generics, which will ignore any of the
+    // duplicated lifetime args that come from reifying late-bounds.
+    for (i, arg) in opaque_type_key.args.iter().take(parent_generics.count()).enumerate() {
         if let Err(guar) = arg.error_reported() {
             return Err(guar);
         }
@@ -395,7 +398,7 @@ fn check_opaque_type_parameter_valid(
             seen_params.entry(arg).or_default().push(i);
         } else {
             // Prevent `fn foo() -> Foo<u32>` from being defining.
-            let opaque_param = opaque_generics.param_at(i, tcx);
+            let opaque_param = parent_generics.param_at(i, tcx);
             let kind = opaque_param.kind.descr();
 
             return Err(tcx.dcx().emit_err(NonGenericOpaqueTypeParam {
@@ -409,10 +412,10 @@ fn check_opaque_type_parameter_valid(
 
     for (_, indices) in seen_params {
         if indices.len() > 1 {
-            let descr = opaque_generics.param_at(indices[0], tcx).kind.descr();
+            let descr = parent_generics.param_at(indices[0], tcx).kind.descr();
             let spans: Vec<_> = indices
                 .into_iter()
-                .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
+                .map(|i| tcx.def_span(parent_generics.param_at(i, tcx).def_id))
                 .collect();
             #[allow(rustc::diagnostic_outside_of_impl)]
             #[allow(rustc::untranslatable_diagnostic)]
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 0f3e995a331..8d38b86fa34 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1770,8 +1770,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 self.assert_iscleanup(body, block_data, real_target, is_cleanup);
                 self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);
             }
-            TerminatorKind::InlineAsm { destination, unwind, .. } => {
-                if let Some(target) = destination {
+            TerminatorKind::InlineAsm { ref targets, unwind, .. } => {
+                for &target in targets {
                     self.assert_iscleanup(body, block_data, target, is_cleanup);
                 }
                 self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index bc2a9d5ad1e..ba8401393d7 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -19,6 +19,8 @@ builtin_macros_asm_expected_other = expected operand, {$is_global_asm ->
 
 builtin_macros_asm_explicit_register_name = explicit register arguments cannot have names
 
+builtin_macros_asm_mayunwind = asm labels are not allowed with the `may_unwind` option
+
 builtin_macros_asm_modifier_invalid = asm template modifier must be a single character
 
 builtin_macros_asm_mutually_exclusive = the `{$opt1}` and `{$opt2}` options are mutually exclusive
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 38fa1ac5935..bc851fadc2e 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -164,6 +164,9 @@ pub fn parse_asm_args<'a>(
                 path: path.clone(),
             };
             ast::InlineAsmOperand::Sym { sym }
+        } else if !is_global_asm && p.eat_keyword(sym::label) {
+            let block = p.parse_block()?;
+            ast::InlineAsmOperand::Label { block }
         } else if allow_templates {
             let template = p.parse_expr()?;
             // If it can't possibly expand to a string, provide diagnostics here to include other
@@ -240,6 +243,7 @@ pub fn parse_asm_args<'a>(
     let mut have_real_output = false;
     let mut outputs_sp = vec![];
     let mut regclass_outputs = vec![];
+    let mut labels_sp = vec![];
     for (op, op_sp) in &args.operands {
         match op {
             ast::InlineAsmOperand::Out { reg, expr, .. }
@@ -257,6 +261,9 @@ pub fn parse_asm_args<'a>(
                     regclass_outputs.push(*op_sp);
                 }
             }
+            ast::InlineAsmOperand::Label { .. } => {
+                labels_sp.push(*op_sp);
+            }
             _ => {}
         }
     }
@@ -268,6 +275,9 @@ pub fn parse_asm_args<'a>(
         // Bail out now since this is likely to confuse MIR
         return Err(err);
     }
+    if args.options.contains(ast::InlineAsmOptions::MAY_UNWIND) && !labels_sp.is_empty() {
+        dcx.emit_err(errors::AsmMayUnwind { labels_sp });
+    }
 
     if args.clobber_abis.len() > 0 {
         if is_global_asm {
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index 1de95ca81f7..93f7d09546b 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -1,5 +1,6 @@
 use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute};
 
+use core::ops::ControlFlow;
 use rustc_ast as ast;
 use rustc_ast::mut_visit::MutVisitor;
 use rustc_ast::ptr::P;
@@ -87,41 +88,40 @@ fn flat_map_annotatable(
     }
 }
 
-struct CfgFinder {
-    has_cfg_or_cfg_attr: bool,
-}
-
-impl CfgFinder {
-    fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool {
-        let mut finder = CfgFinder { has_cfg_or_cfg_attr: false };
-        match annotatable {
-            Annotatable::Item(item) => finder.visit_item(item),
-            Annotatable::TraitItem(item) => finder.visit_assoc_item(item, visit::AssocCtxt::Trait),
-            Annotatable::ImplItem(item) => finder.visit_assoc_item(item, visit::AssocCtxt::Impl),
-            Annotatable::ForeignItem(item) => finder.visit_foreign_item(item),
-            Annotatable::Stmt(stmt) => finder.visit_stmt(stmt),
-            Annotatable::Expr(expr) => finder.visit_expr(expr),
-            Annotatable::Arm(arm) => finder.visit_arm(arm),
-            Annotatable::ExprField(field) => finder.visit_expr_field(field),
-            Annotatable::PatField(field) => finder.visit_pat_field(field),
-            Annotatable::GenericParam(param) => finder.visit_generic_param(param),
-            Annotatable::Param(param) => finder.visit_param(param),
-            Annotatable::FieldDef(field) => finder.visit_field_def(field),
-            Annotatable::Variant(variant) => finder.visit_variant(variant),
-            Annotatable::Crate(krate) => finder.visit_crate(krate),
-        };
-        finder.has_cfg_or_cfg_attr
-    }
-}
+fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool {
+    struct CfgFinder;
 
-impl<'ast> visit::Visitor<'ast> for CfgFinder {
-    fn visit_attribute(&mut self, attr: &'ast Attribute) {
-        // We want short-circuiting behavior, so don't use the '|=' operator.
-        self.has_cfg_or_cfg_attr = self.has_cfg_or_cfg_attr
-            || attr
+    impl<'ast> visit::Visitor<'ast> for CfgFinder {
+        type Result = ControlFlow<()>;
+        fn visit_attribute(&mut self, attr: &'ast Attribute) -> ControlFlow<()> {
+            if attr
                 .ident()
-                .is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr);
+                .is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr)
+            {
+                ControlFlow::Break(())
+            } else {
+                ControlFlow::Continue(())
+            }
+        }
     }
+
+    let res = match annotatable {
+        Annotatable::Item(item) => CfgFinder.visit_item(item),
+        Annotatable::TraitItem(item) => CfgFinder.visit_assoc_item(item, visit::AssocCtxt::Trait),
+        Annotatable::ImplItem(item) => CfgFinder.visit_assoc_item(item, visit::AssocCtxt::Impl),
+        Annotatable::ForeignItem(item) => CfgFinder.visit_foreign_item(item),
+        Annotatable::Stmt(stmt) => CfgFinder.visit_stmt(stmt),
+        Annotatable::Expr(expr) => CfgFinder.visit_expr(expr),
+        Annotatable::Arm(arm) => CfgFinder.visit_arm(arm),
+        Annotatable::ExprField(field) => CfgFinder.visit_expr_field(field),
+        Annotatable::PatField(field) => CfgFinder.visit_pat_field(field),
+        Annotatable::GenericParam(param) => CfgFinder.visit_generic_param(param),
+        Annotatable::Param(param) => CfgFinder.visit_param(param),
+        Annotatable::FieldDef(field) => CfgFinder.visit_field_def(field),
+        Annotatable::Variant(variant) => CfgFinder.visit_variant(variant),
+        Annotatable::Crate(krate) => CfgFinder.visit_crate(krate),
+    };
+    res.is_break()
 }
 
 impl CfgEval<'_, '_> {
@@ -132,7 +132,7 @@ impl CfgEval<'_, '_> {
     fn configure_annotatable(&mut self, mut annotatable: Annotatable) -> Option<Annotatable> {
         // Tokenizing and re-parsing the `Annotatable` can have a significant
         // performance impact, so try to avoid it if possible
-        if !CfgFinder::has_cfg_or_cfg_attr(&annotatable) {
+        if !has_cfg_or_cfg_attr(&annotatable) {
             return Some(annotatable);
         }
 
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index fae0e1d380c..292a916e2a7 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -1,6 +1,7 @@
 use crate::deriving::generic::ty::*;
 use crate::deriving::generic::*;
 use crate::errors;
+use core::ops::ControlFlow;
 use rustc_ast as ast;
 use rustc_ast::visit::walk_list;
 use rustc_ast::{attr, EnumDef, VariantData};
@@ -231,20 +232,19 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonVariantDefaultAttr<'a, '
 }
 
 fn has_a_default_variant(item: &Annotatable) -> bool {
-    struct HasDefaultAttrOnVariant {
-        found: bool,
-    }
+    struct HasDefaultAttrOnVariant;
 
     impl<'ast> rustc_ast::visit::Visitor<'ast> for HasDefaultAttrOnVariant {
-        fn visit_variant(&mut self, v: &'ast rustc_ast::Variant) {
+        type Result = ControlFlow<()>;
+        fn visit_variant(&mut self, v: &'ast rustc_ast::Variant) -> ControlFlow<()> {
             if v.attrs.iter().any(|attr| attr.has_name(kw::Default)) {
-                self.found = true;
+                ControlFlow::Break(())
+            } else {
+                // no need to subrecurse.
+                ControlFlow::Continue(())
             }
-            // no need to subrecurse.
         }
     }
 
-    let mut visitor = HasDefaultAttrOnVariant { found: false };
-    item.visit_with(&mut visitor);
-    visitor.found
+    item.visit_with(&mut HasDefaultAttrOnVariant).is_break()
 }
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index a2570e58713..06302ae577a 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -767,6 +767,13 @@ pub(crate) struct AsmNoReturn {
 }
 
 #[derive(Diagnostic)]
+#[diag(builtin_macros_asm_mayunwind)]
+pub(crate) struct AsmMayUnwind {
+    #[primary_span]
+    pub(crate) labels_sp: Vec<Span>,
+}
+
+#[derive(Diagnostic)]
 #[diag(builtin_macros_global_asm_clobber_abi)]
 pub(crate) struct GlobalAsmClobberAbi {
     #[primary_span]
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
index cf9a105538d..5f0f3e6549c 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
@@ -44,9 +44,10 @@ jobs:
             env:
               TARGET_TRIPLE: x86_64-apple-darwin
           # cross-compile from Linux to Windows using mingw
-          - os: ubuntu-latest
-            env:
-              TARGET_TRIPLE: x86_64-pc-windows-gnu
+          # FIXME The wine version in Ubuntu 22.04 is missing ProcessPrng
+          #- os: ubuntu-latest
+          #  env:
+          #    TARGET_TRIPLE: x86_64-pc-windows-gnu
           - os: ubuntu-latest
             env:
               TARGET_TRIPLE: aarch64-unknown-linux-gnu
@@ -80,11 +81,11 @@ jobs:
       if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
       run: rustup set default-host x86_64-pc-windows-gnu
 
-    - name: Install MinGW toolchain and wine
-      if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
-      run: |
-        sudo apt-get update
-        sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable
+    #- name: Install MinGW toolchain and wine
+    #  if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
+    #  run: |
+    #    sudo apt-get update
+    #    sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable
 
     - name: Install AArch64 toolchain and qemu
       if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'aarch64-unknown-linux-gnu'
diff --git a/compiler/rustc_codegen_cranelift/.gitignore b/compiler/rustc_codegen_cranelift/.gitignore
index e6ac8c8408d..7915fa138f8 100644
--- a/compiler/rustc_codegen_cranelift/.gitignore
+++ b/compiler/rustc_codegen_cranelift/.gitignore
@@ -1,18 +1,21 @@
-/target
-/build_system/target
-**/*.rs.bk
-*.rlib
-*.o
-perf.data
-perf.data.old
-*.events
-*.string*
+# Build artifacts during normal use
 /y.bin
 /y.bin.dSYM
 /y.exe
 /y.pdb
+/download
 /build
 /dist
+/target
+/build_system/target
+
+# Downloaded by certain scripts
 /rust
-/download
 /git-fixed-subtree.sh
+
+# Various things that can be created during development
+*.rlib
+*.o
+perf.data
+perf.data.old
+*.mm_profdata
diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock
index b70a1234af3..e308cf80284 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.lock
+++ b/compiler/rustc_codegen_cranelift/Cargo.lock
@@ -46,18 +46,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "cranelift-bforest"
-version = "0.104.0"
+version = "0.105.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d819feeda4c420a18f1e28236ca0ce1177b22bf7c8a44ddee92dfe40de15bcf0"
+checksum = "9515fcc42b6cb5137f76b84c1a6f819782d0cf12473d145d3bc5cd67eedc8bc2"
 dependencies = [
  "cranelift-entity",
 ]
 
 [[package]]
 name = "cranelift-codegen"
-version = "0.104.0"
+version = "0.105.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9b8d03d5bdbca7e5f72b0e0a0f69933ed1f09e24be6c075aa6fe3f802b0cc0c"
+checksum = "1ad827c6071bfe6d22de1bc331296a29f9ddc506ff926d8415b435ec6a6efce0"
 dependencies = [
  "bumpalo",
  "cranelift-bforest",
@@ -76,39 +76,39 @@ dependencies = [
 
 [[package]]
 name = "cranelift-codegen-meta"
-version = "0.104.0"
+version = "0.105.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3fd3664e38e51649b17dc30cfdd561273fe2f590dcd013fb75d9eabc6272dfb"
+checksum = "10e6b36237a9ca2ce2fb4cc7741d418a080afa1327402138412ef85d5367bef1"
 dependencies = [
  "cranelift-codegen-shared",
 ]
 
 [[package]]
 name = "cranelift-codegen-shared"
-version = "0.104.0"
+version = "0.105.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b031ec5e605828975952622b5a77d49126f20ffe88d33719a0af66b23a0fc36"
+checksum = "c36bf4bfb86898a94ccfa773a1f86e8a5346b1983ff72059bdd2db4600325251"
 
 [[package]]
 name = "cranelift-control"
-version = "0.104.0"
+version = "0.105.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fada054d017cf2ed8f7ed2336e0517fc1b19e6825be1790de9eb00c94788362b"
+checksum = "7cbf36560e7a6bd1409ca91e7b43b2cc7ed8429f343d7605eadf9046e8fac0d0"
 dependencies = [
  "arbitrary",
 ]
 
 [[package]]
 name = "cranelift-entity"
-version = "0.104.0"
+version = "0.105.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "177b6f94ae8de6348eb45bf977c79ab9e3c40fc3ac8cb7ed8109560ea39bee7d"
+checksum = "a71e11061a75b1184c09bea97c026a88f08b59ade96a7bb1f259d4ea0df2e942"
 
 [[package]]
 name = "cranelift-frontend"
-version = "0.104.0"
+version = "0.105.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebebd23a69a23e3ddea78e98ff3a2de222e88c8e045d81ef4a72f042e0d79dbd"
+checksum = "af5d4da63143ee3485c7bcedde0a818727d737d1083484a0ceedb8950c89e495"
 dependencies = [
  "cranelift-codegen",
  "log",
@@ -118,15 +118,15 @@ dependencies = [
 
 [[package]]
 name = "cranelift-isle"
-version = "0.104.0"
+version = "0.105.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1571bfc14df8966d12c6121b5325026591a4b4009e22fea0fe3765ab7cd33b96"
+checksum = "457a9832b089e26f5eea70dcf49bed8ec6edafed630ce7c83161f24d46ab8085"
 
 [[package]]
 name = "cranelift-jit"
-version = "0.104.0"
+version = "0.105.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f61e236d7622c3c43016e8b0f3ba27136e21ac7de328c7fda902e61db1de851"
+checksum = "0af95fe68d5a10919012c8db82b1d59820405b8001c8c6d05f94b08031334fa9"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -144,9 +144,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-module"
-version = "0.104.0"
+version = "0.105.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f30c6820342015c5009070e3e48d1da7b13521399de904663f1c84f5ee839657"
+checksum = "11b0b201fa10a4014062d4c56c307c8d18fdf9a84cb5279efe6080241f42c7a7"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -155,9 +155,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-native"
-version = "0.104.0"
+version = "0.105.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35a69c37e0c10b46fe5527f2397ac821046efbf5f7ec112c8b84df25712f465b"
+checksum = "9b490d579df1ce365e1ea359e24ed86d82289fa785153327c2f6a69a59a731e4"
 dependencies = [
  "cranelift-codegen",
  "libc",
@@ -166,9 +166,9 @@ dependencies = [
 
 [[package]]
 name = "cranelift-object"
-version = "0.104.0"
+version = "0.105.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24425a329b4343177d5f1852243841dcec17f929d72c0e7f41262140155e55e7"
+checksum = "fb7e821ac6db471bcdbd004e5a4fa0d374f1046bd3a2ce278c332e0b0c01ca63"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -241,9 +241,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.148"
+version = "0.2.153"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
+checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
 
 [[package]]
 name = "libloading"
@@ -410,9 +410,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
 [[package]]
 name = "wasmtime-jit-icache-coherence"
-version = "17.0.0"
+version = "18.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdc26415bb89e9ccd3bdc498fef63aabf665c4c0dd710c107691deb9694955da"
+checksum = "33f4121cb29dda08139b2824a734dd095d83ce843f2d613a84eb580b9cfc17ac"
 dependencies = [
  "cfg-if",
  "libc",
diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml
index 586ce2286f9..c0b9e27b179 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.toml
+++ b/compiler/rustc_codegen_cranelift/Cargo.toml
@@ -8,12 +8,12 @@ crate-type = ["dylib"]
 
 [dependencies]
 # These have to be in sync with each other
-cranelift-codegen = { version = "0.104", default-features = false, features = ["std", "unwind", "all-arch"] }
-cranelift-frontend = { version = "0.104" }
-cranelift-module = { version = "0.104" }
-cranelift-native = { version = "0.104" }
-cranelift-jit = { version = "0.104", optional = true }
-cranelift-object = { version = "0.104" }
+cranelift-codegen = { version = "0.105.2", default-features = false, features = ["std", "unwind", "all-arch"] }
+cranelift-frontend = { version = "0.105.2" }
+cranelift-module = { version = "0.105.2" }
+cranelift-native = { version = "0.105.2" }
+cranelift-jit = { version = "0.105.2", optional = true }
+cranelift-object = { version = "0.105.2" }
 target-lexicon = "0.12.0"
 gimli = { version = "0.28", default-features = false, features = ["write"]}
 object = { version = "0.32", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
diff --git a/compiler/rustc_codegen_cranelift/Readme.md b/compiler/rustc_codegen_cranelift/Readme.md
index 4f455261963..a297b22326f 100644
--- a/compiler/rustc_codegen_cranelift/Readme.md
+++ b/compiler/rustc_codegen_cranelift/Readme.md
@@ -123,11 +123,6 @@ You need to do this steps to successfully compile and use the cranelift backend
 
 You can also set `rust-analyzer.rustc.source` to your rust workspace to get rust-analyzer to understand your changes.
 
-## Configuration
-
-See the documentation on the `BackendConfig` struct in [config.rs](src/config.rs) for all
-configuration options.
-
 ## Not yet supported
 
 * SIMD ([tracked here](https://github.com/rust-lang/rustc_codegen_cranelift/issues/171), `std::simd` fully works, `std::arch` is partially supported)
diff --git a/compiler/rustc_codegen_cranelift/build_system/prepare.rs b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
index c68968b4fde..3677d0a7d36 100644
--- a/compiler/rustc_codegen_cranelift/build_system/prepare.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
@@ -1,5 +1,6 @@
 use std::ffi::OsStr;
 use std::fs;
+use std::hash::{Hash, Hasher};
 use std::path::{Path, PathBuf};
 use std::process::Command;
 
@@ -71,7 +72,11 @@ fn hash_file(file: &std::path::Path) -> u64 {
     let contents = std::fs::read(file).unwrap();
     #[allow(deprecated)]
     let mut hasher = std::hash::SipHasher::new();
-    std::hash::Hash::hash(&contents, &mut hasher);
+    // The following is equivalent to
+    //   std::hash::Hash::hash(&contents, &mut hasher);
+    // but gives the same result independent of host byte order.
+    hasher.write_usize(contents.len().to_le());
+    Hash::hash_slice(&contents, &mut hasher);
     std::hash::Hasher::finish(&hasher)
 }
 
@@ -80,16 +85,26 @@ fn hash_dir(dir: &std::path::Path) -> u64 {
     for entry in std::fs::read_dir(dir).unwrap() {
         let entry = entry.unwrap();
         if entry.file_type().unwrap().is_dir() {
-            sub_hashes
-                .insert(entry.file_name().to_str().unwrap().to_owned(), hash_dir(&entry.path()));
+            sub_hashes.insert(
+                entry.file_name().to_str().unwrap().to_owned(),
+                hash_dir(&entry.path()).to_le(),
+            );
         } else {
-            sub_hashes
-                .insert(entry.file_name().to_str().unwrap().to_owned(), hash_file(&entry.path()));
+            sub_hashes.insert(
+                entry.file_name().to_str().unwrap().to_owned(),
+                hash_file(&entry.path()).to_le(),
+            );
         }
     }
     #[allow(deprecated)]
     let mut hasher = std::hash::SipHasher::new();
-    std::hash::Hash::hash(&sub_hashes, &mut hasher);
+    // The following is equivalent to
+    //   std::hash::Hash::hash(&sub_hashes, &mut hasher);
+    // but gives the same result independent of host byte order.
+    hasher.write_usize(sub_hashes.len().to_le());
+    for elt in sub_hashes {
+        elt.hash(&mut hasher);
+    }
     std::hash::Hasher::finish(&hasher)
 }
 
diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs
index 818f3d6f08d..1c3e615c7ab 100644
--- a/compiler/rustc_codegen_cranelift/build_system/tests.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs
@@ -133,8 +133,8 @@ pub(crate) static REGEX: CargoProject = CargoProject::new(&REGEX_REPO.source_dir
 pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github(
     "rust-lang",
     "portable-simd",
-    "97007cc2e70df8c97326ce896a79e2f0ce4dd98b",
-    "e54a16035cedf205",
+    "5794c837bc605c4cd9dbb884285976dfdb293cce",
+    "a64d8fdd0ed0d9c4",
     "portable-simd",
 );
 
diff --git a/compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch b/compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch
index 6afa5c71fe5..5442c3cef9e 100644
--- a/compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0022-coretests-Disable-not-compiling-tests.patch
@@ -39,6 +39,6 @@ index 42a26ae..5ac1042 100644
 +#![cfg(test)]
  #![feature(alloc_layout_extra)]
  #![feature(array_chunks)]
- #![feature(array_methods)]
+ #![feature(array_windows)]
 --
 2.21.0 (Apple Git-122)
diff --git a/compiler/rustc_codegen_cranelift/patches/0023-coretests-Ignore-failing-tests.patch b/compiler/rustc_codegen_cranelift/patches/0023-coretests-Ignore-failing-tests.patch
deleted file mode 100644
index 385f5a8a2e0..00000000000
--- a/compiler/rustc_codegen_cranelift/patches/0023-coretests-Ignore-failing-tests.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From dd82e95c9de212524e14fc60155de1ae40156dfc Mon Sep 17 00:00:00 2001
-From: bjorn3 <bjorn3@users.noreply.github.com>
-Date: Sun, 24 Nov 2019 15:34:06 +0100
-Subject: [PATCH] [core] Ignore failing tests
-
----
- library/core/tests/iter.rs       |  4 ++++
- library/core/tests/num/bignum.rs | 10 ++++++++++
- library/core/tests/num/mod.rs    |  5 +++--
- library/core/tests/time.rs       |  1 +
- 4 files changed, 18 insertions(+), 2 deletions(-)
-
-diff --git a/atomic.rs b/atomic.rs
-index 13b12db..96fe4b9 100644
---- a/atomic.rs
-+++ b/atomic.rs
-@@ -185,6 +185,7 @@ fn ptr_bitops() {
- }
- 
- #[test]
-+#[cfg_attr(target_arch = "s390x", ignore)] // s390x backend doesn't support stack alignment >8 bytes
- #[cfg(any(not(target_arch = "arm"), target_os = "linux"))] // Missing intrinsic in compiler-builtins
- fn ptr_bitops_tagging() {
-     #[repr(align(16))]
--- 
-2.21.0 (Apple Git-122)
diff --git a/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml b/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
index ad63b0768d3..369f9c88be1 100644
--- a/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
+++ b/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
@@ -150,9 +150,9 @@ dependencies = [
 
 [[package]]
 name = "hermit-abi"
-version = "0.3.3"
+version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
+checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
 dependencies = [
  "compiler_builtins",
  "rustc-std-workspace-alloc",
@@ -161,9 +161,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.150"
+version = "0.2.153"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
+checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -398,6 +398,7 @@ version = "0.0.0"
 dependencies = [
  "core",
  "getopts",
+ "libc",
  "panic_abort",
  "panic_unwind",
  "std",
diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain
index ccd7edbc2a9..e9f225b4e9e 100644
--- a/compiler/rustc_codegen_cranelift/rust-toolchain
+++ b/compiler/rustc_codegen_cranelift/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-01-26"
+channel = "nightly-2024-03-08"
 components = ["rust-src", "rustc-dev", "llvm-tools"]
diff --git a/compiler/rustc_codegen_cranelift/rustfmt.toml b/compiler/rustc_codegen_cranelift/rustfmt.toml
index 0f884187add..6f4d4413c25 100644
--- a/compiler/rustc_codegen_cranelift/rustfmt.toml
+++ b/compiler/rustc_codegen_cranelift/rustfmt.toml
@@ -1,5 +1,4 @@
 ignore = [
-    "y.rs",
     "example/gen_block_iterate.rs", # uses edition 2024
 ]
 
diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
index 636f2875a68..e884577d519 100755
--- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
@@ -10,12 +10,26 @@ pushd rust
 
 command -v rg >/dev/null 2>&1 || cargo install ripgrep
 
+# FIXME(rust-lang/rust#122196) fix stage0 rmake.rs run-make tests and remove
+# this workaround
+for test in $(ls tests/run-make); do
+  if [[ -e "tests/run-make/$test/rmake.rs" ]]; then
+    rm -r "tests/run-make/$test"
+  fi
+done
+
+# FIXME remove this workaround once ICE tests no longer emit an outdated nightly message
+for test in $(rg -i --files-with-matches "//@(\[.*\])? failure-status: 101" tests/ui); do
+  echo "rm $test"
+  rm $test
+done
+
 rm -r tests/ui/{unsized-locals/,lto/,linkage*} || true
 for test in $(rg --files-with-matches "lto" tests/{codegen-units,ui,incremental}); do
   rm $test
 done
 
-for test in $(rg -i --files-with-matches "//(\[\w+\])?~[^\|]*\s*ERR|// error-pattern:|// build-fail|// run-fail|-Cllvm-args" tests/ui); do
+for test in $(rg -i --files-with-matches "//(\[\w+\])?~[^\|]*\s*ERR|//@ error-pattern:|//@(\[.*\])? build-fail|//@(\[.*\])? run-fail|-Cllvm-args" tests/ui); do
   rm $test
 done
 
@@ -43,8 +57,8 @@ rm tests/ui/proc-macro/allowed-signatures.rs
 rm tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs
 
 # vendor intrinsics
-rm tests/ui/sse2.rs # CodegenBackend::target_features not yet implemented
 rm tests/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant"
+rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic
 
 # exotic linkages
 rm tests/ui/issues/issue-33992.rs # unsupported linkages
@@ -62,14 +76,12 @@ rm -r tests/run-pass-valgrind/unsized-locals
 # misc unimplemented things
 rm tests/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and nearbyintf64 intrinsics
 rm tests/ui/target-feature/missing-plusminus.rs # error not implemented
-rm tests/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment
 rm -r tests/run-make/emit-named-files # requires full --emit support
 rm -r tests/run-make/repr128-dwarf # debuginfo test
 rm -r tests/run-make/split-debuginfo # same
 rm -r tests/run-make/symbols-include-type-name # --emit=asm not supported
 rm -r tests/run-make/target-specs # i686 not supported by Cranelift
 rm -r tests/run-make/mismatching-target-triples # same
-rm tests/ui/asm/x86_64/issue-82869.rs # vector regs in inline asm not yet supported
 rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly
 
 # requires LTO
@@ -109,8 +121,6 @@ rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific
 rm tests/ui/mir/mir_misc_casts.rs # depends on deduplication of constants
 rm tests/ui/mir/mir_raw_fat_ptr.rs # same
 rm tests/ui/consts/issue-33537.rs # same
-rm tests/ui/layout/valid_range_oob.rs # different ICE message
-rm tests/ui/const-generics/generic_const_exprs/issue-80742.rs # gives error instead of ICE with cg_clif
 
 # rustdoc-clif passes extra args, suppressing the help message when no args are passed
 rm -r tests/run-make/issue-88756-default-output
@@ -119,15 +129,12 @@ rm -r tests/run-make/issue-88756-default-output
 # should work when using ./x.py test the way it is intended
 # ============================================================
 rm -r tests/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
-rm -r tests/ui/consts/missing_span_in_backtrace.rs # expects sysroot source to be elsewhere
 
 # genuine bugs
 # ============
 rm tests/incremental/spike-neg1.rs # errors out for some reason
 rm tests/incremental/spike-neg2.rs # same
 
-rm tests/ui/simd/simd-bitmask.rs # simd_bitmask doesn't implement [u*; N] return type
-
 rm -r tests/run-make/issue-51671 # wrong filename given in case of --emit=obj
 rm -r tests/run-make/issue-30063 # same
 rm -r tests/run-make/multiple-emits # same
@@ -145,6 +152,7 @@ rm tests/ui/codegen/subtyping-enforces-type-equality.rs # assert_assignable bug
 # ======================
 rm tests/ui/backtrace.rs # TODO warning
 rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue
+rm tests/ui/async-await/async-closures/once.rs # FIXME bug in the rustc FnAbi calculation code
 
 rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
 
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index a7e76fbc128..1ce920f3bdb 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -445,7 +445,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                 template,
                 operands,
                 options,
-                destination,
+                targets,
                 line_spans: _,
                 unwind: _,
             } => {
@@ -456,13 +456,25 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                     );
                 }
 
+                let have_labels = if options.contains(InlineAsmOptions::NORETURN) {
+                    !targets.is_empty()
+                } else {
+                    targets.len() > 1
+                };
+                if have_labels {
+                    fx.tcx.dcx().span_fatal(
+                        source_info.span,
+                        "cranelift doesn't support labels in inline assembly.",
+                    );
+                }
+
                 crate::inline_asm::codegen_inline_asm_terminator(
                     fx,
                     source_info.span,
                     template,
                     operands,
                     *options,
-                    *destination,
+                    targets.get(0).copied(),
                 );
             }
             TerminatorKind::UnwindTerminate(reason) => {
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index e35ec4fe1c7..7e29d407a1f 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -392,18 +392,25 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
     }
 
     pub(crate) fn create_stack_slot(&mut self, size: u32, align: u32) -> Pointer {
-        if align <= 16 {
+        let abi_align = if self.tcx.sess.target.arch == "s390x" { 8 } else { 16 };
+        if align <= abi_align {
             let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData {
                 kind: StackSlotKind::ExplicitSlot,
-                // FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
-                // specify stack slot alignment.
-                size: (size + 15) / 16 * 16,
+                // FIXME Don't force the size to a multiple of <abi_align> bytes once Cranelift gets
+                // a way to specify stack slot alignment.
+                size: (size + abi_align - 1) / abi_align * abi_align,
             });
             Pointer::stack_slot(stack_slot)
         } else {
             // Alignment is too big to handle using the above hack. Dynamically realign a stack slot
             // instead. This wastes some space for the realignment.
-            let base_ptr = self.create_stack_slot(size + align, 16).get_addr(self);
+            let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData {
+                kind: StackSlotKind::ExplicitSlot,
+                // FIXME Don't force the size to a multiple of <abi_align> bytes once Cranelift gets
+                // a way to specify stack slot alignment.
+                size: (size + align) / abi_align * abi_align,
+            });
+            let base_ptr = self.bcx.ins().stack_addr(self.pointer_type, stack_slot, 0);
             let misalign_offset = self.bcx.ins().urem_imm(base_ptr, i64::from(align));
             let realign_offset = self.bcx.ins().irsub_imm(misalign_offset, i64::from(align));
             Pointer::new(self.bcx.ins().iadd(base_ptr, realign_offset))
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index b6de688130c..18c5960ffc6 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -372,7 +372,13 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
         }
 
         let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec();
-        data.define(bytes.into_boxed_slice());
+        if bytes.is_empty() {
+            // FIXME(bytecodealliance/wasmtime#7918) cranelift-jit has a bug where it causes UB on
+            // empty data objects
+            data.define(Box::new([0]));
+        } else {
+            data.define(bytes.into_boxed_slice());
+        }
 
         for &(offset, prov) in alloc.provenance().ptrs().iter() {
             let alloc_id = prov.alloc_id();
diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs
index da07b66c762..44650898de8 100644
--- a/compiler/rustc_codegen_cranelift/src/global_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs
@@ -78,7 +78,8 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
                         InlineAsmOperand::In { .. }
                         | InlineAsmOperand::Out { .. }
                         | InlineAsmOperand::InOut { .. }
-                        | InlineAsmOperand::SplitInOut { .. } => {
+                        | InlineAsmOperand::SplitInOut { .. }
+                        | InlineAsmOperand::Label { .. } => {
                             span_bug!(op_sp, "invalid operand type for global_asm!")
                         }
                     }
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
index 7793b1b7092..171ee88a11c 100644
--- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs
@@ -129,6 +129,9 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>(
                 let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
                 CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance).name.to_owned() }
             }
+            InlineAsmOperand::Label { .. } => {
+                span_bug!(span, "asm! label operands are not yet supported");
+            }
         })
         .collect::<Vec<_>>();
 
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
index 2e3e7ce986b..1615dc5de69 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
@@ -170,6 +170,65 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
             }
         }
 
+        "llvm.x86.sse.add.ss" => {
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_add_ss&ig_expand=171
+            intrinsic_args!(fx, args => (a, b); intrinsic);
+
+            assert_eq!(a.layout(), b.layout());
+            assert_eq!(a.layout(), ret.layout());
+            let layout = a.layout();
+
+            let (_, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+            assert!(lane_ty.is_floating_point());
+            let ret_lane_layout = fx.layout_of(lane_ty);
+
+            ret.write_cvalue(fx, a);
+
+            let a_lane = a.value_lane(fx, 0).load_scalar(fx);
+            let b_lane = b.value_lane(fx, 0).load_scalar(fx);
+
+            let res = fx.bcx.ins().fadd(a_lane, b_lane);
+
+            let res_lane = CValue::by_val(res, ret_lane_layout);
+            ret.place_lane(fx, 0).write_cvalue(fx, res_lane);
+        }
+
+        "llvm.x86.sse.sqrt.ps" => {
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sqrt_ps&ig_expand=6245
+            intrinsic_args!(fx, args => (a); intrinsic);
+
+            // FIXME use vector instructions when possible
+            simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
+                fx.bcx.ins().sqrt(lane)
+            });
+        }
+
+        "llvm.x86.sse.max.ps" => {
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_max_ps&ig_expand=4357
+            intrinsic_args!(fx, args => (a, b); intrinsic);
+
+            simd_pair_for_each_lane(
+                fx,
+                a,
+                b,
+                ret,
+                &|fx, _lane_ty, _res_lane_ty, a_lane, b_lane| fx.bcx.ins().fmax(a_lane, b_lane),
+            );
+        }
+
+        "llvm.x86.sse.min.ps" => {
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_min_ps&ig_expand=4489
+            intrinsic_args!(fx, args => (a, b); intrinsic);
+
+            simd_pair_for_each_lane(
+                fx,
+                a,
+                b,
+                ret,
+                &|fx, _lane_ty, _res_lane_ty, a_lane, b_lane| fx.bcx.ins().fmin(a_lane, b_lane),
+            );
+        }
+
         "llvm.x86.sse.cmp.ps" | "llvm.x86.sse2.cmp.pd" => {
             let (x, y, kind) = match args {
                 [x, y, kind] => (x, y, kind),
@@ -1067,6 +1126,122 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
             );
         }
 
+        "llvm.x86.sha1rnds4" => {
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sha1rnds4_epu32&ig_expand=5877
+            intrinsic_args!(fx, args => (a, b, _func); intrinsic);
+
+            let a = a.load_scalar(fx);
+            let b = b.load_scalar(fx);
+
+            let func = if let Some(func) =
+                crate::constant::mir_operand_get_const_val(fx, &args[2].node)
+            {
+                func
+            } else {
+                fx.tcx
+                    .dcx()
+                    .span_fatal(span, "Func argument for `_mm_sha1rnds4_epu32` is not a constant");
+            };
+
+            let func = func.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", func));
+
+            codegen_inline_asm_inner(
+                fx,
+                &[InlineAsmTemplatePiece::String(format!("sha1rnds4 xmm1, xmm2, {func}"))],
+                &[
+                    CInlineAsmOperand::InOut {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
+                        _late: true,
+                        in_value: a,
+                        out_place: Some(ret),
+                    },
+                    CInlineAsmOperand::In {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm2)),
+                        value: b,
+                    },
+                ],
+                InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+            );
+        }
+
+        "llvm.x86.sha1msg1" => {
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sha1msg1_epu32&ig_expand=5874
+            intrinsic_args!(fx, args => (a, b); intrinsic);
+
+            let a = a.load_scalar(fx);
+            let b = b.load_scalar(fx);
+
+            codegen_inline_asm_inner(
+                fx,
+                &[InlineAsmTemplatePiece::String("sha1msg1 xmm1, xmm2".to_string())],
+                &[
+                    CInlineAsmOperand::InOut {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
+                        _late: true,
+                        in_value: a,
+                        out_place: Some(ret),
+                    },
+                    CInlineAsmOperand::In {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm2)),
+                        value: b,
+                    },
+                ],
+                InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+            );
+        }
+
+        "llvm.x86.sha1msg2" => {
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sha1msg2_epu32&ig_expand=5875
+            intrinsic_args!(fx, args => (a, b); intrinsic);
+
+            let a = a.load_scalar(fx);
+            let b = b.load_scalar(fx);
+
+            codegen_inline_asm_inner(
+                fx,
+                &[InlineAsmTemplatePiece::String("sha1msg2 xmm1, xmm2".to_string())],
+                &[
+                    CInlineAsmOperand::InOut {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
+                        _late: true,
+                        in_value: a,
+                        out_place: Some(ret),
+                    },
+                    CInlineAsmOperand::In {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm2)),
+                        value: b,
+                    },
+                ],
+                InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+            );
+        }
+
+        "llvm.x86.sha1nexte" => {
+            // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sha1nexte_epu32&ig_expand=5876
+            intrinsic_args!(fx, args => (a, b); intrinsic);
+
+            let a = a.load_scalar(fx);
+            let b = b.load_scalar(fx);
+
+            codegen_inline_asm_inner(
+                fx,
+                &[InlineAsmTemplatePiece::String("sha1nexte xmm1, xmm2".to_string())],
+                &[
+                    CInlineAsmOperand::InOut {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
+                        _late: true,
+                        in_value: a,
+                        out_place: Some(ret),
+                    },
+                    CInlineAsmOperand::In {
+                        reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm2)),
+                        value: b,
+                    },
+                ],
+                InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM,
+            );
+        }
+
         "llvm.x86.sha256rnds2" => {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sha256rnds2_epu32&ig_expand=5977
             intrinsic_args!(fx, args => (a, b, k); intrinsic);
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index 9b8167fa2bf..8b86a116df1 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -391,12 +391,15 @@ fn codegen_float_intrinsic_call<'tcx>(
         | sym::ceilf32
         | sym::ceilf64
         | sym::truncf32
-        | sym::truncf64 => {
+        | sym::truncf64
+        | sym::sqrtf32
+        | sym::sqrtf64 => {
             let val = match intrinsic {
                 sym::fabsf32 | sym::fabsf64 => fx.bcx.ins().fabs(args[0]),
                 sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]),
                 sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]),
                 sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]),
+                sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]),
                 _ => unreachable!(),
             };
 
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index 8f662808522..79da970a58e 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -853,7 +853,13 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
             };
 
             for lane in 0..lane_count {
-                let m_lane = fx.bcx.ins().ushr_imm(m, u64::from(lane) as i64);
+                // The bit order of the mask depends on the byte endianness, LSB-first for
+                // little endian and MSB-first for big endian.
+                let mask_lane = match fx.tcx.sess.target.endian {
+                    Endian::Big => lane_count - 1 - lane,
+                    Endian::Little => lane,
+                };
+                let m_lane = fx.bcx.ins().ushr_imm(m, u64::from(mask_lane) as i64);
                 let m_lane = fx.bcx.ins().band_imm(m_lane, 1);
                 let a_lane = a.value_lane(fx, lane).load_scalar(fx);
                 let b_lane = b.value_lane(fx, lane).load_scalar(fx);
diff --git a/compiler/rustc_codegen_cranelift/y.rs b/compiler/rustc_codegen_cranelift/y.rs
deleted file mode 100755
index e806a64d943..00000000000
--- a/compiler/rustc_codegen_cranelift/y.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env bash
-#![deny(unsafe_code)] /*This line is ignored by bash
-# This block is ignored by rustc
-echo "Warning: y.rs is a deprecated alias for y.sh" 1>&2
-exec ./y.sh "$@"
-*/
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs
index 78e8e32b972..07edd26e27a 100644
--- a/compiler/rustc_codegen_gcc/src/asm.rs
+++ b/compiler/rustc_codegen_gcc/src/asm.rs
@@ -107,7 +107,7 @@ enum ConstraintOrRegister {
 
 
 impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
-    fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], instance: Instance<'_>, _dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>) {
+    fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], instance: Instance<'_>, dest: Option<Self::BasicBlock>, _catch_funclet: Option<(Self::BasicBlock, Option<&Self::Funclet>)>) {
         if options.contains(InlineAsmOptions::MAY_UNWIND) {
             self.sess().dcx()
                 .create_err(UnwindingInlineAsm { span: span[0] })
@@ -126,6 +126,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
         // added to `outputs.len()`
         let mut inputs = vec![];
 
+        // GCC index of a label equals its position in the array added to
+        // `outputs.len() + inputs.len()`.
+        let mut labels = vec![];
+
         // Clobbers collected from `out("explicit register") _` and `inout("expl_reg") var => _`
         let mut clobbers = vec![];
 
@@ -269,6 +273,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                     // some targets to add a leading underscore (Mach-O).
                     constants_len += self.tcx.symbol_name(Instance::mono(self.tcx, def_id)).name.len();
                 }
+
+                InlineAsmOperandRef::Label { label } => {
+                    labels.push(label);
+                }
             }
         }
 
@@ -368,6 +376,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                 InlineAsmOperandRef::Const { .. } => {
                     // processed in the previous pass
                 }
+
+                InlineAsmOperandRef::Label { .. } => {
+                    // processed in the previous pass
+                }
             }
         }
 
@@ -454,6 +466,14 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                         InlineAsmOperandRef::Const { ref string } => {
                             template_str.push_str(string);
                         }
+
+                        InlineAsmOperandRef::Label { label } => {
+                            let label_gcc_index = labels.iter()
+                                .position(|&l| l == label)
+                                .expect("wrong rust index");
+                            let gcc_index = label_gcc_index + outputs.len() + inputs.len();
+                            push_to_template(Some('l'), gcc_index);
+                        }
                     }
                 }
             }
@@ -466,7 +486,12 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
         // 4. Generate Extended Asm block
 
         let block = self.llbb();
-        let extended_asm = block.add_extended_asm(None, &template_str);
+        let extended_asm = if let Some(dest) = dest {
+            assert!(!labels.is_empty());
+            block.end_with_extended_asm_goto(None, &template_str, &labels, Some(dest))
+        } else {
+            block.add_extended_asm(None, &template_str)
+        };
 
         for op in &outputs {
             extended_asm.add_output_operand(None, &op.to_constraint(), op.tmp_var);
@@ -494,7 +519,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
         if !options.contains(InlineAsmOptions::NOSTACK) {
             // TODO(@Commeownist): figure out how to align stack
         }
-        if options.contains(InlineAsmOptions::NORETURN) {
+        if dest.is_none() && options.contains(InlineAsmOptions::NORETURN) {
             let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable");
             let builtin_unreachable: RValue<'gcc> = unsafe { std::mem::transmute(builtin_unreachable) };
             self.call(self.type_void(), None, None, builtin_unreachable, &[], None);
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index a413466093b..74539d4d495 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -28,7 +28,8 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
         options: InlineAsmOptions,
         line_spans: &[Span],
         instance: Instance<'_>,
-        dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>,
+        dest: Option<Self::BasicBlock>,
+        catch_funclet: Option<(Self::BasicBlock, Option<&Self::Funclet>)>,
     ) {
         let asm_arch = self.tcx.sess.asm_arch.unwrap();
 
@@ -165,6 +166,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
         }
 
         // Build the template string
+        let mut labels = vec![];
         let mut template_str = String::new();
         for piece in template {
             match *piece {
@@ -205,6 +207,11 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                             // Only emit the raw symbol name
                             template_str.push_str(&format!("${{{}:c}}", op_idx[&operand_idx]));
                         }
+                        InlineAsmOperandRef::Label { label } => {
+                            template_str.push_str(&format!("${{{}:l}}", constraints.len()));
+                            constraints.push("!i".to_owned());
+                            labels.push(label);
+                        }
                     }
                 }
             }
@@ -292,12 +299,14 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
             &constraints.join(","),
             &inputs,
             output_type,
+            &labels,
             volatile,
             alignstack,
             dialect,
             line_spans,
             options.contains(InlineAsmOptions::MAY_UNWIND),
-            dest_catch_funclet,
+            dest,
+            catch_funclet,
         )
         .unwrap_or_else(|| span_bug!(line_spans[0], "LLVM asm constraint validation failed"));
 
@@ -317,7 +326,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
         attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs });
 
         // Switch to the 'normal' basic block if we did an `invoke` instead of a `call`
-        if let Some((dest, _, _)) = dest_catch_funclet {
+        if let Some(dest) = dest {
             self.switch_to_block(dest);
         }
 
@@ -415,16 +424,14 @@ pub(crate) fn inline_asm_call<'ll>(
     cons: &str,
     inputs: &[&'ll Value],
     output: &'ll llvm::Type,
+    labels: &[&'ll llvm::BasicBlock],
     volatile: bool,
     alignstack: bool,
     dia: llvm::AsmDialect,
     line_spans: &[Span],
     unwind: bool,
-    dest_catch_funclet: Option<(
-        &'ll llvm::BasicBlock,
-        &'ll llvm::BasicBlock,
-        Option<&Funclet<'ll>>,
-    )>,
+    dest: Option<&'ll llvm::BasicBlock>,
+    catch_funclet: Option<(&'ll llvm::BasicBlock, Option<&Funclet<'ll>>)>,
 ) -> Option<&'ll Value> {
     let volatile = if volatile { llvm::True } else { llvm::False };
     let alignstack = if alignstack { llvm::True } else { llvm::False };
@@ -457,8 +464,11 @@ pub(crate) fn inline_asm_call<'ll>(
                 can_throw,
             );
 
-            let call = if let Some((dest, catch, funclet)) = dest_catch_funclet {
-                bx.invoke(fty, None, None, v, inputs, dest, catch, funclet)
+            let call = if !labels.is_empty() {
+                assert!(catch_funclet.is_none());
+                bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None)
+            } else if let Some((catch, funclet)) = catch_funclet {
+                bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet)
             } else {
                 bx.call(fty, None, None, v, inputs, None)
             };
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index eaedaec635f..ca2e2b57580 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -1538,6 +1538,58 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         }
     }
 
+    pub(crate) fn callbr(
+        &mut self,
+        llty: &'ll Type,
+        fn_attrs: Option<&CodegenFnAttrs>,
+        fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
+        llfn: &'ll Value,
+        args: &[&'ll Value],
+        default_dest: &'ll BasicBlock,
+        indirect_dest: &[&'ll BasicBlock],
+        funclet: Option<&Funclet<'ll>>,
+    ) -> &'ll Value {
+        debug!("invoke {:?} with args ({:?})", llfn, args);
+
+        let args = self.check_call("callbr", llty, llfn, args);
+        let funclet_bundle = funclet.map(|funclet| funclet.bundle());
+        let funclet_bundle = funclet_bundle.as_ref().map(|b| &*b.raw);
+        let mut bundles: SmallVec<[_; 2]> = SmallVec::new();
+        if let Some(funclet_bundle) = funclet_bundle {
+            bundles.push(funclet_bundle);
+        }
+
+        // Emit CFI pointer type membership test
+        self.cfi_type_test(fn_attrs, fn_abi, llfn);
+
+        // Emit KCFI operand bundle
+        let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
+        let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
+        if let Some(kcfi_bundle) = kcfi_bundle {
+            bundles.push(kcfi_bundle);
+        }
+
+        let callbr = unsafe {
+            llvm::LLVMRustBuildCallBr(
+                self.llbuilder,
+                llty,
+                llfn,
+                default_dest,
+                indirect_dest.as_ptr(),
+                indirect_dest.len() as c_uint,
+                args.as_ptr(),
+                args.len() as c_uint,
+                bundles.as_ptr(),
+                bundles.len() as c_uint,
+                UNNAMED,
+            )
+        };
+        if let Some(fn_abi) = fn_abi {
+            fn_abi.apply_attrs_callsite(self, callbr);
+        }
+        callbr
+    }
+
     // Emits CFI pointer type membership tests.
     fn cfi_type_test(
         &mut self,
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 16122e5557e..d1f32087908 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -260,35 +260,29 @@ pub unsafe fn create_module<'ll>(
     }
 
     if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection {
-        let behavior = if llvm_version >= (15, 0, 0) {
-            llvm::LLVMModFlagBehavior::Min
-        } else {
-            llvm::LLVMModFlagBehavior::Error
-        };
-
         if sess.target.arch == "aarch64" {
             llvm::LLVMRustAddModuleFlag(
                 llmod,
-                behavior,
+                llvm::LLVMModFlagBehavior::Min,
                 c"branch-target-enforcement".as_ptr().cast(),
                 bti.into(),
             );
             llvm::LLVMRustAddModuleFlag(
                 llmod,
-                behavior,
+                llvm::LLVMModFlagBehavior::Min,
                 c"sign-return-address".as_ptr().cast(),
                 pac_ret.is_some().into(),
             );
             let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
             llvm::LLVMRustAddModuleFlag(
                 llmod,
-                behavior,
+                llvm::LLVMModFlagBehavior::Min,
                 c"sign-return-address-all".as_ptr().cast(),
                 pac_opts.leaf.into(),
             );
             llvm::LLVMRustAddModuleFlag(
                 llmod,
-                behavior,
+                llvm::LLVMModFlagBehavior::Min,
                 c"sign-return-address-with-bkey".as_ptr().cast(),
                 u32::from(pac_opts.key == PAuthKey::B),
             );
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index f33a672aff0..467e02d55e3 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -448,12 +448,14 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     constraint,
                     inputs,
                     self.type_void(),
+                    &[],
                     true,
                     false,
                     llvm::AsmDialect::Att,
                     &[span],
                     false,
                     None,
+                    None,
                 )
                 .unwrap_or_else(|| bug!("failed to generate inline asm call for `black_box`"));
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 3a34ef0874e..58e98037067 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1616,6 +1616,20 @@ extern "C" {
         Name: *const c_char,
     ) -> &'a Value;
 
+    pub fn LLVMRustBuildCallBr<'a>(
+        B: &Builder<'a>,
+        Ty: &'a Type,
+        Fn: &'a Value,
+        DefaultDest: &'a BasicBlock,
+        IndirectDests: *const &'a BasicBlock,
+        NumIndirectDests: c_uint,
+        Args: *const &'a Value,
+        NumArgs: c_uint,
+        OpBundles: *const &OperandBundleDef<'a>,
+        NumOpBundles: c_uint,
+        Name: *const c_char,
+    ) -> &'a Value;
+
     pub fn LLVMRustSetFastMath(Instr: &Value);
     pub fn LLVMRustSetAlgebraicMath(Instr: &Value);
     pub fn LLVMRustSetAllowReassoc(Instr: &Value);
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 2161bf61daa..1a3c70cedd0 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -510,11 +510,13 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         // Params for UEFI
         let param_handle = bx.get_param(0);
         let param_system_table = bx.get_param(1);
+        let ptr_size = bx.tcx().data_layout.pointer_size;
+        let ptr_align = bx.tcx().data_layout.pointer_align.abi;
         let arg_argc = bx.const_int(cx.type_isize(), 2);
-        let arg_argv = bx.alloca(cx.type_array(cx.type_ptr(), 2), Align::ONE);
-        bx.store(param_handle, arg_argv, Align::ONE);
-        let arg_argv_el1 = bx.gep(cx.type_ptr(), arg_argv, &[bx.const_int(cx.type_int(), 1)]);
-        bx.store(param_system_table, arg_argv_el1, Align::ONE);
+        let arg_argv = bx.alloca(cx.type_array(cx.type_ptr(), 2), ptr_align);
+        bx.store(param_handle, arg_argv, ptr_align);
+        let arg_argv_el1 = bx.inbounds_ptradd(arg_argv, bx.const_usize(ptr_size.bytes()));
+        bx.store(param_system_table, arg_argv_el1, ptr_align);
         (arg_argc, arg_argv)
     } else if cx.sess().target.main_needs_argc_argv {
         // Params from native `main()` used as args for rust start function
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index b0efb646ef3..89a44d2897a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -264,7 +264,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
             mir::UnwindAction::Unreachable => None,
         };
 
-        if let Some(cleanup) = unwind_target {
+        if operands.iter().any(|x| matches!(x, InlineAsmOperandRef::Label { .. })) {
+            assert!(unwind_target.is_none());
             let ret_llbb = if let Some(target) = destination {
                 fx.llbb(target)
             } else {
@@ -277,11 +278,29 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
                 options,
                 line_spans,
                 instance,
-                Some((ret_llbb, cleanup, self.funclet(fx))),
+                Some(ret_llbb),
+                None,
+            );
+            MergingSucc::False
+        } else if let Some(cleanup) = unwind_target {
+            let ret_llbb = if let Some(target) = destination {
+                fx.llbb(target)
+            } else {
+                fx.unreachable_block()
+            };
+
+            bx.codegen_inline_asm(
+                template,
+                operands,
+                options,
+                line_spans,
+                instance,
+                Some(ret_llbb),
+                Some((cleanup, self.funclet(fx))),
             );
             MergingSucc::False
         } else {
-            bx.codegen_inline_asm(template, operands, options, line_spans, instance, None);
+            bx.codegen_inline_asm(template, operands, options, line_spans, instance, None, None);
 
             if let Some(target) = destination {
                 self.funclet_br(fx, bx, target, mergeable_succ)
@@ -1100,7 +1119,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         operands: &[mir::InlineAsmOperand<'tcx>],
         options: ast::InlineAsmOptions,
         line_spans: &[Span],
-        destination: Option<mir::BasicBlock>,
+        targets: &[mir::BasicBlock],
         unwind: mir::UnwindAction,
         instance: Instance<'_>,
         mergeable_succ: bool,
@@ -1152,6 +1171,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 mir::InlineAsmOperand::SymStatic { def_id } => {
                     InlineAsmOperandRef::SymStatic { def_id }
                 }
+                mir::InlineAsmOperand::Label { target_index } => {
+                    InlineAsmOperandRef::Label { label: self.llbb(targets[target_index]) }
+                }
             })
             .collect();
 
@@ -1162,7 +1184,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             &operands,
             options,
             line_spans,
-            destination,
+            if options.contains(InlineAsmOptions::NORETURN) {
+                None
+            } else {
+                targets.get(0).copied()
+            },
             unwind,
             instance,
             mergeable_succ,
@@ -1318,7 +1344,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 ref operands,
                 options,
                 line_spans,
-                destination,
+                ref targets,
                 unwind,
             } => self.codegen_asm_terminator(
                 helper,
@@ -1328,7 +1354,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 operands,
                 options,
                 line_spans,
-                destination,
+                targets,
                 unwind,
                 self.instance,
                 mergeable_succ(),
diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs
index 295e2769109..1a4795c0213 100644
--- a/compiler/rustc_codegen_ssa/src/mono_item.rs
+++ b/compiler/rustc_codegen_ssa/src/mono_item.rs
@@ -76,7 +76,8 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
                             hir::InlineAsmOperand::In { .. }
                             | hir::InlineAsmOperand::Out { .. }
                             | hir::InlineAsmOperand::InOut { .. }
-                            | hir::InlineAsmOperand::SplitInOut { .. } => {
+                            | hir::InlineAsmOperand::SplitInOut { .. }
+                            | hir::InlineAsmOperand::Label { .. } => {
                                 span_bug!(*op_sp, "invalid operand type for global_asm!")
                             }
                         })
diff --git a/compiler/rustc_codegen_ssa/src/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs
index c2ae74b18d8..8d67b626bbd 100644
--- a/compiler/rustc_codegen_ssa/src/traits/asm.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs
@@ -33,6 +33,9 @@ pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> {
     SymStatic {
         def_id: DefId,
     },
+    Label {
+        label: B::BasicBlock,
+    },
 }
 
 #[derive(Debug)]
@@ -51,7 +54,8 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes {
         options: InlineAsmOptions,
         line_spans: &[Span],
         instance: Instance<'_>,
-        dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>,
+        dest: Option<Self::BasicBlock>,
+        catch_funclet: Option<(Self::BasicBlock, Option<&Self::Funclet>)>,
     );
 }
 
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 2805ca360ad..81c9e02e2ee 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -232,9 +232,6 @@ const_eval_non_const_fn_call =
 const_eval_non_const_impl =
     impl defined here, but it is not `const`
 
-const_eval_noreturn_asm_returned =
-    returned from noreturn inline assembly
-
 const_eval_not_enough_caller_args =
     calling a function with fewer arguments than it requires
 
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 864241fbd4a..6736fc749c0 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -227,7 +227,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
         if self.tcx.has_attr(def_id, sym::rustc_const_panic_str)
             || Some(def_id) == self.tcx.lang_items().begin_panic_fn()
         {
-            let args = self.copy_fn_args(args)?;
+            let args = self.copy_fn_args(args);
             // &str or &&str
             assert!(args.len() == 1);
 
@@ -254,7 +254,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
 
             return Ok(Some(new_instance));
         } else if Some(def_id) == self.tcx.lang_items().align_offset_fn() {
-            let args = self.copy_fn_args(args)?;
+            let args = self.copy_fn_args(args);
             // For align_offset, we replace the function call if the pointer has no address.
             match self.align_offset(instance, &args, dest, ret)? {
                 ControlFlow::Continue(()) => return Ok(Some(instance)),
diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs
index e951a77611c..6d4f6d0cb3c 100644
--- a/compiler/rustc_const_eval/src/interpret/discriminant.rs
+++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs
@@ -10,6 +10,8 @@ use super::{ImmTy, InterpCx, InterpResult, Machine, Readable, Scalar, Writeable}
 
 impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Writes the discriminant of the given variant.
+    ///
+    /// If the variant is uninhabited, this is UB.
     #[instrument(skip(self), level = "trace")]
     pub fn write_discriminant(
         &mut self,
@@ -102,6 +104,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
     /// Read discriminant, return the runtime value as well as the variant index.
     /// Can also legally be called on non-enums (e.g. through the discriminant_value intrinsic)!
+    ///
+    /// Will never return an uninhabited variant.
     #[instrument(skip(self), level = "trace")]
     pub fn read_discriminant(
         &self,
@@ -244,7 +248,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 variant
             }
         };
-        // For consistency with `write_discriminant`, and to make sure that `project_downcast` cannot fail due to strange layouts, we declare immediate UB for uninhabited variants.
+        // Reading the discriminant of an uninhabited variant is UB. This is the basis for the
+        // `uninhabited_enum_branching` MIR pass. It also ensures consistency with
+        // `write_discriminant`.
         if op.layout().for_variant(self, index).abi.is_uninhabited() {
             throw_ub!(UninhabitedEnumVariantRead(index))
         }
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index ee5de44a651..90a654a1229 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -374,11 +374,17 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
         kind: Option<MemoryKind<Self::MemoryKind>>,
     ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
 
+    /// Evaluate the inline assembly.
+    ///
+    /// This should take care of jumping to the next block (one of `targets`) when asm goto
+    /// is triggered, `targets[0]` when the assembly falls through, or diverge in case of
+    /// `InlineAsmOptions::NORETURN` being set.
     fn eval_inline_asm(
         _ecx: &mut InterpCx<'mir, 'tcx, Self>,
         _template: &'tcx [InlineAsmTemplatePiece],
         _operands: &[mir::InlineAsmOperand<'tcx>],
         _options: InlineAsmOptions,
+        _targets: &[mir::BasicBlock],
     ) -> InterpResult<'tcx> {
         throw_unsup_format!("inline assembly is not supported")
     }
@@ -466,11 +472,11 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
     /// argument/return value was actually copied or passed in-place..
     fn protect_in_place_function_argument(
         ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        place: &PlaceTy<'tcx, Self::Provenance>,
+        mplace: &MPlaceTy<'tcx, Self::Provenance>,
     ) -> InterpResult<'tcx> {
         // Without an aliasing model, all we can do is put `Uninit` into the place.
         // Conveniently this also ensures that the place actually points to suitable memory.
-        ecx.write_uninit(place)
+        ecx.write_uninit(mplace)
     }
 
     /// Called immediately before a new stack frame gets pushed.
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 55f85573f38..bafb8cb0018 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -1,6 +1,7 @@
 use std::borrow::Cow;
 
-use rustc_ast::ast::InlineAsmOptions;
+use either::Either;
+
 use rustc_middle::{
     mir,
     ty::{
@@ -30,14 +31,14 @@ pub enum FnArg<'tcx, Prov: Provenance = CtfeProvenance> {
     Copy(OpTy<'tcx, Prov>),
     /// Allow for the argument to be passed in-place: destroy the value originally stored at that place and
     /// make the place inaccessible for the duration of the function call.
-    InPlace(PlaceTy<'tcx, Prov>),
+    InPlace(MPlaceTy<'tcx, Prov>),
 }
 
 impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> {
     pub fn layout(&self) -> &TyAndLayout<'tcx> {
         match self {
             FnArg::Copy(op) => &op.layout,
-            FnArg::InPlace(place) => &place.layout,
+            FnArg::InPlace(mplace) => &mplace.layout,
         }
     }
 }
@@ -45,13 +46,10 @@ impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> {
 impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Make a copy of the given fn_arg. Any `InPlace` are degenerated to copies, no protection of the
     /// original memory occurs.
-    pub fn copy_fn_arg(
-        &self,
-        arg: &FnArg<'tcx, M::Provenance>,
-    ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
+    pub fn copy_fn_arg(&self, arg: &FnArg<'tcx, M::Provenance>) -> OpTy<'tcx, M::Provenance> {
         match arg {
-            FnArg::Copy(op) => Ok(op.clone()),
-            FnArg::InPlace(place) => self.place_to_op(place),
+            FnArg::Copy(op) => op.clone(),
+            FnArg::InPlace(mplace) => mplace.clone().into(),
         }
     }
 
@@ -60,7 +58,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     pub fn copy_fn_args(
         &self,
         args: &[FnArg<'tcx, M::Provenance>],
-    ) -> InterpResult<'tcx, Vec<OpTy<'tcx, M::Provenance>>> {
+    ) -> Vec<OpTy<'tcx, M::Provenance>> {
         args.iter().map(|fn_arg| self.copy_fn_arg(fn_arg)).collect()
     }
 
@@ -71,7 +69,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ) -> InterpResult<'tcx, FnArg<'tcx, M::Provenance>> {
         Ok(match arg {
             FnArg::Copy(op) => FnArg::Copy(self.project_field(op, field)?),
-            FnArg::InPlace(place) => FnArg::InPlace(self.project_field(place, field)?),
+            FnArg::InPlace(mplace) => FnArg::InPlace(self.project_field(mplace, field)?),
         })
     }
 
@@ -224,15 +222,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 terminator.kind
             ),
 
-            InlineAsm { template, ref operands, options, destination, .. } => {
-                M::eval_inline_asm(self, template, operands, options)?;
-                if options.contains(InlineAsmOptions::NORETURN) {
-                    throw_ub_custom!(fluent::const_eval_noreturn_asm_returned);
-                }
-                self.go_to_block(
-                    destination
-                        .expect("InlineAsm terminators without noreturn must have a destination"),
-                )
+            InlineAsm { template, ref operands, options, ref targets, .. } => {
+                M::eval_inline_asm(self, template, operands, options, targets)?;
             }
         }
 
@@ -246,10 +237,36 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ) -> InterpResult<'tcx, Vec<FnArg<'tcx, M::Provenance>>> {
         ops.iter()
             .map(|op| {
-                Ok(match &op.node {
-                    mir::Operand::Move(place) => FnArg::InPlace(self.eval_place(*place)?),
-                    _ => FnArg::Copy(self.eval_operand(&op.node, None)?),
-                })
+                let arg = match &op.node {
+                    mir::Operand::Copy(_) | mir::Operand::Constant(_) => {
+                        // Make a regular copy.
+                        let op = self.eval_operand(&op.node, None)?;
+                        FnArg::Copy(op)
+                    }
+                    mir::Operand::Move(place) => {
+                        // If this place lives in memory, preserve its location.
+                        // We call `place_to_op` which will be an `MPlaceTy` whenever there exists
+                        // an mplace for this place. (This is in contrast to `PlaceTy::as_mplace_or_local`
+                        // which can return a local even if that has an mplace.)
+                        let place = self.eval_place(*place)?;
+                        let op = self.place_to_op(&place)?;
+
+                        match op.as_mplace_or_imm() {
+                            Either::Left(mplace) => FnArg::InPlace(mplace),
+                            Either::Right(_imm) => {
+                                // This argument doesn't live in memory, so there's no place
+                                // to make inaccessible during the call.
+                                // We rely on there not being any stray `PlaceTy` that would let the
+                                // caller directly access this local!
+                                // This is also crucial for tail calls, where we want the `FnArg` to
+                                // stay valid when the old stack frame gets popped.
+                                FnArg::Copy(op)
+                            }
+                        }
+                    }
+                };
+
+                Ok(arg)
             })
             .collect()
     }
@@ -459,7 +476,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // We work with a copy of the argument for now; if this is in-place argument passing, we
         // will later protect the source it comes from. This means the callee cannot observe if we
         // did in-place of by-copy argument passing, except for pointer equality tests.
-        let caller_arg_copy = self.copy_fn_arg(caller_arg)?;
+        let caller_arg_copy = self.copy_fn_arg(caller_arg);
         if !already_live {
             let local = callee_arg.as_local().unwrap();
             let meta = caller_arg_copy.meta();
@@ -477,8 +494,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // specifically.)
         self.copy_op_allow_transmute(&caller_arg_copy, &callee_arg)?;
         // If this was an in-place pass, protect the place it comes from for the duration of the call.
-        if let FnArg::InPlace(place) = caller_arg {
-            M::protect_in_place_function_argument(self, place)?;
+        if let FnArg::InPlace(mplace) = caller_arg {
+            M::protect_in_place_function_argument(self, mplace)?;
         }
         Ok(())
     }
@@ -525,7 +542,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 M::call_intrinsic(
                     self,
                     instance,
-                    &self.copy_fn_args(args)?,
+                    &self.copy_fn_args(args),
                     destination,
                     target,
                     unwind,
@@ -602,8 +619,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                             .map(|arg| (
                                 arg.layout().ty,
                                 match arg {
-                                    FnArg::Copy(op) => format!("copy({:?})", *op),
-                                    FnArg::InPlace(place) => format!("in-place({:?})", *place),
+                                    FnArg::Copy(op) => format!("copy({op:?})"),
+                                    FnArg::InPlace(mplace) => format!("in-place({mplace:?})"),
                                 }
                             ))
                             .collect::<Vec<_>>()
@@ -725,8 +742,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                             callee_ty: callee_fn_abi.ret.layout.ty
                         });
                     }
+
                     // Protect return place for in-place return value passing.
-                    M::protect_in_place_function_argument(self, &destination.clone().into())?;
+                    M::protect_in_place_function_argument(self, &destination)?;
 
                     // Don't forget to mark "initially live" locals as live.
                     self.storage_live_for_always_live_locals()?;
@@ -749,7 +767,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 // An `InPlace` does nothing here, we keep the original receiver intact. We can't
                 // really pass the argument in-place anyway, and we are constructing a new
                 // `Immediate` receiver.
-                let mut receiver = self.copy_fn_arg(&args[0])?;
+                let mut receiver = self.copy_fn_arg(&args[0]);
                 let receiver_place = loop {
                     match receiver.layout.ty.kind() {
                         ty::Ref(..) | ty::RawPtr(..) => {
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 0b41b4f9682..7ec78e7b9cf 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -581,7 +581,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 if is_int_bool_or_char(lhs_ty) && is_int_bool_or_char(rhs_ty) {
                     // Int, bool, and char operations are fine.
                 } else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() {
-                    assert_eq!(lhs_ty, rhs_ty);
                     assert!(matches!(
                         op,
                         BinOp::Eq
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index cc49e8ea247..74ba2f6039e 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -471,9 +471,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
                 self.check_edge(location, *real_target, EdgeKind::Normal);
                 self.check_unwind_edge(location, *unwind);
             }
-            TerminatorKind::InlineAsm { destination, unwind, .. } => {
-                if let Some(destination) = destination {
-                    self.check_edge(location, *destination, EdgeKind::Normal);
+            TerminatorKind::InlineAsm { targets, unwind, .. } => {
+                for &target in targets {
+                    self.check_edge(location, target, EdgeKind::Normal);
                 }
                 self.check_unwind_edge(location, *unwind);
             }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0657.md b/compiler/rustc_error_codes/src/error_codes/E0657.md
index 7fe48c51147..477d8e8bb6d 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0657.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0657.md
@@ -1,57 +1,26 @@
-A lifetime bound on a trait implementation was captured at an incorrect place.
+An `impl Trait` captured a higher-ranked lifetime, which is not supported.
+
+Currently, `impl Trait` types are only allowed to capture lifetimes from
+their parent items, and not from any `for<'a>` binders in scope.
 
 Erroneous code example:
 
 ```compile_fail,E0657
-trait Id<T> {}
-trait Lt<'a> {}
-
-impl<'a> Lt<'a> for () {}
-impl<T> Id<T> for T {}
-
-fn free_fn_capture_hrtb_in_impl_trait()
-    -> Box<for<'a> Id<impl Lt<'a>>> // error!
-{
-    Box::new(())
-}
+trait BorrowInto<'a> {
+    type Target;
 
-struct Foo;
-impl Foo {
-    fn impl_fn_capture_hrtb_in_impl_trait()
-        -> Box<for<'a> Id<impl Lt<'a>>> // error!
-    {
-        Box::new(())
-    }
+    fn borrow_into(&'a self) -> Self::Target;
 }
-```
 
-Here, you have used the inappropriate lifetime in the `impl Trait`,
-The `impl Trait` can only capture lifetimes bound at the fn or impl
-level.
+impl<'a> BorrowInto<'a> for () {
+    type Target = &'a ();
 
-To fix this we have to define the lifetime at the function or impl
-level and use that lifetime in the `impl Trait`. For example you can
-define the lifetime at the function:
-
-```
-trait Id<T> {}
-trait Lt<'a> {}
-
-impl<'a> Lt<'a> for () {}
-impl<T> Id<T> for T {}
-
-fn free_fn_capture_hrtb_in_impl_trait<'b>()
-    -> Box<for<'a> Id<impl Lt<'b>>> // ok!
-{
-    Box::new(())
+    fn borrow_into(&'a self) -> Self::Target {
+        self
+    }
 }
 
-struct Foo;
-impl Foo {
-    fn impl_fn_capture_hrtb_in_impl_trait<'b>()
-        -> Box<for<'a> Id<impl Lt<'b>>> // ok!
-    {
-        Box::new(())
-    }
+fn opaque() -> impl for<'a> BorrowInto<'a, Target = impl Sized + 'a> {
+    ()
 }
 ```
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 9f4bead21dc..a10f4b934ea 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -345,6 +345,8 @@ declare_features! (
     (unstable, asm_const, "1.58.0", Some(93332)),
     /// Enables experimental inline assembly support for additional architectures.
     (unstable, asm_experimental_arch, "1.58.0", Some(93335)),
+    /// Allows using `label` operands in inline assembly.
+    (unstable, asm_goto, "CURRENT_RUSTC_VERSION", Some(119364)),
     /// Allows the `may_unwind` option in inline assembly.
     (unstable, asm_unwind, "1.58.0", Some(93334)),
     /// Allows users to enforce equality of associated constants `TraitImpl<AssocConst=3>`.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 3dac6880f17..7d5b4c0f06d 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2562,6 +2562,8 @@ pub enum OpaqueTyOrigin {
     AsyncFn(LocalDefId),
     /// type aliases: `type Foo = impl Trait;`
     TyAlias {
+        /// The type alias or associated type parent of the TAIT/ATPIT
+        parent: LocalDefId,
         /// associated types in impl blocks for traits.
         in_assoc_ty: bool,
     },
@@ -2650,6 +2652,9 @@ pub enum InlineAsmOperand<'hir> {
         path: QPath<'hir>,
         def_id: DefId,
     },
+    Label {
+        block: &'hir Block<'hir>,
+    },
 }
 
 impl<'hir> InlineAsmOperand<'hir> {
@@ -2659,7 +2664,10 @@ impl<'hir> InlineAsmOperand<'hir> {
             | Self::Out { reg, .. }
             | Self::InOut { reg, .. }
             | Self::SplitInOut { reg, .. } => Some(reg),
-            Self::Const { .. } | Self::SymFn { .. } | Self::SymStatic { .. } => None,
+            Self::Const { .. }
+            | Self::SymFn { .. }
+            | Self::SymStatic { .. }
+            | Self::Label { .. } => None,
         }
     }
 
@@ -2680,6 +2688,12 @@ pub struct InlineAsm<'hir> {
     pub line_spans: &'hir [Span],
 }
 
+impl InlineAsm<'_> {
+    pub fn contains_label(&self) -> bool {
+        self.operands.iter().any(|x| matches!(x.0, InlineAsmOperand::Label { .. }))
+    }
+}
+
 /// Represents a parameter in a function header.
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct Param<'hir> {
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 88e0238b523..32b4bf38fa9 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -1289,6 +1289,7 @@ pub fn walk_inline_asm<'v, V: Visitor<'v>>(
             InlineAsmOperand::SymStatic { path, .. } => {
                 try_visit!(visitor.visit_qpath(path, id, *op_sp));
             }
+            InlineAsmOperand::Label { block } => try_visit!(visitor.visit_block(block)),
         }
     }
     V::Result::output()
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index e376411cd95..bad472dcb5c 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -312,6 +312,10 @@ hir_analysis_only_current_traits_primitive = only traits defined in the current
 
 hir_analysis_only_current_traits_ty = `{$ty}` is not defined in the current crate
 
+hir_analysis_opaque_captures_higher_ranked_lifetime = `impl Trait` cannot capture {$bad_place}
+    .label = `impl Trait` implicitly captures all lifetimes in scope
+    .note = lifetime declared here
+
 hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a temporary means of controlling which traits can use parenthetical notation
     .help = add `#![feature(unboxed_closures)]` to the crate attributes to use it
 
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 748571c12b3..1b24c2b61fd 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -339,8 +339,9 @@ fn check_opaque_meets_bounds<'tcx>(
     origin: &hir::OpaqueTyOrigin,
 ) -> Result<(), ErrorGuaranteed> {
     let defining_use_anchor = match *origin {
-        hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did,
-        hir::OpaqueTyOrigin::TyAlias { .. } => tcx.impl_trait_parent(def_id),
+        hir::OpaqueTyOrigin::FnReturn(did)
+        | hir::OpaqueTyOrigin::AsyncFn(did)
+        | hir::OpaqueTyOrigin::TyAlias { parent: did, .. } => did,
     };
     let param_env = tcx.param_env(defining_use_anchor);
 
@@ -351,14 +352,14 @@ fn check_opaque_meets_bounds<'tcx>(
     let ocx = ObligationCtxt::new(&infcx);
 
     let args = match *origin {
-        hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
-            GenericArgs::identity_for_item(tcx, parent).extend_to(
-                tcx,
-                def_id.to_def_id(),
-                |param, _| tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()).into(),
-            )
-        }
-        hir::OpaqueTyOrigin::TyAlias { .. } => GenericArgs::identity_for_item(tcx, def_id),
+        hir::OpaqueTyOrigin::FnReturn(parent)
+        | hir::OpaqueTyOrigin::AsyncFn(parent)
+        | hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item(
+            tcx, parent,
+        )
+        .extend_to(tcx, def_id.to_def_id(), |param, _| {
+            tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()).into()
+        }),
     };
 
     let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 435e251b130..ec9e928ce59 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -1,5 +1,6 @@
 use super::potentially_plural_count;
 use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture};
+use core::ops::ControlFlow;
 use hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
@@ -520,14 +521,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
         )
         .fold_with(&mut collector);
 
-    if !unnormalized_trait_sig.output().references_error() {
-        debug_assert_ne!(
-            collector.types.len(),
-            0,
-            "expect >1 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`"
-        );
-    }
-
     let trait_sig = ocx.normalize(&misc_cause, param_env, unnormalized_trait_sig);
     trait_sig.error_reported()?;
     let trait_return_ty = trait_sig.output();
@@ -646,6 +639,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
         }
     }
 
+    if !unnormalized_trait_sig.output().references_error() {
+        debug_assert!(
+            !collector.types.is_empty(),
+            "expect >0 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`"
+        );
+    }
+
     // FIXME: This has the same issue as #108544, but since this isn't breaking
     // existing code, I'm not particularly inclined to do the same hack as above
     // where we process wf obligations manually. This can be fixed in a forward-
@@ -1565,24 +1565,24 @@ fn compare_synthetic_generics<'tcx>(
                     let (sig, _) = impl_m.expect_fn();
                     let input_tys = sig.decl.inputs;
 
-                    struct Visitor(Option<Span>, hir::def_id::LocalDefId);
+                    struct Visitor(hir::def_id::LocalDefId);
                     impl<'v> intravisit::Visitor<'v> for Visitor {
-                        fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
-                            intravisit::walk_ty(self, ty);
+                        type Result = ControlFlow<Span>;
+                        fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) -> Self::Result {
                             if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind
                                 && let Res::Def(DefKind::TyParam, def_id) = path.res
-                                && def_id == self.1.to_def_id()
+                                && def_id == self.0.to_def_id()
                             {
-                                self.0 = Some(ty.span);
+                                ControlFlow::Break(ty.span)
+                            } else {
+                                intravisit::walk_ty(self, ty)
                             }
                         }
                     }
 
-                    let mut visitor = Visitor(None, impl_def_id);
-                    for ty in input_tys {
-                        intravisit::Visitor::visit_ty(&mut visitor, ty);
-                    }
-                    let span = visitor.0?;
+                    let span = input_tys.iter().find_map(|ty| {
+                        intravisit::Visitor::visit_ty(&mut Visitor(impl_def_id), ty).break_value()
+                    })?;
 
                     let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds;
                     let bounds = bounds.first()?.span().to(bounds.last()?.span());
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index d03b02f028d..9de660407d7 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -470,6 +470,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                         }
                     };
                 }
+                // No special checking is needed for labels.
+                hir::InlineAsmOperand::Label { .. } => {}
             }
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index ae7ea271c56..09689b22e90 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1,7 +1,9 @@
 use crate::autoderef::Autoderef;
+use crate::collect::CollectItemTypesVisitor;
 use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
 use crate::errors;
 
+use hir::intravisit::Visitor;
 use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
@@ -225,6 +227,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
         ?item.owner_id,
         item.name = ? tcx.def_path_str(def_id)
     );
+    CollectItemTypesVisitor { tcx }.visit_item(item);
 
     let res = match item.kind {
         // Right now we check that every default trait implementation
@@ -336,9 +339,14 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
     res
 }
 
-fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) -> Result<(), ErrorGuaranteed> {
+fn check_foreign_item<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    item: &'tcx hir::ForeignItem<'tcx>,
+) -> Result<(), ErrorGuaranteed> {
     let def_id = item.owner_id.def_id;
 
+    CollectItemTypesVisitor { tcx }.visit_foreign_item(item);
+
     debug!(
         ?item.owner_id,
         item.name = ? tcx.def_path_str(def_id)
@@ -355,12 +363,14 @@ fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) -> Result<()
     }
 }
 
-fn check_trait_item(
-    tcx: TyCtxt<'_>,
-    trait_item: &hir::TraitItem<'_>,
+fn check_trait_item<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    trait_item: &'tcx hir::TraitItem<'tcx>,
 ) -> Result<(), ErrorGuaranteed> {
     let def_id = trait_item.owner_id.def_id;
 
+    CollectItemTypesVisitor { tcx }.visit_trait_item(trait_item);
+
     let (method_sig, span) = match trait_item.kind {
         hir::TraitItemKind::Fn(ref sig, _) => (Some(sig), trait_item.span),
         hir::TraitItemKind::Type(_bounds, Some(ty)) => (None, ty.span),
@@ -895,7 +905,12 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem
     }
 }
 
-fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) -> Result<(), ErrorGuaranteed> {
+fn check_impl_item<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    impl_item: &'tcx hir::ImplItem<'tcx>,
+) -> Result<(), ErrorGuaranteed> {
+    CollectItemTypesVisitor { tcx }.visit_impl_item(impl_item);
+
     let (method_sig, span) = match impl_item.kind {
         hir::ImplItemKind::Fn(ref sig, _) => (Some(sig), impl_item.span),
         // Constrain binding and overflow error spans to `<Ty>` in `type foo = <Ty>`.
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index e1704ffc8bf..10922d53479 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -20,7 +20,7 @@ use rustc_data_structures::unord::UnordMap;
 use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
+use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{GenericParamKind, Node};
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
@@ -52,11 +52,6 @@ mod resolve_bound_vars;
 mod type_of;
 
 ///////////////////////////////////////////////////////////////////////////
-// Main entry point
-
-fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
-    tcx.hir().visit_item_likes_in_module(module_def_id, &mut CollectItemTypesVisitor { tcx });
-}
 
 pub fn provide(providers: &mut Providers) {
     resolve_bound_vars::provide(providers);
@@ -82,7 +77,6 @@ pub fn provide(providers: &mut Providers) {
         impl_trait_header,
         coroutine_kind,
         coroutine_for_closure,
-        collect_mod_item_types,
         is_type_alias_impl_trait,
         find_field,
         ..*providers
@@ -155,8 +149,8 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector {
     }
 }
 
-struct CollectItemTypesVisitor<'tcx> {
-    tcx: TyCtxt<'tcx>,
+pub struct CollectItemTypesVisitor<'tcx> {
+    pub tcx: TyCtxt<'tcx>,
 }
 
 /// If there are any placeholder types (`_`), emit an error explaining that this is not allowed
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index f70bb8c4289..2675eacc06e 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -339,7 +339,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
     predicates: &mut Vec<(ty::Clause<'tcx>, Span)>,
 ) {
     for param in opaque_own_params {
-        let orig_lifetime = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local());
+        let orig_lifetime = tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
         if let ty::ReEarlyParam(..) = *orig_lifetime {
             let dup_lifetime = ty::Region::new_early_param(
                 tcx,
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index ad8ec1036ef..7936621c868 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -6,9 +6,9 @@
 //! the types in HIR to identify late-bound lifetimes and assign their Debruijn indices. This file
 //! is also responsible for assigning their semantics to implicit lifetimes in trait objects.
 
+use core::ops::ControlFlow;
 use rustc_ast::visit::walk_list;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
-use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::LocalDefId;
@@ -417,23 +417,18 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
         {
             if let &hir::ClosureBinder::For { span: for_sp, .. } = binder {
                 fn span_of_infer(ty: &hir::Ty<'_>) -> Option<Span> {
-                    struct V(Option<Span>);
-
+                    struct V;
                     impl<'v> Visitor<'v> for V {
-                        fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
-                            match t.kind {
-                                _ if self.0.is_some() => (),
-                                hir::TyKind::Infer => {
-                                    self.0 = Some(t.span);
-                                }
-                                _ => intravisit::walk_ty(self, t),
+                        type Result = ControlFlow<Span>;
+                        fn visit_ty(&mut self, t: &'v hir::Ty<'v>) -> Self::Result {
+                            if matches!(t.kind, hir::TyKind::Infer) {
+                                ControlFlow::Break(t.span)
+                            } else {
+                                intravisit::walk_ty(self, t)
                             }
                         }
                     }
-
-                    let mut v = V(None);
-                    v.visit_ty(ty);
-                    v.0
+                    V.visit_ty(ty).break_value()
                 }
 
                 let infer_in_rt_sp = match fn_decl.output {
@@ -514,38 +509,11 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 // These sorts of items have no lifetime parameters at all.
                 intravisit::walk_item(self, item);
             }
-            hir::ItemKind::OpaqueTy(hir::OpaqueTy {
-                origin: hir::OpaqueTyOrigin::TyAlias { .. },
-                ..
-            }) => {
-                // Opaque types are visited when we visit the
-                // `TyKind::OpaqueDef`, so that they have the lifetimes from
-                // their parent opaque_ty in scope.
-                //
-                // The core idea here is that since OpaqueTys are generated with the impl Trait as
-                // their owner, we can keep going until we find the Item that owns that. We then
-                // conservatively add all resolved lifetimes. Otherwise we run into problems in
-                // cases like `type Foo<'a> = impl Bar<As = impl Baz + 'a>`.
-                let parent_item = self.tcx.hir().get_parent_item(item.hir_id());
-                let resolved_lifetimes: &ResolveBoundVars =
-                    self.tcx.resolve_bound_vars(parent_item);
-                // We need to add *all* deps, since opaque tys may want them from *us*
-                for (&owner, defs) in resolved_lifetimes.defs.iter() {
-                    defs.iter().for_each(|(&local_id, region)| {
-                        self.map.defs.insert(hir::HirId { owner, local_id }, *region);
-                    });
-                }
-                for (&owner, late_bound_vars) in resolved_lifetimes.late_bound_vars.iter() {
-                    late_bound_vars.iter().for_each(|(&local_id, late_bound_vars)| {
-                        self.record_late_bound_vars(
-                            hir::HirId { owner, local_id },
-                            late_bound_vars.clone(),
-                        );
-                    });
-                }
-            }
             hir::ItemKind::OpaqueTy(&hir::OpaqueTy {
-                origin: hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent),
+                origin:
+                    hir::OpaqueTyOrigin::FnReturn(parent)
+                    | hir::OpaqueTyOrigin::AsyncFn(parent)
+                    | hir::OpaqueTyOrigin::TyAlias { parent, .. },
                 generics,
                 ..
             }) => {
@@ -683,26 +651,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 //                                      the opaque_ty generics
                 let opaque_ty = self.tcx.hir().item(item_id);
                 match &opaque_ty.kind {
-                    hir::ItemKind::OpaqueTy(hir::OpaqueTy {
-                        origin: hir::OpaqueTyOrigin::TyAlias { .. },
-                        ..
-                    }) => {
-                        intravisit::walk_ty(self, ty);
-
-                        // Elided lifetimes and late-bound lifetimes (from the parent)
-                        // are not allowed in non-return position impl Trait
-                        let scope = Scope::LateBoundary {
-                            s: &Scope::TraitRefBoundary { s: self.scope },
-                            what: "type alias impl trait",
-                        };
-                        self.with(scope, |this| intravisit::walk_item(this, opaque_ty));
-
-                        return;
-                    }
-                    hir::ItemKind::OpaqueTy(hir::OpaqueTy {
-                        origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..),
-                        ..
-                    }) => {}
+                    hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin: _, .. }) => {}
                     i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
                 };
 
@@ -719,34 +668,47 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                     // and ban them. Type variables instantiated inside binders aren't
                     // well-supported at the moment, so this doesn't work.
                     // In the future, this should be fixed and this error should be removed.
-                    let def = self.map.defs.get(&lifetime.hir_id).cloned();
-                    let Some(ResolvedArg::LateBound(_, _, def_id)) = def else { continue };
-                    let Some(def_id) = def_id.as_local() else { continue };
-                    let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
-                    // Ensure that the parent of the def is an item, not HRTB
-                    let parent_id = self.tcx.parent_hir_id(hir_id);
-                    if !parent_id.is_owner() {
-                        struct_span_code_err!(
-                            self.tcx.dcx(),
-                            lifetime.ident.span,
-                            E0657,
-                            "`impl Trait` can only capture lifetimes bound at the fn or impl level"
-                        )
-                        .emit();
-                        self.uninsert_lifetime_on_error(lifetime, def.unwrap());
-                    }
-                    if let hir::Node::Item(hir::Item {
-                        kind: hir::ItemKind::OpaqueTy { .. }, ..
-                    }) = self.tcx.hir_node(parent_id)
+                    let def = self.map.defs.get(&lifetime.hir_id).copied();
+                    let Some(ResolvedArg::LateBound(_, _, lifetime_def_id)) = def else { continue };
+                    let Some(lifetime_def_id) = lifetime_def_id.as_local() else { continue };
+                    let lifetime_hir_id = self.tcx.local_def_id_to_hir_id(lifetime_def_id);
+
+                    let bad_place = match self.tcx.hir_node(self.tcx.parent_hir_id(lifetime_hir_id))
                     {
-                        self.tcx.dcx().struct_span_err(
-                            lifetime.ident.span,
-                            "higher kinded lifetime bounds on nested opaque types are not supported yet",
-                        )
-                        .with_span_note(self.tcx.def_span(def_id), "lifetime declared here")
-                        .emit();
-                        self.uninsert_lifetime_on_error(lifetime, def.unwrap());
-                    }
+                        // Opaques do not declare their own lifetimes, so if a lifetime comes from an opaque
+                        // it must be a reified late-bound lifetime from a trait goal.
+                        hir::Node::Item(hir::Item {
+                            kind: hir::ItemKind::OpaqueTy { .. }, ..
+                        }) => "higher-ranked lifetime from outer `impl Trait`",
+                        // Other items are fine.
+                        hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => {
+                            continue;
+                        }
+                        hir::Node::Ty(hir::Ty { kind: hir::TyKind::BareFn(_), .. }) => {
+                            "higher-ranked lifetime from function pointer"
+                        }
+                        hir::Node::Ty(hir::Ty { kind: hir::TyKind::TraitObject(..), .. }) => {
+                            "higher-ranked lifetime from `dyn` type"
+                        }
+                        _ => "higher-ranked lifetime",
+                    };
+
+                    let (span, label) = if lifetime.ident.span == self.tcx.def_span(lifetime_def_id)
+                    {
+                        let opaque_span = self.tcx.def_span(item_id.owner_id);
+                        (opaque_span, Some(opaque_span))
+                    } else {
+                        (lifetime.ident.span, None)
+                    };
+
+                    // Ensure that the parent of the def is an item, not HRTB
+                    self.tcx.dcx().emit_err(errors::OpaqueCapturesHigherRankedLifetime {
+                        span,
+                        label,
+                        decl_span: self.tcx.def_span(lifetime_def_id),
+                        bad_place,
+                    });
+                    self.uninsert_lifetime_on_error(lifetime, def.unwrap());
                 }
             }
             _ => intravisit::walk_ty(self, ty),
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 2217e5280a7..a1345c2d81b 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -1,3 +1,4 @@
+use core::ops::ControlFlow;
 use rustc_errors::{Applicability, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -553,11 +554,11 @@ pub(super) fn type_of_opaque(
         Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id) {
             Node::Item(item) => match item.kind {
                 ItemKind::OpaqueTy(OpaqueTy {
-                    origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false },
+                    origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. },
                     ..
                 }) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id),
                 ItemKind::OpaqueTy(OpaqueTy {
-                    origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true },
+                    origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. },
                     ..
                 }) => opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id),
                 // Opaque types desugared from `impl Trait`.
@@ -675,19 +676,16 @@ pub fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
     if tcx.features().lazy_type_alias {
         return true;
     }
-    struct HasTait {
-        has_type_alias_impl_trait: bool,
-    }
+    struct HasTait;
     impl<'tcx> Visitor<'tcx> for HasTait {
-        fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
+        type Result = ControlFlow<()>;
+        fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) -> Self::Result {
             if let hir::TyKind::OpaqueDef(..) = t.kind {
-                self.has_type_alias_impl_trait = true;
+                ControlFlow::Break(())
             } else {
-                hir::intravisit::walk_ty(self, t);
+                hir::intravisit::walk_ty(self, t)
             }
         }
     }
-    let mut has_tait = HasTait { has_type_alias_impl_trait: false };
-    has_tait.visit_ty(tcx.hir().expect_item(def_id).expect_ty_alias().0);
-    has_tait.has_type_alias_impl_trait
+    HasTait.visit_ty(tcx.hir().expect_item(def_id).expect_ty_alias().0).is_break()
 }
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 5330260fbf5..26349cd1c65 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1607,3 +1607,15 @@ pub struct UnnamedFieldsReprFieldDefined {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_opaque_captures_higher_ranked_lifetime, code = E0657)]
+pub struct OpaqueCapturesHigherRankedLifetime {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub label: Option<Span>,
+    #[note]
+    pub decl_span: Span,
+    pub bad_place: &'static str,
+}
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 77c4ff382b9..e056c0e84cf 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -159,12 +159,6 @@ pub fn provide(providers: &mut Providers) {
 pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
     let _prof_timer = tcx.sess.timer("type_check_crate");
 
-    // this ensures that later parts of type checking can assume that items
-    // have valid types and not error
-    tcx.sess.time("type_collecting", || {
-        tcx.hir().for_each_module(|module| tcx.ensure().collect_mod_item_types(module))
-    });
-
     if tcx.features().rustc_attrs {
         tcx.sess.time("outlives_testing", || outlives::test::test_inferred_outlives(tcx))?;
     }
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 9618c6d8011..42885b0c832 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -125,15 +125,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
 
     // By default, RPIT are invariant wrt type and const generics, but they are bivariant wrt
     // lifetime generics.
-    let variances = std::iter::repeat(ty::Invariant).take(generics.count());
-
-    let mut variances: Vec<_> = match tcx.opaque_type_origin(item_def_id) {
-        rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {
-            variances.collect()
-        }
-        // But TAIT are invariant for all generics
-        rustc_hir::OpaqueTyOrigin::TyAlias { .. } => return tcx.arena.alloc_from_iter(variances),
-    };
+    let mut variances = vec![ty::Invariant; generics.count()];
 
     // Mark all lifetimes from parent generics as unused (Bivariant).
     // This will be overridden later if required.
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 8f8f747339b..b5bb063c5ed 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1265,6 +1265,10 @@ impl<'a> State<'a> {
                     s.space();
                     s.print_qpath(path, true);
                 }
+                hir::InlineAsmOperand::Label { block } => {
+                    s.head("label");
+                    s.print_block(block);
+                }
             },
             AsmArg::Options(opts) => {
                 s.word("options");
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index fcb490bcfec..ceaae9cf49f 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -3232,6 +3232,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>) -> Ty<'tcx> {
+        let mut diverge = asm.options.contains(ast::InlineAsmOptions::NORETURN);
+
         for (op, _op_sp) in asm.operands {
             match op {
                 hir::InlineAsmOperand::In { expr, .. } => {
@@ -3253,13 +3255,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // be well-formed.
                 hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::SymFn { .. } => {}
                 hir::InlineAsmOperand::SymStatic { .. } => {}
+                hir::InlineAsmOperand::Label { block } => {
+                    let previous_diverges = self.diverges.get();
+
+                    // The label blocks should have unit return value or diverge.
+                    let ty =
+                        self.check_block_with_expected(block, ExpectHasType(self.tcx.types.unit));
+                    if !ty.is_never() {
+                        self.demand_suptype(block.span, self.tcx.types.unit, ty);
+                        diverge = false;
+                    }
+
+                    // We need this to avoid false unreachable warning when a label diverges.
+                    self.diverges.set(previous_diverges);
+                }
             }
         }
-        if asm.options.contains(ast::InlineAsmOptions::NORETURN) {
-            self.tcx.types.never
-        } else {
-            Ty::new_unit(self.tcx)
-        }
+
+        if diverge { self.tcx.types.never } else { self.tcx.types.unit }
     }
 
     fn check_offset_of(
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index 04fb7bcf4f3..ba0383d19b9 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -293,6 +293,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                         | hir::InlineAsmOperand::Const { .. }
                         | hir::InlineAsmOperand::SymFn { .. }
                         | hir::InlineAsmOperand::SymStatic { .. } => {}
+                        hir::InlineAsmOperand::Label { block } => {
+                            self.walk_block(block);
+                        }
                     }
                 }
             }
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 70ddd6b2f4c..d86b4912c89 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -61,7 +61,7 @@ use rustc_hir::{HirIdMap, Node};
 use rustc_hir_analysis::astconv::AstConv;
 use rustc_hir_analysis::check::check_abi;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use rustc_infer::traits::ObligationInspector;
+use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc};
 use rustc_middle::query::Providers;
 use rustc_middle::traits;
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -253,6 +253,10 @@ fn typeck_with_fallback<'tcx>(
         let expected_type = expected_type.unwrap_or_else(fallback);
 
         let expected_type = fcx.normalize(body.value.span, expected_type);
+
+        let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id)));
+        fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code);
+
         fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
 
         // Gather locals in statics (because of block expressions).
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 7012f40e349..4c413e4d1c6 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -6,6 +6,7 @@
 use crate::errors::{self, CandidateTraitNote, NoAssociatedItem};
 use crate::Expectation;
 use crate::FnCtxt;
+use core::ops::ControlFlow;
 use rustc_ast::ast::Mutability;
 use rustc_attr::parse_confusables;
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
@@ -2212,30 +2213,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let map = self.infcx.tcx.hir();
                 let body_id = self.tcx.hir().body_owned_by(self.body_id);
                 let body = map.body(body_id);
-                struct LetVisitor<'a> {
-                    result: Option<&'a hir::Expr<'a>>,
+                struct LetVisitor {
                     ident_name: Symbol,
                 }
 
                 // FIXME: This really should be taking scoping, etc into account.
-                impl<'v> Visitor<'v> for LetVisitor<'v> {
-                    fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) {
-                        if let hir::StmtKind::Local(hir::Local { pat, init, .. }) = &ex.kind
+                impl<'v> Visitor<'v> for LetVisitor {
+                    type Result = ControlFlow<Option<&'v hir::Expr<'v>>>;
+                    fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) -> Self::Result {
+                        if let hir::StmtKind::Local(&hir::Local { pat, init, .. }) = ex.kind
                             && let Binding(_, _, ident, ..) = pat.kind
                             && ident.name == self.ident_name
                         {
-                            self.result = *init;
+                            ControlFlow::Break(init)
                         } else {
-                            hir::intravisit::walk_stmt(self, ex);
+                            hir::intravisit::walk_stmt(self, ex)
                         }
                     }
                 }
 
-                let mut visitor = LetVisitor { result: None, ident_name: seg1.ident.name };
-                visitor.visit_body(body);
-
                 if let Node::Expr(call_expr) = self.tcx.parent_hir_node(seg1.hir_id)
-                    && let Some(expr) = visitor.result
+                    && let ControlFlow::Break(Some(expr)) =
+                        (LetVisitor { ident_name: seg1.ident.name }).visit_body(body)
                     && let Some(self_ty) = self.node_ty_opt(expr.hir_id)
                 {
                     let probe = self.lookup_probe_for_diagnostic(
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 362ca3b4833..ea5c6b8c057 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -79,7 +79,7 @@ use rustc_middle::ty::{
 use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span};
 use rustc_target::spec::abi;
 use std::borrow::Cow;
-use std::ops::Deref;
+use std::ops::{ControlFlow, Deref};
 use std::path::PathBuf;
 use std::{cmp, fmt, iter};
 
@@ -2129,15 +2129,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         let tykind = match self.tcx.opt_hir_node_by_def_id(trace.cause.body_id) {
             Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) => {
                 let body = hir.body(*body_id);
-                struct LetVisitor<'v> {
+                struct LetVisitor {
                     span: Span,
-                    result: Option<&'v hir::Ty<'v>>,
                 }
-                impl<'v> Visitor<'v> for LetVisitor<'v> {
-                    fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) {
-                        if self.result.is_some() {
-                            return;
-                        }
+                impl<'v> Visitor<'v> for LetVisitor {
+                    type Result = ControlFlow<&'v hir::TyKind<'v>>;
+                    fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) -> Self::Result {
                         // Find a local statement where the initializer has
                         // the same span as the error and the type is specified.
                         if let hir::Stmt {
@@ -2151,13 +2148,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         } = s
                             && init_span == &self.span
                         {
-                            self.result = Some(*array_ty);
+                            ControlFlow::Break(&array_ty.peel_refs().kind)
+                        } else {
+                            ControlFlow::Continue(())
                         }
                     }
                 }
-                let mut visitor = LetVisitor { span, result: None };
-                visitor.visit_body(body);
-                visitor.result.map(|r| &r.peel_refs().kind)
+                LetVisitor { span }.visit_body(body).break_value()
             }
             Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. })) => {
                 Some(&ty.peel_refs().kind)
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
index 4f74365d06c..265a315a559 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs
@@ -1,3 +1,4 @@
+use core::ops::ControlFlow;
 use rustc_hir as hir;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_middle::hir::map::Map;
@@ -43,14 +44,9 @@ fn find_component_for_bound_region<'tcx>(
     arg: &'tcx hir::Ty<'tcx>,
     br: &ty::BoundRegionKind,
 ) -> Option<&'tcx hir::Ty<'tcx>> {
-    let mut nested_visitor = FindNestedTypeVisitor {
-        tcx,
-        bound_region: *br,
-        found_type: None,
-        current_index: ty::INNERMOST,
-    };
-    nested_visitor.visit_ty(arg);
-    nested_visitor.found_type
+    FindNestedTypeVisitor { tcx, bound_region: *br, current_index: ty::INNERMOST }
+        .visit_ty(arg)
+        .break_value()
 }
 
 // The FindNestedTypeVisitor captures the corresponding `hir::Ty` of the
@@ -65,26 +61,24 @@ struct FindNestedTypeVisitor<'tcx> {
     // The bound_region corresponding to the Refree(freeregion)
     // associated with the anonymous region we are looking for.
     bound_region: ty::BoundRegionKind,
-    // The type where the anonymous lifetime appears
-    // for e.g., Vec<`&u8`> and <`&u8`>
-    found_type: Option<&'tcx hir::Ty<'tcx>>,
     current_index: ty::DebruijnIndex,
 }
 
 impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
+    type Result = ControlFlow<&'tcx hir::Ty<'tcx>>;
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn nested_visit_map(&mut self) -> Self::Map {
         self.tcx.hir()
     }
 
-    fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
+    fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) -> Self::Result {
         match arg.kind {
             hir::TyKind::BareFn(_) => {
                 self.current_index.shift_in(1);
                 intravisit::walk_ty(self, arg);
                 self.current_index.shift_out(1);
-                return;
+                return ControlFlow::Continue(());
             }
 
             hir::TyKind::TraitObject(bounds, ..) => {
@@ -105,8 +99,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
                     (Some(rbv::ResolvedArg::EarlyBound(id)), ty::BrNamed(def_id, _)) => {
                         debug!("EarlyBound id={:?} def_id={:?}", id, def_id);
                         if id == def_id {
-                            self.found_type = Some(arg);
-                            return; // we can stop visiting now
+                            return ControlFlow::Break(arg);
                         }
                     }
 
@@ -123,8 +116,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
                         );
                         debug!("LateBound id={:?} def_id={:?}", id, def_id);
                         if debruijn_index == self.current_index && id == def_id {
-                            self.found_type = Some(arg);
-                            return; // we can stop visiting now
+                            return ControlFlow::Break(arg);
                         }
                     }
 
@@ -145,23 +137,30 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
             }
             // Checks if it is of type `hir::TyKind::Path` which corresponds to a struct.
             hir::TyKind::Path(_) => {
-                let subvisitor = &mut TyPathVisitor {
-                    tcx: self.tcx,
-                    found_it: false,
-                    bound_region: self.bound_region,
-                    current_index: self.current_index,
+                // Prefer using the lifetime in type arguments rather than lifetime arguments.
+                intravisit::walk_ty(self, arg)?;
+
+                // Call `walk_ty` as `visit_ty` is empty.
+                return if intravisit::walk_ty(
+                    &mut TyPathVisitor {
+                        tcx: self.tcx,
+                        bound_region: self.bound_region,
+                        current_index: self.current_index,
+                    },
+                    arg,
+                )
+                .is_break()
+                {
+                    ControlFlow::Break(arg)
+                } else {
+                    ControlFlow::Continue(())
                 };
-                intravisit::walk_ty(subvisitor, arg); // call walk_ty; as visit_ty is empty,
-                // this will visit only outermost type
-                if subvisitor.found_it {
-                    self.found_type = Some(arg);
-                }
             }
             _ => {}
         }
         // walk the embedded contents: e.g., if we are visiting `Vec<&Foo>`,
         // go on to visit `&Foo`
-        intravisit::walk_ty(self, arg);
+        intravisit::walk_ty(self, arg)
     }
 }
 
@@ -173,26 +172,25 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
 // specific part of the type in the error message.
 struct TyPathVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
-    found_it: bool,
     bound_region: ty::BoundRegionKind,
     current_index: ty::DebruijnIndex,
 }
 
 impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
+    type Result = ControlFlow<()>;
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn nested_visit_map(&mut self) -> Map<'tcx> {
         self.tcx.hir()
     }
 
-    fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) {
+    fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) -> Self::Result {
         match (self.tcx.named_bound_var(lifetime.hir_id), self.bound_region) {
             // the lifetime of the TyPath!
             (Some(rbv::ResolvedArg::EarlyBound(id)), ty::BrNamed(def_id, _)) => {
                 debug!("EarlyBound id={:?} def_id={:?}", id, def_id);
                 if id == def_id {
-                    self.found_it = true;
-                    return; // we can stop visiting now
+                    return ControlFlow::Break(());
                 }
             }
 
@@ -201,8 +199,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
                 debug!("id={:?}", id);
                 debug!("def_id={:?}", def_id);
                 if debruijn_index == self.current_index && id == def_id {
-                    self.found_it = true;
-                    return; // we can stop visiting now
+                    return ControlFlow::Break(());
                 }
             }
 
@@ -220,9 +217,10 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
                 debug!("no arg found");
             }
         }
+        ControlFlow::Continue(())
     }
 
-    fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
+    fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) -> Self::Result {
         // ignore nested types
         //
         // If you have a type like `Foo<'a, &Ty>` we
@@ -231,5 +229,6 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
         // Making `visit_ty` empty will ignore the `&Ty` embedded
         // inside, it will get reached by the outer visitor.
         debug!("`Ty` corresponding to a struct is {:?}", arg);
+        ControlFlow::Continue(())
     }
 }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index 472dab639d5..8cdf39b1739 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -1,4 +1,5 @@
 use crate::infer::error_reporting::hir::Path;
+use core::ops::ControlFlow;
 use hir::def::CtorKind;
 use hir::intravisit::{walk_expr, walk_stmt, Visitor};
 use hir::{Local, QPath};
@@ -563,62 +564,55 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         cause: &ObligationCause<'_>,
         span: Span,
     ) -> Option<TypeErrorAdditionalDiags> {
-        let hir = self.tcx.hir();
-        if let Some(body_id) = self.tcx.hir().maybe_body_owned_by(cause.body_id) {
-            let body = hir.body(body_id);
-
-            /// Find the if expression with given span
-            struct IfVisitor {
-                pub result: bool,
-                pub found_if: bool,
-                pub err_span: Span,
-            }
-
-            impl<'v> Visitor<'v> for IfVisitor {
-                fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
-                    if self.result {
-                        return;
-                    }
-                    match ex.kind {
-                        hir::ExprKind::If(cond, _, _) => {
-                            self.found_if = true;
-                            walk_expr(self, cond);
-                            self.found_if = false;
-                        }
-                        _ => walk_expr(self, ex),
-                    }
-                }
+        /// Find the if expression with given span
+        struct IfVisitor {
+            pub found_if: bool,
+            pub err_span: Span,
+        }
 
-                fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) {
-                    if let hir::StmtKind::Local(hir::Local {
-                        span,
-                        pat: hir::Pat { .. },
-                        ty: None,
-                        init: Some(_),
-                        ..
-                    }) = &ex.kind
-                        && self.found_if
-                        && span.eq(&self.err_span)
-                    {
-                        self.result = true;
+        impl<'v> Visitor<'v> for IfVisitor {
+            type Result = ControlFlow<()>;
+            fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) -> Self::Result {
+                match ex.kind {
+                    hir::ExprKind::If(cond, _, _) => {
+                        self.found_if = true;
+                        walk_expr(self, cond)?;
+                        self.found_if = false;
+                        ControlFlow::Continue(())
                     }
-                    walk_stmt(self, ex);
+                    _ => walk_expr(self, ex),
                 }
+            }
 
-                fn visit_body(&mut self, body: &'v hir::Body<'v>) {
-                    hir::intravisit::walk_body(self, body);
+            fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) -> Self::Result {
+                if let hir::StmtKind::Local(hir::Local {
+                    span,
+                    pat: hir::Pat { .. },
+                    ty: None,
+                    init: Some(_),
+                    ..
+                }) = &ex.kind
+                    && self.found_if
+                    && span.eq(&self.err_span)
+                {
+                    ControlFlow::Break(())
+                } else {
+                    walk_stmt(self, ex)
                 }
             }
 
-            let mut visitor = IfVisitor { err_span: span, found_if: false, result: false };
-            visitor.visit_body(body);
-            if visitor.result {
-                return Some(TypeErrorAdditionalDiags::AddLetForLetChains {
-                    span: span.shrink_to_lo(),
-                });
+            fn visit_body(&mut self, body: &'v hir::Body<'v>) -> Self::Result {
+                hir::intravisit::walk_body(self, body)
             }
         }
-        None
+
+        self.tcx.hir().maybe_body_owned_by(cause.body_id).and_then(|body_id| {
+            let body = self.tcx.hir().body(body_id);
+            IfVisitor { err_span: span, found_if: false }
+                .visit_body(body)
+                .is_break()
+                .then(|| TypeErrorAdditionalDiags::AddLetForLetChains { span: span.shrink_to_lo() })
+        })
     }
 
     /// For "one type is more general than the other" errors on closures, suggest changing the lifetime
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index b6f3c38cb3f..3d6829ba657 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -391,7 +391,7 @@ impl<'tcx> InferCtxt<'tcx> {
             // Anonymous `impl Trait`
             hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
             // Named `type Foo = impl Bar;`
-            hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
+            hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
                 if in_assoc_ty {
                     self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id)
                 } else {
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 97f9a4b291d..029bddda1e1 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -20,6 +20,7 @@
 #![allow(rustc::untranslatable_diagnostic)]
 #![feature(associated_type_bounds)]
 #![feature(box_patterns)]
+#![feature(control_flow_enum)]
 #![feature(extend_one)]
 #![feature(let_chains)]
 #![feature(if_let_guard)]
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 3a8c8e79b4f..e8fcf4132ea 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -379,13 +379,15 @@ impl LateLintPass<'_> for Diagnostics {
                     _ => return, // occurs for fns passed as args
                 }
             }
-            ExprKind::MethodCall(segment, _recv, args, _span) => {
-                let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
-                let fn_gen_args = cx.typeck_results().node_args(expr.hir_id);
+            ExprKind::MethodCall(_segment, _recv, args, _span) => {
+                let Some((span, def_id, fn_gen_args)) = typeck_results_of_method_fn(cx, expr)
+                else {
+                    return;
+                };
                 let mut call_tys: Vec<_> =
                     args.iter().map(|arg| cx.typeck_results().expr_ty(arg)).collect();
                 call_tys.insert(0, cx.tcx.types.self_param); // dummy inserted for `self`
-                (segment.ident.span, def_id, fn_gen_args, call_tys)
+                (span, def_id, fn_gen_args, call_tys)
             }
             _ => return,
         };
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 3481c66da70..f84d1c6c2d0 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -20,6 +20,7 @@ use rustc_span::symbol::Symbol;
 use rustc_span::symbol::{kw, sym};
 use rustc_span::{BytePos, Span};
 use std::iter;
+use std::ops::ControlFlow;
 
 declare_lint! {
     /// The `unused_must_use` lint detects unused result of a type flagged as
@@ -753,21 +754,18 @@ trait UnusedDelimLint {
         // fn f(){(print!(á
         // ```
         use rustc_ast::visit::{walk_expr, Visitor};
-        struct ErrExprVisitor {
-            has_error: bool,
-        }
+        struct ErrExprVisitor;
         impl<'ast> Visitor<'ast> for ErrExprVisitor {
-            fn visit_expr(&mut self, expr: &'ast ast::Expr) {
+            type Result = ControlFlow<()>;
+            fn visit_expr(&mut self, expr: &'ast ast::Expr) -> ControlFlow<()> {
                 if let ExprKind::Err(_) = expr.kind {
-                    self.has_error = true;
-                    return;
+                    ControlFlow::Break(())
+                } else {
+                    walk_expr(self, expr)
                 }
-                walk_expr(self, expr)
             }
         }
-        let mut visitor = ErrExprVisitor { has_error: false };
-        visitor.visit_expr(value);
-        if visitor.has_error {
+        if ErrExprVisitor.visit_expr(value).is_break() {
             return;
         }
         let spans = match value.kind {
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 1cdfc22431e..f6253068eaa 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -451,14 +451,30 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
       Options.ObjectFilenameForDebug = OutputObjFile;
   }
   if (!strcmp("zlib", DebugInfoCompression) && llvm::compression::zlib::isAvailable()) {
+#if LLVM_VERSION_GE(19, 0)
+    Options.MCOptions.CompressDebugSections = DebugCompressionType::Zlib;
+#else
     Options.CompressDebugSections = DebugCompressionType::Zlib;
+#endif
   } else if (!strcmp("zstd", DebugInfoCompression) && llvm::compression::zstd::isAvailable()) {
+#if LLVM_VERSION_GE(19, 0)
+    Options.MCOptions.CompressDebugSections = DebugCompressionType::Zstd;
+#else
     Options.CompressDebugSections = DebugCompressionType::Zstd;
+#endif
   } else if (!strcmp("none", DebugInfoCompression)) {
+#if LLVM_VERSION_GE(19, 0)
+    Options.MCOptions.CompressDebugSections = DebugCompressionType::None;
+#else
     Options.CompressDebugSections = DebugCompressionType::None;
+#endif
   }
 
+#if LLVM_VERSION_GE(19, 0)
+  Options.MCOptions.X86RelaxRelocations = RelaxELFRelocations;
+#else
   Options.RelaxELFRelocations = RelaxELFRelocations;
+#endif
   Options.UseInitArray = UseInitArray;
 
 #if LLVM_VERSION_LT(17, 0)
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index d9262a92782..3e998d428ee 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1549,6 +1549,31 @@ LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
                                       Name));
 }
 
+extern "C" LLVMValueRef
+LLVMRustBuildCallBr(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
+                    LLVMBasicBlockRef DefaultDest,
+                    LLVMBasicBlockRef *IndirectDests, unsigned NumIndirectDests,
+                    LLVMValueRef *Args, unsigned NumArgs,
+                    OperandBundleDef **OpBundles, unsigned NumOpBundles,
+                    const char *Name) {
+  Value *Callee = unwrap(Fn);
+  FunctionType *FTy = unwrap<FunctionType>(Ty);
+
+  // FIXME: Is there a way around this?
+  std::vector<BasicBlock*> IndirectDestsUnwrapped;
+  IndirectDestsUnwrapped.reserve(NumIndirectDests);
+  for (unsigned i = 0; i < NumIndirectDests; ++i) {
+    IndirectDestsUnwrapped.push_back(unwrap(IndirectDests[i]));
+  }
+
+  return wrap(unwrap(B)->CreateCallBr(
+      FTy, Callee, unwrap(DefaultDest),
+      ArrayRef<BasicBlock*>(IndirectDestsUnwrapped),
+      ArrayRef<Value*>(unwrap(Args), NumArgs),
+      ArrayRef<OperandBundleDef>(*OpBundles, NumOpBundles),
+      Name));
+}
+
 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
                                                LLVMBasicBlockRef BB) {
   auto Point = unwrap(BB)->getFirstInsertionPt();
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 2f507b258fe..1c59af51589 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -356,7 +356,7 @@ provide! { tcx, def_id, other, cdata,
         cdata.get_stability_implications(tcx).iter().copied().collect()
     }
     stripped_cfg_items => { cdata.get_stripped_cfg_items(cdata.cnum, tcx) }
-    intrinsic => { cdata.get_intrinsic(def_id.index) }
+    intrinsic_raw => { cdata.get_intrinsic(def_id.index) }
     defined_lang_items => { cdata.get_lang_items(tcx) }
     diagnostic_items => { cdata.get_diagnostic_items() }
     missing_lang_items => { cdata.get_missing_lang_items(tcx) }
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 4b97c25f610..0221bc6c363 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1716,13 +1716,13 @@ mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
     // tidy-alphabetical-start
-    static_assert_size!(BasicBlockData<'_>, 136);
+    static_assert_size!(BasicBlockData<'_>, 144);
     static_assert_size!(LocalDecl<'_>, 40);
     static_assert_size!(SourceScopeData<'_>, 72);
     static_assert_size!(Statement<'_>, 32);
     static_assert_size!(StatementKind<'_>, 16);
-    static_assert_size!(Terminator<'_>, 104);
-    static_assert_size!(TerminatorKind<'_>, 88);
+    static_assert_size!(Terminator<'_>, 112);
+    static_assert_size!(TerminatorKind<'_>, 96);
     static_assert_size!(VarDebugInfo<'_>, 88);
     // tidy-alphabetical-end
 }
diff --git a/compiler/rustc_middle/src/mir/patch.rs b/compiler/rustc_middle/src/mir/patch.rs
index b81e9fa1aab..33412297017 100644
--- a/compiler/rustc_middle/src/mir/patch.rs
+++ b/compiler/rustc_middle/src/mir/patch.rs
@@ -11,6 +11,8 @@ pub struct MirPatch<'tcx> {
     resume_block: Option<BasicBlock>,
     // Only for unreachable in cleanup path.
     unreachable_cleanup_block: Option<BasicBlock>,
+    // Only for unreachable not in cleanup path.
+    unreachable_no_cleanup_block: Option<BasicBlock>,
     // Cached block for UnwindTerminate (with reason)
     terminate_block: Option<(BasicBlock, UnwindTerminateReason)>,
     body_span: Span,
@@ -27,6 +29,7 @@ impl<'tcx> MirPatch<'tcx> {
             next_local: body.local_decls.len(),
             resume_block: None,
             unreachable_cleanup_block: None,
+            unreachable_no_cleanup_block: None,
             terminate_block: None,
             body_span: body.span,
         };
@@ -43,9 +46,12 @@ impl<'tcx> MirPatch<'tcx> {
             // Check if we already have an unreachable block
             if matches!(block.terminator().kind, TerminatorKind::Unreachable)
                 && block.statements.is_empty()
-                && block.is_cleanup
             {
-                result.unreachable_cleanup_block = Some(bb);
+                if block.is_cleanup {
+                    result.unreachable_cleanup_block = Some(bb);
+                } else {
+                    result.unreachable_no_cleanup_block = Some(bb);
+                }
                 continue;
             }
 
@@ -95,6 +101,23 @@ impl<'tcx> MirPatch<'tcx> {
         bb
     }
 
+    pub fn unreachable_no_cleanup_block(&mut self) -> BasicBlock {
+        if let Some(bb) = self.unreachable_no_cleanup_block {
+            return bb;
+        }
+
+        let bb = self.new_block(BasicBlockData {
+            statements: vec![],
+            terminator: Some(Terminator {
+                source_info: SourceInfo::outermost(self.body_span),
+                kind: TerminatorKind::Unreachable,
+            }),
+            is_cleanup: false,
+        });
+        self.unreachable_no_cleanup_block = Some(bb);
+        bb
+    }
+
     pub fn terminate_block(&mut self, reason: UnwindTerminateReason) -> BasicBlock {
         if let Some((cached_bb, cached_reason)) = self.terminate_block
             && reason == cached_reason
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 5638b575b31..e058302af31 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -7,7 +7,7 @@ use std::path::{Path, PathBuf};
 use crate::mir::interpret::ConstAllocation;
 
 use super::graphviz::write_mir_fn_graphviz;
-use rustc_ast::InlineAsmTemplatePiece;
+use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_middle::mir::interpret::{
     alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer,
     Provenance,
@@ -830,6 +830,9 @@ impl<'tcx> TerminatorKind<'tcx> {
                         InlineAsmOperand::SymStatic { def_id } => {
                             write!(fmt, "sym_static {def_id:?}")?;
                         }
+                        InlineAsmOperand::Label { target_index } => {
+                            write!(fmt, "label {target_index}")?;
+                        }
                     }
                 }
                 write!(fmt, ", options({options:?}))")
@@ -868,16 +871,19 @@ impl<'tcx> TerminatorKind<'tcx> {
                 vec!["real".into(), "unwind".into()]
             }
             FalseUnwind { unwind: _, .. } => vec!["real".into()],
-            InlineAsm { destination: Some(_), unwind: UnwindAction::Cleanup(_), .. } => {
-                vec!["return".into(), "unwind".into()]
-            }
-            InlineAsm { destination: Some(_), unwind: _, .. } => {
-                vec!["return".into()]
-            }
-            InlineAsm { destination: None, unwind: UnwindAction::Cleanup(_), .. } => {
-                vec!["unwind".into()]
+            InlineAsm { options, ref targets, unwind, .. } => {
+                let mut vec = Vec::with_capacity(targets.len() + 1);
+                if !options.contains(InlineAsmOptions::NORETURN) {
+                    vec.push("return".into());
+                }
+                vec.resize(targets.len(), "label".into());
+
+                if let UnwindAction::Cleanup(_) = unwind {
+                    vec.push("unwind".into());
+                }
+
+                vec
             }
-            InlineAsm { destination: None, unwind: _, .. } => vec![],
         }
     }
 }
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 5c9857b9c53..f188923f876 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -793,9 +793,10 @@ pub enum TerminatorKind<'tcx> {
         /// used to map assembler errors back to the line in the source code.
         line_spans: &'tcx [Span],
 
-        /// Destination block after the inline assembly returns, unless it is
-        /// diverging (InlineAsmOptions::NORETURN).
-        destination: Option<BasicBlock>,
+        /// Valid targets for the inline assembly.
+        /// The first element is the fallthrough destination, unless
+        /// InlineAsmOptions::NORETURN is set.
+        targets: Vec<BasicBlock>,
 
         /// Action to be taken if the inline assembly unwinds. This is present
         /// if and only if InlineAsmOptions::MAY_UNWIND is set.
@@ -918,6 +919,10 @@ pub enum InlineAsmOperand<'tcx> {
     SymStatic {
         def_id: DefId,
     },
+    Label {
+        /// This represents the index into the `targets` array in `TerminatorKind::InlineAsm`.
+        target_index: usize,
+    },
 }
 
 /// Type for MIR `Assert` terminator error messages.
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index 6c92dfa3cd8..a4a4df55c48 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -74,6 +74,17 @@ impl SwitchTargets {
     pub fn target_for_value(&self, value: u128) -> BasicBlock {
         self.iter().find_map(|(v, t)| (v == value).then_some(t)).unwrap_or_else(|| self.otherwise())
     }
+
+    /// Adds a new target to the switch. But You cannot add an already present value.
+    #[inline]
+    pub fn add_target(&mut self, value: u128, bb: BasicBlock) {
+        let value = Pu128(value);
+        if self.values.contains(&value) {
+            bug!("target value {:?} already present", value);
+        }
+        self.values.push(value);
+        self.targets.insert(self.targets.len() - 1, bb);
+    }
 }
 
 pub struct SwitchTargetsIter<'a> {
@@ -336,8 +347,7 @@ pub struct Terminator<'tcx> {
 }
 
 pub type Successors<'a> = impl DoubleEndedIterator<Item = BasicBlock> + 'a;
-pub type SuccessorsMut<'a> =
-    iter::Chain<std::option::IntoIter<&'a mut BasicBlock>, slice::IterMut<'a, BasicBlock>>;
+pub type SuccessorsMut<'a> = impl DoubleEndedIterator<Item = &'a mut BasicBlock> + 'a;
 
 impl<'tcx> Terminator<'tcx> {
     #[inline]
@@ -371,40 +381,36 @@ impl<'tcx> TerminatorKind<'tcx> {
     pub fn successors(&self) -> Successors<'_> {
         use self::TerminatorKind::*;
         match *self {
-            Call { target: Some(t), unwind: UnwindAction::Cleanup(ref u), .. }
-            | Yield { resume: t, drop: Some(ref u), .. }
-            | Drop { target: t, unwind: UnwindAction::Cleanup(ref u), .. }
-            | Assert { target: t, unwind: UnwindAction::Cleanup(ref u), .. }
-            | FalseUnwind { real_target: t, unwind: UnwindAction::Cleanup(ref u) }
-            | InlineAsm { destination: Some(t), unwind: UnwindAction::Cleanup(ref u), .. } => {
-                Some(t).into_iter().chain(slice::from_ref(u).into_iter().copied())
-            }
-            Goto { target: t }
-            | Call { target: None, unwind: UnwindAction::Cleanup(t), .. }
-            | Call { target: Some(t), unwind: _, .. }
-            | Yield { resume: t, drop: None, .. }
-            | Drop { target: t, unwind: _, .. }
-            | Assert { target: t, unwind: _, .. }
-            | FalseUnwind { real_target: t, unwind: _ }
-            | InlineAsm { destination: None, unwind: UnwindAction::Cleanup(t), .. }
-            | InlineAsm { destination: Some(t), unwind: _, .. } => {
-                Some(t).into_iter().chain((&[]).into_iter().copied())
+            Call { target: Some(ref t), unwind: UnwindAction::Cleanup(u), .. }
+            | Yield { resume: ref t, drop: Some(u), .. }
+            | Drop { target: ref t, unwind: UnwindAction::Cleanup(u), .. }
+            | Assert { target: ref t, unwind: UnwindAction::Cleanup(u), .. }
+            | FalseUnwind { real_target: ref t, unwind: UnwindAction::Cleanup(u) } => {
+                slice::from_ref(t).into_iter().copied().chain(Some(u))
+            }
+            Goto { target: ref t }
+            | Call { target: None, unwind: UnwindAction::Cleanup(ref t), .. }
+            | Call { target: Some(ref t), unwind: _, .. }
+            | Yield { resume: ref t, drop: None, .. }
+            | Drop { target: ref t, unwind: _, .. }
+            | Assert { target: ref t, unwind: _, .. }
+            | FalseUnwind { real_target: ref t, unwind: _ } => {
+                slice::from_ref(t).into_iter().copied().chain(None)
             }
             UnwindResume
             | UnwindTerminate(_)
             | CoroutineDrop
             | Return
             | Unreachable
-            | Call { target: None, unwind: _, .. }
-            | InlineAsm { destination: None, unwind: _, .. } => {
-                None.into_iter().chain((&[]).into_iter().copied())
+            | Call { target: None, unwind: _, .. } => (&[]).into_iter().copied().chain(None),
+            InlineAsm { ref targets, unwind: UnwindAction::Cleanup(u), .. } => {
+                targets.iter().copied().chain(Some(u))
             }
-            SwitchInt { ref targets, .. } => {
-                None.into_iter().chain(targets.targets.iter().copied())
+            InlineAsm { ref targets, unwind: _, .. } => targets.iter().copied().chain(None),
+            SwitchInt { ref targets, .. } => targets.targets.iter().copied().chain(None),
+            FalseEdge { ref real_target, imaginary_target } => {
+                slice::from_ref(real_target).into_iter().copied().chain(Some(imaginary_target))
             }
-            FalseEdge { real_target, ref imaginary_target } => Some(real_target)
-                .into_iter()
-                .chain(slice::from_ref(imaginary_target).into_iter().copied()),
         }
     }
 
@@ -416,33 +422,31 @@ impl<'tcx> TerminatorKind<'tcx> {
             | Yield { resume: ref mut t, drop: Some(ref mut u), .. }
             | Drop { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
             | Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
-            | FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u) }
-            | InlineAsm {
-                destination: Some(ref mut t),
-                unwind: UnwindAction::Cleanup(ref mut u),
-                ..
-            } => Some(t).into_iter().chain(slice::from_mut(u)),
+            | FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u) } => {
+                slice::from_mut(t).into_iter().chain(Some(u))
+            }
             Goto { target: ref mut t }
             | Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. }
             | Call { target: Some(ref mut t), unwind: _, .. }
             | Yield { resume: ref mut t, drop: None, .. }
             | Drop { target: ref mut t, unwind: _, .. }
             | Assert { target: ref mut t, unwind: _, .. }
-            | FalseUnwind { real_target: ref mut t, unwind: _ }
-            | InlineAsm { destination: None, unwind: UnwindAction::Cleanup(ref mut t), .. }
-            | InlineAsm { destination: Some(ref mut t), unwind: _, .. } => {
-                Some(t).into_iter().chain(&mut [])
+            | FalseUnwind { real_target: ref mut t, unwind: _ } => {
+                slice::from_mut(t).into_iter().chain(None)
             }
             UnwindResume
             | UnwindTerminate(_)
             | CoroutineDrop
             | Return
             | Unreachable
-            | Call { target: None, unwind: _, .. }
-            | InlineAsm { destination: None, unwind: _, .. } => None.into_iter().chain(&mut []),
-            SwitchInt { ref mut targets, .. } => None.into_iter().chain(&mut targets.targets),
+            | Call { target: None, unwind: _, .. } => (&mut []).into_iter().chain(None),
+            InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => {
+                targets.iter_mut().chain(Some(u))
+            }
+            InlineAsm { ref mut targets, unwind: _, .. } => targets.iter_mut().chain(None),
+            SwitchInt { ref mut targets, .. } => targets.targets.iter_mut().chain(None),
             FalseEdge { ref mut real_target, ref mut imaginary_target } => {
-                Some(real_target).into_iter().chain(slice::from_mut(imaginary_target))
+                slice::from_mut(real_target).into_iter().chain(Some(imaginary_target))
             }
         }
     }
@@ -514,7 +518,7 @@ pub enum TerminatorEdges<'mir, 'tcx> {
     Double(BasicBlock, BasicBlock),
     /// Special action for `Yield`, `Call` and `InlineAsm` terminators.
     AssignOnReturn {
-        return_: Option<BasicBlock>,
+        return_: &'mir [BasicBlock],
         /// The cleanup block, if it exists.
         cleanup: Option<BasicBlock>,
         place: CallReturnPlaces<'mir, 'tcx>,
@@ -578,31 +582,37 @@ impl<'tcx> TerminatorKind<'tcx> {
                 TerminatorEdges::Double(real_target, imaginary_target)
             }
 
-            Yield { resume: target, drop, resume_arg, value: _ } => {
+            Yield { resume: ref target, drop, resume_arg, value: _ } => {
                 TerminatorEdges::AssignOnReturn {
-                    return_: Some(target),
+                    return_: slice::from_ref(target),
                     cleanup: drop,
                     place: CallReturnPlaces::Yield(resume_arg),
                 }
             }
 
-            Call { unwind, destination, target, func: _, args: _, fn_span: _, call_source: _ } => {
-                TerminatorEdges::AssignOnReturn {
-                    return_: target,
-                    cleanup: unwind.cleanup_block(),
-                    place: CallReturnPlaces::Call(destination),
-                }
-            }
+            Call {
+                unwind,
+                destination,
+                ref target,
+                func: _,
+                args: _,
+                fn_span: _,
+                call_source: _,
+            } => TerminatorEdges::AssignOnReturn {
+                return_: target.as_ref().map(slice::from_ref).unwrap_or_default(),
+                cleanup: unwind.cleanup_block(),
+                place: CallReturnPlaces::Call(destination),
+            },
 
             InlineAsm {
                 template: _,
                 ref operands,
                 options: _,
                 line_spans: _,
-                destination,
+                ref targets,
                 unwind,
             } => TerminatorEdges::AssignOnReturn {
-                return_: destination,
+                return_: targets,
                 cleanup: unwind.cleanup_block(),
                 place: CallReturnPlaces::InlineAsm(operands),
             },
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 2c5ca82a4cd..845b1717550 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -565,7 +565,7 @@ macro_rules! make_mir_visitor {
                         operands,
                         options: _,
                         line_spans: _,
-                        destination: _,
+                        targets: _,
                         unwind: _,
                     } => {
                         for op in operands {
@@ -595,7 +595,8 @@ macro_rules! make_mir_visitor {
                                     self.visit_constant(value, location);
                                 }
                                 InlineAsmOperand::Out { place: None, .. }
-                                | InlineAsmOperand::SymStatic { def_id: _ } => {}
+                                | InlineAsmOperand::SymStatic { def_id: _ }
+                                | InlineAsmOperand::Label { target_index: _ } => {}
                             }
                         }
                     }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 7c6e9762f2a..332ebdbdd94 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -762,6 +762,7 @@ rustc_queries! {
         desc { |tcx| "computing the variances of `{}`", tcx.def_path_str(def_id) }
         cache_on_disk_if { def_id.is_local() }
         separate_provide_extern
+        cycle_delay_bug
     }
 
     /// Maps from thee `DefId` of a type to its (inferred) outlives.
@@ -959,10 +960,6 @@ rustc_queries! {
         ensure_forwards_result_if_red
     }
 
-    query collect_mod_item_types(key: LocalModDefId) {
-        desc { |tcx| "collecting item types in {}", describe_as_module(key, tcx) }
-    }
-
     /// Caches `CoerceUnsized` kinds for impls on custom types.
     query coerce_unsized_info(key: DefId) -> Result<ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed> {
         desc { |tcx| "computing CoerceUnsized info for `{}`", tcx.def_path_str(key) }
@@ -1745,7 +1742,7 @@ rustc_queries! {
         separate_provide_extern
     }
     /// Whether the function is an intrinsic
-    query intrinsic(def_id: DefId) -> Option<rustc_middle::ty::IntrinsicDef> {
+    query intrinsic_raw(def_id: DefId) -> Option<rustc_middle::ty::IntrinsicDef> {
         desc { |tcx| "fetch intrinsic name if `{}` is an intrinsic", tcx.def_path_str(def_id) }
         separate_provide_extern
     }
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 65875ff3f9a..913d0072c29 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -565,6 +565,9 @@ pub enum InlineAsmOperand<'tcx> {
     SymStatic {
         def_id: DefId,
     },
+    Label {
+        block: BlockId,
+    },
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, HashStable)]
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 4847a7bea91..5952c296fb6 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -162,6 +162,7 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
                     | Const { value: _, span: _ }
                     | SymFn { value: _, span: _ }
                     | SymStatic { def_id: _ } => {}
+                    Label { block } => visitor.visit_block(&visitor.thir()[*block]),
                 }
             }
         }
diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
index 89c5eb517e5..8d3109a7b28 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
@@ -4,22 +4,31 @@ pub(super) struct ProofTreeFormatter<'a, 'b> {
     f: &'a mut (dyn Write + 'b),
 }
 
+enum IndentorState {
+    StartWithNewline,
+    OnNewline,
+    Inline,
+}
+
 /// A formatter which adds 4 spaces of indentation to its input before
 /// passing it on to its nested formatter.
 ///
 /// We can use this for arbitrary levels of indentation by nesting it.
 struct Indentor<'a, 'b> {
     f: &'a mut (dyn Write + 'b),
-    on_newline: bool,
+    state: IndentorState,
 }
 
 impl Write for Indentor<'_, '_> {
     fn write_str(&mut self, s: &str) -> std::fmt::Result {
         for line in s.split_inclusive('\n') {
-            if self.on_newline {
-                self.f.write_str("    ")?;
+            match self.state {
+                IndentorState::StartWithNewline => self.f.write_str("\n    ")?,
+                IndentorState::OnNewline => self.f.write_str("    ")?,
+                IndentorState::Inline => {}
             }
-            self.on_newline = line.ends_with('\n');
+            self.state =
+                if line.ends_with('\n') { IndentorState::OnNewline } else { IndentorState::Inline };
             self.f.write_str(line)?;
         }
 
@@ -32,11 +41,15 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
         ProofTreeFormatter { f }
     }
 
-    fn nested<F, R>(&mut self, func: F) -> R
+    fn nested<F>(&mut self, func: F) -> std::fmt::Result
     where
-        F: FnOnce(&mut ProofTreeFormatter<'_, '_>) -> R,
+        F: FnOnce(&mut ProofTreeFormatter<'_, '_>) -> std::fmt::Result,
     {
-        func(&mut ProofTreeFormatter { f: &mut Indentor { f: self.f, on_newline: true } })
+        write!(self.f, " {{")?;
+        func(&mut ProofTreeFormatter {
+            f: &mut Indentor { f: self.f, state: IndentorState::StartWithNewline },
+        })?;
+        writeln!(self.f, "}}")
     }
 
     pub(super) fn format_goal_evaluation(&mut self, eval: &GoalEvaluation<'_>) -> std::fmt::Result {
@@ -47,7 +60,7 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
                 IsNormalizesToHack::Yes => "NORMALIZES-TO HACK GOAL",
             },
         };
-        writeln!(self.f, "{}: {:?}", goal_text, eval.uncanonicalized_goal)?;
+        write!(self.f, "{}: {:?}", goal_text, eval.uncanonicalized_goal)?;
         self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation))
     }
 
@@ -69,7 +82,7 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
             }
             CanonicalGoalEvaluationKind::Evaluation { revisions } => {
                 for (n, step) in revisions.iter().enumerate() {
-                    writeln!(self.f, "REVISION {n}")?;
+                    write!(self.f, "REVISION {n}")?;
                     self.nested(|this| this.format_evaluation_step(step))?;
                 }
                 writeln!(self.f, "RESULT: {:?}", eval.result)
@@ -88,25 +101,25 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
     pub(super) fn format_probe(&mut self, probe: &Probe<'_>) -> std::fmt::Result {
         match &probe.kind {
             ProbeKind::Root { result } => {
-                writeln!(self.f, "ROOT RESULT: {result:?}")
+                write!(self.f, "ROOT RESULT: {result:?}")
             }
             ProbeKind::NormalizedSelfTyAssembly => {
-                writeln!(self.f, "NORMALIZING SELF TY FOR ASSEMBLY:")
+                write!(self.f, "NORMALIZING SELF TY FOR ASSEMBLY:")
             }
             ProbeKind::UnsizeAssembly => {
-                writeln!(self.f, "ASSEMBLING CANDIDATES FOR UNSIZING:")
+                write!(self.f, "ASSEMBLING CANDIDATES FOR UNSIZING:")
             }
             ProbeKind::UpcastProjectionCompatibility => {
-                writeln!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:")
+                write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:")
             }
             ProbeKind::CommitIfOk => {
-                writeln!(self.f, "COMMIT_IF_OK:")
+                write!(self.f, "COMMIT_IF_OK:")
             }
             ProbeKind::MiscCandidate { name, result } => {
-                writeln!(self.f, "CANDIDATE {name}: {result:?}")
+                write!(self.f, "CANDIDATE {name}: {result:?}")
             }
             ProbeKind::TraitCandidate { source, result } => {
-                writeln!(self.f, "CANDIDATE {source:?}: {result:?}")
+                write!(self.f, "CANDIDATE {source:?}: {result:?}")
             }
         }?;
 
@@ -137,7 +150,7 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
         writeln!(self.f, "TRY_EVALUATE_ADDED_GOALS: {:?}", added_goals_evaluation.result)?;
 
         for (n, iterations) in added_goals_evaluation.evaluations.iter().enumerate() {
-            writeln!(self.f, "ITERATION {n}")?;
+            write!(self.f, "ITERATION {n}")?;
             self.nested(|this| {
                 for goal_evaluation in iterations {
                     this.format_goal_evaluation(goal_evaluation)?;
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 4f8e4aa90f4..f947832d28c 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1254,7 +1254,7 @@ impl<'tcx> TyCtxt<'tcx> {
             if self.def_kind(scope) == DefKind::OpaqueTy {
                 // Lifetime params of opaque types are synthetic and thus irrelevant to
                 // diagnostics. Map them back to their origin!
-                region = self.map_rpit_lifetime_to_fn_lifetime(def_id);
+                region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
                 continue;
             }
             break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into())));
@@ -2219,31 +2219,31 @@ impl<'tcx> TyCtxt<'tcx> {
         )
     }
 
-    /// Given the def-id of an early-bound lifetime on an RPIT corresponding to
+    /// Given the def-id of an early-bound lifetime on an opaque corresponding to
     /// a duplicated captured lifetime, map it back to the early- or late-bound
     /// lifetime of the function from which it originally as captured. If it is
     /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
     /// of the signature.
     // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
     // re-use the generics of the opaque, this function will need to be tweaked slightly.
-    pub fn map_rpit_lifetime_to_fn_lifetime(
+    pub fn map_opaque_lifetime_to_parent_lifetime(
         self,
-        mut rpit_lifetime_param_def_id: LocalDefId,
+        mut opaque_lifetime_param_def_id: LocalDefId,
     ) -> ty::Region<'tcx> {
         debug_assert!(
-            matches!(self.def_kind(rpit_lifetime_param_def_id), DefKind::LifetimeParam),
-            "{rpit_lifetime_param_def_id:?} is a {}",
-            self.def_descr(rpit_lifetime_param_def_id.to_def_id())
+            matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
+            "{opaque_lifetime_param_def_id:?} is a {}",
+            self.def_descr(opaque_lifetime_param_def_id.to_def_id())
         );
 
         loop {
-            let parent = self.local_parent(rpit_lifetime_param_def_id);
+            let parent = self.local_parent(opaque_lifetime_param_def_id);
             let hir::OpaqueTy { lifetime_mapping, .. } =
                 self.hir_node_by_def_id(parent).expect_item().expect_opaque_ty();
 
             let Some((lifetime, _)) = lifetime_mapping
                 .iter()
-                .find(|(_, duplicated_param)| *duplicated_param == rpit_lifetime_param_def_id)
+                .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
             else {
                 bug!("duplicated lifetime param should be present");
             };
@@ -2256,7 +2256,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     // of the opaque we mapped from. Continue mapping.
                     if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
                         debug_assert_eq!(self.parent(parent.to_def_id()), new_parent);
-                        rpit_lifetime_param_def_id = ebv.expect_local();
+                        opaque_lifetime_param_def_id = ebv.expect_local();
                         continue;
                     }
 
@@ -2334,6 +2334,14 @@ impl<'tcx> TyCtxt<'tcx> {
         )
     }
 
+    pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {
+        match self.def_kind(def_id) {
+            DefKind::Fn | DefKind::AssocFn => {}
+            _ => return None,
+        }
+        self.intrinsic_raw(def_id)
+    }
+
     pub fn local_def_id_to_hir_id(self, local_def_id: LocalDefId) -> HirId {
         self.opt_local_def_id_to_hir_id(local_def_id).unwrap()
     }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 4edec0e6951..5c2d3973d61 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1940,18 +1940,6 @@ impl<'tcx> TyCtxt<'tcx> {
         matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait))
     }
 
-    /// Returns the `DefId` of the item within which the `impl Trait` is declared.
-    /// For type-alias-impl-trait this is the `type` alias.
-    /// For impl-trait-in-assoc-type this is the assoc type.
-    /// For return-position-impl-trait this is the function.
-    pub fn impl_trait_parent(self, mut def_id: LocalDefId) -> LocalDefId {
-        // Find the surrounding item (type alias or assoc type)
-        while let DefKind::OpaqueTy = self.def_kind(def_id) {
-            def_id = self.local_parent(def_id);
-        }
-        def_id
-    }
-
     pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
         if self.def_kind(def_id) != DefKind::AssocFn {
             return false;
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index a3c22db2add..4bb0d2c7d1c 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -1642,11 +1642,7 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
 }
 
 /// Determines whether an item is an intrinsic (which may be via Abi or via the `rustc_intrinsic` attribute)
-pub fn intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef> {
-    match tcx.def_kind(def_id) {
-        DefKind::Fn | DefKind::AssocFn => {}
-        _ => return None,
-    }
+pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef> {
     if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic)
         || tcx.has_attr(def_id, sym::rustc_intrinsic)
     {
@@ -1664,7 +1660,7 @@ pub fn provide(providers: &mut Providers) {
         reveal_opaque_types_in_bounds,
         is_doc_hidden,
         is_doc_notable_trait,
-        intrinsic,
+        intrinsic_raw,
         ..*providers
     }
 }
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index 27b48f46e75..f7a3879a7d4 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -131,6 +131,27 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<ty::Binder<'_, ty::FnSig<'_>>
     }
 }
 
+impl<'tcx> Value<TyCtxt<'tcx>> for &[ty::Variance] {
+    fn from_cycle_error(
+        tcx: TyCtxt<'tcx>,
+        cycle_error: &CycleError,
+        _guar: ErrorGuaranteed,
+    ) -> Self {
+        if let Some(frame) = cycle_error.cycle.get(0)
+            && frame.query.dep_kind == dep_kinds::variances_of
+            && let Some(def_id) = frame.query.def_id
+        {
+            let n = tcx.generics_of(def_id).params.len();
+            vec![ty::Variance::Bivariant; n].leak()
+        } else {
+            span_bug!(
+                cycle_error.usage.as_ref().unwrap().0,
+                "only `variances_of` returns `&[ty::Variance]`"
+            );
+        }
+    }
+}
+
 // Take a cycle of `Q` and try `try_cycle` on every permutation, falling back to `otherwise`.
 fn search_for_cycle_permutation<Q, T>(
     cycle: &[Q],
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 8a9dc34bc7b..b4eeeccc127 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -383,6 +383,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 line_spans,
             }) => {
                 use rustc_middle::{mir, thir};
+
+                let destination_block = this.cfg.start_new_block();
+                let mut targets = if options.contains(InlineAsmOptions::NORETURN) {
+                    vec![]
+                } else {
+                    vec![destination_block]
+                };
+
                 let operands = operands
                     .into_iter()
                     .map(|op| match *op {
@@ -438,14 +446,28 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         thir::InlineAsmOperand::SymStatic { def_id } => {
                             mir::InlineAsmOperand::SymStatic { def_id }
                         }
+                        thir::InlineAsmOperand::Label { block } => {
+                            let target = this.cfg.start_new_block();
+                            let target_index = targets.len();
+                            targets.push(target);
+
+                            let tmp = this.get_unit_temp();
+                            let target = unpack!(this.ast_block(tmp, target, block, source_info));
+                            this.cfg.terminate(
+                                target,
+                                source_info,
+                                TerminatorKind::Goto { target: destination_block },
+                            );
+
+                            mir::InlineAsmOperand::Label { target_index }
+                        }
                     })
                     .collect();
 
-                if !options.contains(InlineAsmOptions::NORETURN) {
+                if !expr.ty.is_never() {
                     this.cfg.push_assign_unit(block, source_info, destination, this.tcx);
                 }
 
-                let destination_block = this.cfg.start_new_block();
                 this.cfg.terminate(
                     block,
                     source_info,
@@ -454,11 +476,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         operands,
                         options,
                         line_spans,
-                        destination: if options.contains(InlineAsmOptions::NORETURN) {
-                            None
-                        } else {
-                            Some(destination_block)
-                        },
+                        targets,
                         unwind: if options.contains(InlineAsmOptions::MAY_UNWIND) {
                             UnwindAction::Continue
                         } else {
diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs
index 3f2b7c482a6..2c817d605af 100644
--- a/compiler/rustc_mir_build/src/lints.rs
+++ b/compiler/rustc_mir_build/src/lints.rs
@@ -199,9 +199,10 @@ impl<'mir, 'tcx, C: TerminatorClassifier<'tcx>> TriColorVisitor<BasicBlocks<'tcx
             | TerminatorKind::Unreachable
             | TerminatorKind::Yield { .. } => ControlFlow::Break(NonRecursive),
 
-            // A diverging InlineAsm is treated as non-recursing
-            TerminatorKind::InlineAsm { destination, .. } => {
-                if destination.is_some() {
+            // A InlineAsm without targets (diverging and contains no labels)
+            // is treated as non-recursing.
+            TerminatorKind::InlineAsm { ref targets, .. } => {
+                if !targets.is_empty() {
                     ControlFlow::Continue(())
                 } else {
                     ControlFlow::Break(NonRecursive)
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 62762168cf4..2318e84292b 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -656,6 +656,9 @@ impl<'tcx> Cx<'tcx> {
                         hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
                             InlineAsmOperand::SymStatic { def_id }
                         }
+                        hir::InlineAsmOperand::Label { block } => {
+                            InlineAsmOperand::Label { block: self.mirror_block(block) }
+                        }
                     })
                     .collect(),
                 options: asm.options,
diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
index 267ea3aa3e1..d53704f89e7 100644
--- a/compiler/rustc_mir_build/src/thir/print.rs
+++ b/compiler/rustc_mir_build/src/thir/print.rs
@@ -889,6 +889,12 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
                 print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
                 print_indented!(self, "}", depth_lvl + 1);
             }
+            InlineAsmOperand::Label { block } => {
+                print_indented!(self, "InlineAsmOperand::Block {", depth_lvl);
+                print_indented!(self, "block:", depth_lvl + 1);
+                self.print_block(*block, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
         }
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 4c3fadf487b..f57e8b8bd6f 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -242,9 +242,9 @@ impl Direction for Backward {
                     propagate(pred, &tmp);
                 }
 
-                mir::TerminatorKind::InlineAsm {
-                    destination: Some(dest), ref operands, ..
-                } if dest == bb => {
+                mir::TerminatorKind::InlineAsm { ref targets, ref operands, .. }
+                    if targets.contains(&bb) =>
+                {
                     let mut tmp = exit_state.clone();
                     analysis.apply_call_return_effect(
                         &mut tmp,
@@ -491,9 +491,12 @@ impl Direction for Forward {
                 if let Some(cleanup) = cleanup {
                     propagate(cleanup, exit_state);
                 }
-                if let Some(return_) = return_ {
+
+                if !return_.is_empty() {
                     analysis.apply_call_return_effect(exit_state, bb, place);
-                    propagate(return_, exit_state);
+                    for &target in return_ {
+                        propagate(target, exit_state);
+                    }
                 }
             }
             TerminatorEdges::SwitchInt { targets, discr } => {
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index 0270e059a58..a827f6a8dbd 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -299,7 +299,9 @@ where
                 })?;
             }
 
-            mir::TerminatorKind::InlineAsm { destination: Some(_), ref operands, .. } => {
+            mir::TerminatorKind::InlineAsm { ref targets, ref operands, .. }
+                if !targets.is_empty() =>
+            {
                 self.write_row(w, "", "(on successful return)", |this, w, fmt| {
                     let state_on_unwind = this.results.get().clone();
                     this.results.apply_custom_effect(|analysis, state| {
diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
index 595c2ff5bf7..29169c31263 100644
--- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
@@ -271,7 +271,8 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
                         InlineAsmOperand::In { .. }
                         | InlineAsmOperand::Const { .. }
                         | InlineAsmOperand::SymFn { .. }
-                        | InlineAsmOperand::SymStatic { .. } => {}
+                        | InlineAsmOperand::SymStatic { .. }
+                        | InlineAsmOperand::Label { .. } => {}
                     }
                 }
             }
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index c6ec1b5aee4..db48ecd702b 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -491,7 +491,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
                 ref operands,
                 options: _,
                 line_spans: _,
-                destination: _,
+                targets: _,
                 unwind: _,
             } => {
                 for op in operands {
@@ -515,7 +515,8 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
                         }
                         InlineAsmOperand::Const { value: _ }
                         | InlineAsmOperand::SymFn { value: _ }
-                        | InlineAsmOperand::SymStatic { def_id: _ } => {}
+                        | InlineAsmOperand::SymStatic { def_id: _ }
+                        | InlineAsmOperand::Label { target_index: _ } => {}
                     }
                 }
             }
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index c97192435ce..ed8c4d8283d 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -349,12 +349,20 @@ fn bcb_filtered_successors<'a, 'tcx>(terminator: &'a Terminator<'tcx>) -> Covera
         | FalseUnwind { real_target: target, .. }
         | Goto { target } => CoverageSuccessors::Chainable(target),
 
-        // These terminators can normally be chained, except when they have no
+        // A call terminator can normally be chained, except when they have no
         // successor because they are known to diverge.
-        Call { target: maybe_target, .. } | InlineAsm { destination: maybe_target, .. } => {
-            match maybe_target {
-                Some(target) => CoverageSuccessors::Chainable(target),
-                None => CoverageSuccessors::NotChainable(&[]),
+        Call { target: maybe_target, .. } => match maybe_target {
+            Some(target) => CoverageSuccessors::Chainable(target),
+            None => CoverageSuccessors::NotChainable(&[]),
+        },
+
+        // An inline asm terminator can normally be chained, except when it diverges or uses asm
+        // goto.
+        InlineAsm { ref targets, .. } => {
+            if targets.len() == 1 {
+                CoverageSuccessors::Chainable(targets[0])
+            } else {
+                CoverageSuccessors::NotChainable(targets)
             }
         }
 
diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs
index d9a3c0cb162..569998de35e 100644
--- a/compiler/rustc_mir_transform/src/coverage/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/tests.rs
@@ -88,7 +88,6 @@ impl<'tcx> MockBlocks<'tcx> {
             | TerminatorKind::FalseEdge { real_target: ref mut target, .. }
             | TerminatorKind::FalseUnwind { real_target: ref mut target, .. }
             | TerminatorKind::Goto { ref mut target }
-            | TerminatorKind::InlineAsm { destination: Some(ref mut target), .. }
             | TerminatorKind::Yield { resume: ref mut target, .. } => *target = to_block,
             ref invalid => bug!("Invalid from_block: {:?}", invalid),
         }
@@ -185,10 +184,12 @@ fn debug_basic_blocks(mir_body: &Body<'_>) -> String {
                     | TerminatorKind::FalseEdge { real_target: target, .. }
                     | TerminatorKind::FalseUnwind { real_target: target, .. }
                     | TerminatorKind::Goto { target }
-                    | TerminatorKind::InlineAsm { destination: Some(target), .. }
                     | TerminatorKind::Yield { resume: target, .. } => {
                         format!("{}{:?}:{} -> {:?}", sp, bb, kind.name(), target)
                     }
+                    TerminatorKind::InlineAsm { targets, .. } => {
+                        format!("{}{:?}:{} -> {:?}", sp, bb, kind.name(), targets)
+                    }
                     TerminatorKind::SwitchInt { targets, .. } => {
                         format!("{}{:?}:{} -> {:?}", sp, bb, kind.name(), targets)
                     }
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 2c8201b1903..10fea09531a 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -648,7 +648,8 @@ impl WriteInfo {
                         }
                         InlineAsmOperand::Const { .. }
                         | InlineAsmOperand::SymFn { .. }
-                        | InlineAsmOperand::SymStatic { .. } => (),
+                        | InlineAsmOperand::SymStatic { .. }
+                        | InlineAsmOperand::Label { .. } => {}
                     }
                 }
             }
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 36546a03cdf..f6a0945c222 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -1036,8 +1036,8 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
             {
                 bug!("False unwinds should have been removed before inlining")
             }
-            TerminatorKind::InlineAsm { ref mut destination, ref mut unwind, .. } => {
-                if let Some(ref mut tgt) = *destination {
+            TerminatorKind::InlineAsm { ref mut targets, ref mut unwind, .. } => {
+                for tgt in targets.iter_mut() {
                     *tgt = self.map_block(*tgt);
                 }
                 *unwind = self.map_unwind(*unwind);
diff --git a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs
index e68d37f4c70..57fe46ad75a 100644
--- a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs
+++ b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs
@@ -2,8 +2,10 @@
 
 use crate::MirPass;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::{
-    BasicBlockData, Body, Local, Operand, Rvalue, StatementKind, Terminator, TerminatorKind,
+    BasicBlock, BasicBlockData, BasicBlocks, Body, Local, Operand, Rvalue, StatementKind,
+    TerminatorKind,
 };
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::{Ty, TyCtxt};
@@ -77,7 +79,8 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         trace!("UninhabitedEnumBranching starting for {:?}", body.source);
 
-        let mut removable_switchs = Vec::new();
+        let mut unreachable_targets = Vec::new();
+        let mut patch = MirPatch::new(body);
 
         for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
             trace!("processing block {:?}", bb);
@@ -92,46 +95,73 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
                 tcx.param_env_reveal_all_normalized(body.source.def_id()).and(discriminant_ty),
             );
 
-            let allowed_variants = if let Ok(layout) = layout {
+            let mut allowed_variants = if let Ok(layout) = layout {
                 variant_discriminants(&layout, discriminant_ty, tcx)
+            } else if let Some(variant_range) = discriminant_ty.variant_range(tcx) {
+                variant_range
+                    .map(|variant| {
+                        discriminant_ty.discriminant_for_variant(tcx, variant).unwrap().val
+                    })
+                    .collect()
             } else {
                 continue;
             };
 
             trace!("allowed_variants = {:?}", allowed_variants);
 
-            let terminator = bb_data.terminator();
-            let TerminatorKind::SwitchInt { targets, .. } = &terminator.kind else { bug!() };
+            unreachable_targets.clear();
+            let TerminatorKind::SwitchInt { targets, discr } = &bb_data.terminator().kind else {
+                bug!()
+            };
 
-            let mut reachable_count = 0;
             for (index, (val, _)) in targets.iter().enumerate() {
-                if allowed_variants.contains(&val) {
-                    reachable_count += 1;
-                } else {
-                    removable_switchs.push((bb, index));
+                if !allowed_variants.remove(&val) {
+                    unreachable_targets.push(index);
+                }
+            }
+            let otherwise_is_empty_unreachable =
+                body.basic_blocks[targets.otherwise()].is_empty_unreachable();
+            // After resolving https://github.com/llvm/llvm-project/issues/78578,
+            // we can remove the limit on the number of successors.
+            fn check_successors(basic_blocks: &BasicBlocks<'_>, bb: BasicBlock) -> bool {
+                let mut successors = basic_blocks[bb].terminator().successors();
+                let Some(first_successor) = successors.next() else { return true };
+                if successors.next().is_some() {
+                    return true;
                 }
+                if let TerminatorKind::SwitchInt { .. } =
+                    &basic_blocks[first_successor].terminator().kind
+                {
+                    return false;
+                };
+                true
             }
+            let otherwise_is_last_variant = !otherwise_is_empty_unreachable
+                && allowed_variants.len() == 1
+                && check_successors(&body.basic_blocks, targets.otherwise());
+            let replace_otherwise_to_unreachable = otherwise_is_last_variant
+                || !otherwise_is_empty_unreachable && allowed_variants.is_empty();
 
-            if reachable_count == allowed_variants.len() {
-                removable_switchs.push((bb, targets.iter().count()));
+            if unreachable_targets.is_empty() && !replace_otherwise_to_unreachable {
+                continue;
             }
-        }
 
-        if removable_switchs.is_empty() {
-            return;
+            let unreachable_block = patch.unreachable_no_cleanup_block();
+            let mut targets = targets.clone();
+            if replace_otherwise_to_unreachable {
+                if otherwise_is_last_variant {
+                    #[allow(rustc::potential_query_instability)]
+                    let last_variant = *allowed_variants.iter().next().unwrap();
+                    targets.add_target(last_variant, targets.otherwise());
+                }
+                unreachable_targets.push(targets.iter().count());
+            }
+            for index in unreachable_targets.iter() {
+                targets.all_targets_mut()[*index] = unreachable_block;
+            }
+            patch.patch_terminator(bb, TerminatorKind::SwitchInt { targets, discr: discr.clone() });
         }
 
-        let new_block = BasicBlockData::new(Some(Terminator {
-            source_info: body.basic_blocks[removable_switchs[0].0].terminator().source_info,
-            kind: TerminatorKind::Unreachable,
-        }));
-        let unreachable_block = body.basic_blocks.as_mut().push(new_block);
-
-        for (bb, index) in removable_switchs {
-            let bb = &mut body.basic_blocks.as_mut()[bb];
-            let terminator = bb.terminator_mut();
-            let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind else { bug!() };
-            targets.all_targets_mut()[index] = unreachable_block;
-        }
+        patch.apply(body);
     }
 }
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 37cce625c8e..32f823a5ac6 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -446,7 +446,8 @@ fn collect_items_rec<'tcx>(
                         hir::InlineAsmOperand::In { .. }
                         | hir::InlineAsmOperand::Out { .. }
                         | hir::InlineAsmOperand::InOut { .. }
-                        | hir::InlineAsmOperand::SplitInOut { .. } => {
+                        | hir::InlineAsmOperand::SplitInOut { .. }
+                        | hir::InlineAsmOperand::Label { .. } => {
                             span_bug!(*op_sp, "invalid operand type for global_asm!")
                         }
                     }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 6cc358db9fc..7a34bc7890c 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -13,13 +13,14 @@ use ast::mut_visit::{noop_visit_expr, MutVisitor};
 use ast::token::IdentIsRaw;
 use ast::{CoroutineKind, ForLoopKind, GenBlockKind, Pat, Path, PathSegment};
 use core::mem;
+use core::ops::ControlFlow;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, Token, TokenKind};
 use rustc_ast::tokenstream::Spacing;
 use rustc_ast::util::case::Case;
 use rustc_ast::util::classify;
 use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
-use rustc_ast::visit::Visitor;
+use rustc_ast::visit::{walk_expr, Visitor};
 use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, UnOp, DUMMY_NODE_ID};
 use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind};
 use rustc_ast::{Arm, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
@@ -1703,19 +1704,20 @@ impl<'a> Parser<'a> {
                 let span = expr.span;
 
                 let found_labeled_breaks = {
-                    struct FindLabeledBreaksVisitor(bool);
+                    struct FindLabeledBreaksVisitor;
 
                     impl<'ast> Visitor<'ast> for FindLabeledBreaksVisitor {
-                        fn visit_expr_post(&mut self, ex: &'ast Expr) {
+                        type Result = ControlFlow<()>;
+                        fn visit_expr(&mut self, ex: &'ast Expr) -> ControlFlow<()> {
                             if let ExprKind::Break(Some(_label), _) = ex.kind {
-                                self.0 = true;
+                                ControlFlow::Break(())
+                            } else {
+                                walk_expr(self, ex)
                             }
                         }
                     }
 
-                    let mut vis = FindLabeledBreaksVisitor(false);
-                    vis.visit_expr(&expr);
-                    vis.0
+                    FindLabeledBreaksVisitor.visit_expr(&expr).is_break()
                 };
 
                 // Suggestion involves adding a labeled block.
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index ea9c78ca34c..73f5829adec 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -448,7 +448,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a block. No inner attributes are allowed.
-    pub(super) fn parse_block(&mut self) -> PResult<'a, P<Block>> {
+    pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
         let (attrs, block) = self.parse_inner_attrs_and_block()?;
         if let [.., last] = &*attrs {
             self.error_on_forbidden_inner_attr(
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 487407014d1..e5033e1f51f 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -86,7 +86,6 @@ use crate::errors;
 use self::LiveNodeKind::*;
 use self::VarKind::*;
 
-use rustc_ast::InlineAsmOptions;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir as hir;
 use rustc_hir::def::*;
@@ -416,6 +415,12 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
                 self.add_live_node_for_node(expr.hir_id, ExprNode(expr.span, expr.hir_id));
             }
 
+            // Inline assembly may contain labels.
+            hir::ExprKind::InlineAsm(asm) if asm.contains_label() => {
+                self.add_live_node_for_node(expr.hir_id, ExprNode(expr.span, expr.hir_id));
+                intravisit::walk_expr(self, expr);
+            }
+
             // otherwise, live nodes are not required:
             hir::ExprKind::Index(..)
             | hir::ExprKind::Field(..)
@@ -1045,20 +1050,53 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             | hir::ExprKind::Repeat(ref e, _) => self.propagate_through_expr(e, succ),
 
             hir::ExprKind::InlineAsm(asm) => {
+                //
+                //     (inputs)
+                //        |
+                //        v
+                //     (outputs)
+                //    /         \
+                //    |         |
+                //    v         v
+                // (labels)(fallthrough)
+                //    |         |
+                //    v         v
+                // ( succ / exit_ln )
+
                 // Handle non-returning asm
-                let mut succ = if asm.options.contains(InlineAsmOptions::NORETURN) {
-                    self.exit_ln
-                } else {
-                    succ
-                };
+                let mut succ =
+                    if self.typeck_results.expr_ty(expr).is_never() { self.exit_ln } else { succ };
+
+                // Do a first pass for labels only
+                if asm.contains_label() {
+                    let ln = self.live_node(expr.hir_id, expr.span);
+                    self.init_from_succ(ln, succ);
+                    for (op, _op_sp) in asm.operands.iter().rev() {
+                        match op {
+                            hir::InlineAsmOperand::Label { block } => {
+                                let label_ln = self.propagate_through_block(block, succ);
+                                self.merge_from_succ(ln, label_ln);
+                            }
+                            hir::InlineAsmOperand::In { .. }
+                            | hir::InlineAsmOperand::Out { .. }
+                            | hir::InlineAsmOperand::InOut { .. }
+                            | hir::InlineAsmOperand::SplitInOut { .. }
+                            | hir::InlineAsmOperand::Const { .. }
+                            | hir::InlineAsmOperand::SymFn { .. }
+                            | hir::InlineAsmOperand::SymStatic { .. } => {}
+                        }
+                    }
+                    succ = ln;
+                }
 
-                // Do a first pass for writing outputs only
+                // Do a second pass for writing outputs only
                 for (op, _op_sp) in asm.operands.iter().rev() {
                     match op {
                         hir::InlineAsmOperand::In { .. }
                         | hir::InlineAsmOperand::Const { .. }
                         | hir::InlineAsmOperand::SymFn { .. }
-                        | hir::InlineAsmOperand::SymStatic { .. } => {}
+                        | hir::InlineAsmOperand::SymStatic { .. }
+                        | hir::InlineAsmOperand::Label { .. } => {}
                         hir::InlineAsmOperand::Out { expr, .. } => {
                             if let Some(expr) = expr {
                                 succ = self.write_place(expr, succ, ACC_WRITE);
@@ -1075,7 +1113,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                     }
                 }
 
-                // Then do a second pass for inputs
+                // Then do a third pass for inputs
                 for (op, _op_sp) in asm.operands.iter().rev() {
                     match op {
                         hir::InlineAsmOperand::In { expr, .. } => {
@@ -1097,7 +1135,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                         }
                         hir::InlineAsmOperand::Const { .. }
                         | hir::InlineAsmOperand::SymFn { .. }
-                        | hir::InlineAsmOperand::SymStatic { .. } => {}
+                        | hir::InlineAsmOperand::SymStatic { .. }
+                        | hir::InlineAsmOperand::Label { .. } => {}
                     }
                 }
                 succ
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index 0455d6d4acb..27c9c1306e6 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -237,7 +237,8 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
                 InlineAsmOperand::In { .. }
                 | InlineAsmOperand::Out { .. }
                 | InlineAsmOperand::InOut { .. }
-                | InlineAsmOperand::SplitInOut { .. } => Some(op_sp),
+                | InlineAsmOperand::SplitInOut { .. }
+                | InlineAsmOperand::Label { .. } => Some(op_sp),
             })
             .collect();
         if !unsupported_operands.is_empty() {
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 455afb8de8e..d2aea0056b3 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1242,6 +1242,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                     self.resolve_anon_const(anon_const, AnonConstKind::InlineConst);
                 }
                 InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym),
+                InlineAsmOperand::Label { block } => self.visit_block(block),
             }
         }
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index 501d6f7d304..003a9a59200 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -559,7 +559,8 @@ impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> {
             }
             InlineAsmOperand::Const { .. }
             | InlineAsmOperand::SymFn { .. }
-            | InlineAsmOperand::SymStatic { .. } => (None, None),
+            | InlineAsmOperand::SymStatic { .. }
+            | InlineAsmOperand::Label { .. } => (None, None),
         };
 
         stable_mir::mir::InlineAsmOperand { in_value, out_place, raw_rpr: format!("{self:?}") }
@@ -632,14 +633,15 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
                 operands,
                 options,
                 line_spans,
-                destination,
+                targets,
                 unwind,
             } => TerminatorKind::InlineAsm {
                 template: format!("{template:?}"),
                 operands: operands.iter().map(|operand| operand.stable(tables)).collect(),
                 options: format!("{options:?}"),
                 line_spans: format!("{line_spans:?}"),
-                destination: destination.map(|d| d.as_usize()),
+                // FIXME: Figure out how to do labels in SMIR
+                destination: targets.first().map(|d| d.as_usize()),
                 unwind: unwind.stable(tables),
             },
             mir::TerminatorKind::Yield { .. }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9e628e4ef91..9dadd471247 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -399,6 +399,7 @@ symbols! {
         asm,
         asm_const,
         asm_experimental_arch,
+        asm_goto,
         asm_sym,
         asm_unwind,
         assert,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index a68dae0ade3..3b6e15fad46 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1404,6 +1404,7 @@ supported_targets! {
     ("i686-unknown-linux-gnu", i686_unknown_linux_gnu),
     ("i586-unknown-linux-gnu", i586_unknown_linux_gnu),
     ("loongarch64-unknown-linux-gnu", loongarch64_unknown_linux_gnu),
+    ("loongarch64-unknown-linux-musl", loongarch64_unknown_linux_musl),
     ("m68k-unknown-linux-gnu", m68k_unknown_linux_gnu),
     ("csky-unknown-linux-gnuabiv2", csky_unknown_linux_gnuabiv2),
     ("csky-unknown-linux-gnuabiv2hf", csky_unknown_linux_gnuabiv2hf),
@@ -3252,6 +3253,7 @@ impl ToJson for Target {
         }
 
         target_val!(llvm_target);
+        target_val!(description);
         d.insert("target-pointer-width".to_string(), self.pointer_width.to_string().to_json());
         target_val!(arch);
         target_val!(data_layout);
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
index 12eba149258..29c191fc9ab 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
@@ -7,7 +7,7 @@ pub fn target() -> Target {
 
     Target {
         llvm_target: "aarch64-pc-windows-msvc".into(),
-        description: None,
+        description: Some("ARM64 Windows MSVC".into()),
         pointer_width: 64,
         data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".into(),
         arch: "aarch64".into(),
diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs
index 28b2345874a..0ba486417ff 100644
--- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs
@@ -23,7 +23,7 @@ pub fn target() -> Target {
 
     Target {
         llvm_target: "i686-pc-windows-msvc".into(),
-        description: None,
+        description: Some("32-bit MSVC (Windows 7+)".into()),
         pointer_width: 32,
         data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
             i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
diff --git a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs
index 1990c91bdcc..081b4c5364c 100644
--- a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs
@@ -23,7 +23,7 @@ pub fn target() -> Target {
 
     Target {
         llvm_target: "i686-pc-windows-msvc".into(),
-        description: None,
+        description: Some("32-bit Windows 7 support".into()),
         pointer_width: 32,
         data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
             i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs
new file mode 100644
index 00000000000..9f653174cf0
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs
@@ -0,0 +1,19 @@
+use crate::spec::{base, Target, TargetOptions};
+
+pub fn target() -> Target {
+    Target {
+        llvm_target: "loongarch64-unknown-linux-musl".into(),
+        description: None,
+        pointer_width: 64,
+        data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
+        arch: "loongarch64".into(),
+        options: TargetOptions {
+            cpu: "generic".into(),
+            features: "+f,+d".into(),
+            llvm_abiname: "lp64d".into(),
+            max_atomic_width: Some(64),
+            crt_static_default: false,
+            ..base::linux_musl::opts()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs
index 31a01f5cbff..bb2555bb1a5 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs
@@ -13,7 +13,7 @@ pub fn target() -> Target {
 
     Target {
         llvm_target: "thumbv7a-pc-windows-msvc".into(),
-        description: None,
+        description: Some("ARM32 Windows MSVC".into()),
         pointer_width: 32,
         data_layout: "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
         arch: "arm".into(),
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs
index c8d01a912cb..c066c453feb 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_msvc.rs
@@ -10,7 +10,7 @@ pub fn target() -> Target {
 
     Target {
         llvm_target: "x86_64-pc-windows-msvc".into(),
-        description: None,
+        description: Some("64-bit MSVC (Windows 7+)".into()),
         pointer_width: 64,
         data_layout:
             "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs
index f0c1afcdce8..813802e2320 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs
@@ -9,7 +9,7 @@ pub fn target() -> Target {
 
     Target {
         llvm_target: "x86_64-win7-windows-msvc".into(),
-        description: None,
+        description: Some("64-bit Windows 7 support".into()),
         pointer_width: 64,
         data_layout:
             "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index ac2b738d3b6..71fcc47dba3 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -19,6 +19,7 @@ use crate::traits::{
     ObligationCause, ObligationCauseCode, ObligationCtxt, Overflow, PredicateObligation,
     SelectionError, SignatureMismatch, TraitNotObjectSafe,
 };
+use core::ops::ControlFlow;
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_errors::codes::*;
 use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan, StringPart};
@@ -1126,22 +1127,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         err: &mut Diag<'_>,
     ) -> bool {
         let span = obligation.cause.span;
-        struct V<'v> {
+        struct V {
             search_span: Span,
-            found: Option<&'v hir::Expr<'v>>,
         }
-        impl<'v> Visitor<'v> for V<'v> {
-            fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
+        impl<'v> Visitor<'v> for V {
+            type Result = ControlFlow<&'v hir::Expr<'v>>;
+            fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) -> Self::Result {
                 if let hir::ExprKind::Match(expr, _arms, hir::MatchSource::TryDesugar(_)) = ex.kind
+                    && ex.span.with_lo(ex.span.hi() - BytePos(1)).source_equal(self.search_span)
+                    && let hir::ExprKind::Call(_, [expr, ..]) = expr.kind
                 {
-                    if ex.span.with_lo(ex.span.hi() - BytePos(1)).source_equal(self.search_span) {
-                        if let hir::ExprKind::Call(_, [expr, ..]) = expr.kind {
-                            self.found = Some(expr);
-                            return;
-                        }
-                    }
+                    ControlFlow::Break(expr)
+                } else {
+                    hir::intravisit::walk_expr(self, ex)
                 }
-                hir::intravisit::walk_expr(self, ex);
             }
         }
         let hir_id = self.tcx.local_def_id_to_hir_id(obligation.cause.body_id);
@@ -1149,9 +1148,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. }) => body_id,
             _ => return false,
         };
-        let mut v = V { search_span: span, found: None };
-        v.visit_body(self.tcx.hir().body(*body_id));
-        let Some(expr) = v.found else {
+        let ControlFlow::Break(expr) =
+            (V { search_span: span }).visit_body(self.tcx.hir().body(*body_id))
+        else {
             return false;
         };
         let Some(typeck) = &self.typeck_results else {
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index 191671bcc1e..87462963c27 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -71,7 +71,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
                     // the end of the list corresponding to the opaque's generics.
                     for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] {
                         let orig_lt =
-                            tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local());
+                            tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
                         if matches!(*orig_lt, ty::ReLateParam(..)) {
                             mapping.insert(
                                 orig_lt,
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index c6448b4f661..3dcc8382289 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -141,7 +141,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
         trace!(?origin);
         match origin {
             rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {}
-            rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
+            rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
                 if !in_assoc_ty {
                     if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
                         return;
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 58ffa9710d3..e99c6220e20 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -624,6 +624,7 @@ impl<K, V> BTreeMap<K, V> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_btree_new", since = "1.66.0")]
+    #[inline]
     #[must_use]
     pub const fn new() -> BTreeMap<K, V> {
         BTreeMap { root: None, length: 0, alloc: ManuallyDrop::new(Global), _marker: PhantomData }
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 25a2d410c45..4016167d05c 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -201,14 +201,22 @@ pub trait Write {
         impl<W: Write + ?Sized> SpecWriteFmt for &mut W {
             #[inline]
             default fn spec_write_fmt(mut self, args: Arguments<'_>) -> Result {
-                write(&mut self, args)
+                if let Some(s) = args.as_const_str() {
+                    self.write_str(s)
+                } else {
+                    write(&mut self, args)
+                }
             }
         }
 
         impl<W: Write> SpecWriteFmt for &mut W {
             #[inline]
             fn spec_write_fmt(self, args: Arguments<'_>) -> Result {
-                write(self, args)
+                if let Some(s) = args.as_const_str() {
+                    self.write_str(s)
+                } else {
+                    write(self, args)
+                }
             }
         }
 
@@ -430,6 +438,14 @@ impl<'a> Arguments<'a> {
             _ => None,
         }
     }
+
+    /// Same as [`Arguments::as_str`], but will only return `Some(s)` if it can be determined at compile time.
+    #[must_use]
+    #[inline]
+    fn as_const_str(&self) -> Option<&'static str> {
+        let s = self.as_str();
+        if core::intrinsics::is_val_statically_known(s.is_some()) { s } else { None }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1119,14 +1135,8 @@ pub trait UpperExp {
 /// ```
 ///
 /// [`write!`]: crate::write!
-#[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
-    if let Some(s) = args.as_str() { output.write_str(s) } else { write_internal(output, args) }
-}
-
-/// Actual implementation of the [`write()`], but without the simple string optimization.
-fn write_internal(output: &mut dyn Write, args: Arguments<'_>) -> Result {
     let mut formatter = Formatter::new(output);
     let mut idx = 0;
 
@@ -1605,8 +1615,9 @@ impl<'a> Formatter<'a> {
     /// assert_eq!(format!("{:0>8}", Foo(2)), "Foo 2");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result {
-        write(self.buf, fmt)
+        if let Some(s) = fmt.as_const_str() { self.buf.write_str(s) } else { write(self.buf, fmt) }
     }
 
     /// Flags for formatting
@@ -2295,8 +2306,13 @@ impl Write for Formatter<'_> {
         self.buf.write_char(c)
     }
 
+    #[inline]
     fn write_fmt(&mut self, args: Arguments<'_>) -> Result {
-        write(self.buf, args)
+        if let Some(s) = args.as_const_str() {
+            self.buf.write_str(s)
+        } else {
+            write(self.buf, args)
+        }
     }
 }
 
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index f2566fe9bcc..0c69bf2aef9 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -1326,9 +1326,7 @@ impl<T: ?Sized> *const T {
     /// `align`.
     ///
     /// If it is not possible to align the pointer, the implementation returns
-    /// `usize::MAX`. It is permissible for the implementation to *always*
-    /// return `usize::MAX`. Only your algorithm's performance can depend
-    /// on getting a usable offset here, not its correctness.
+    /// `usize::MAX`.
     ///
     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
     /// used with the `wrapping_add` method.
@@ -1337,6 +1335,15 @@ impl<T: ?Sized> *const T {
     /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
     /// the returned offset is correct in all terms other than alignment.
     ///
+    /// When this is called during compile-time evaluation (which is unstable), the implementation
+    /// may return `usize::MAX` in cases where that can never happen at runtime. This is because the
+    /// actual alignment of pointers is not known yet during compile-time, so an offset with
+    /// guaranteed alignment can sometimes not be computed. For example, a buffer declared as `[u8;
+    /// N]` might be allocated at an odd or an even address, but at compile-time this is not yet
+    /// known, so the execution has to be correct for either choice. It is therefore impossible to
+    /// find an offset that is guaranteed to be 2-aligned. (This behavior is subject to change, as usual
+    /// for unstable APIs.)
+    ///
     /// # Panics
     ///
     /// The function panics if `align` is not a power-of-two.
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 2bf486062fe..caa8ffb271d 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -796,6 +796,17 @@ pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T {
 /// let slice = ptr::slice_from_raw_parts(raw_pointer, 3);
 /// assert_eq!(unsafe { &*slice }[2], 7);
 /// ```
+///
+/// You must ensure that the pointer is valid and not null before dereferencing
+/// the raw slice. A slice reference must never have a null pointer, even if it's empty.
+///
+/// ```rust,should_panic
+/// use std::ptr;
+/// let danger: *const [u8] = ptr::slice_from_raw_parts(ptr::null(), 0);
+/// unsafe {
+///     danger.as_ref().expect("references must not be null");
+/// }
+/// ```
 #[inline]
 #[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
 #[rustc_const_stable(feature = "const_slice_from_raw_parts", since = "1.64.0")]
@@ -805,11 +816,13 @@ pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
     from_raw_parts(data.cast(), len)
 }
 
+/// Forms a raw mutable slice from a pointer and a length.
+///
+/// The `len` argument is the number of **elements**, not the number of bytes.
+///
 /// Performs the same functionality as [`slice_from_raw_parts`], except that a
 /// raw mutable slice is returned, as opposed to a raw immutable slice.
 ///
-/// See the documentation of [`slice_from_raw_parts`] for more details.
-///
 /// This function is safe, but actually using the return value is unsafe.
 /// See the documentation of [`slice::from_raw_parts_mut`] for slice safety requirements.
 ///
@@ -830,6 +843,17 @@ pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
 ///
 /// assert_eq!(unsafe { &*slice }[2], 99);
 /// ```
+///
+/// You must ensure that the pointer is valid and not null before dereferencing
+/// the raw slice. A slice reference must never have a null pointer, even if it's empty.
+///
+/// ```rust,should_panic
+/// use std::ptr;
+/// let danger: *mut [u8] = ptr::slice_from_raw_parts_mut(ptr::null_mut(), 0);
+/// unsafe {
+///     danger.as_mut().expect("references must not be null");
+/// }
+/// ```
 #[inline]
 #[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
 #[rustc_const_unstable(feature = "const_slice_from_raw_parts_mut", issue = "67456")]
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 8b0b22a02f2..5ce3b1f298c 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1589,9 +1589,7 @@ impl<T: ?Sized> *mut T {
     /// `align`.
     ///
     /// If it is not possible to align the pointer, the implementation returns
-    /// `usize::MAX`. It is permissible for the implementation to *always*
-    /// return `usize::MAX`. Only your algorithm's performance can depend
-    /// on getting a usable offset here, not its correctness.
+    /// `usize::MAX`.
     ///
     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
     /// used with the `wrapping_add` method.
@@ -1600,6 +1598,15 @@ impl<T: ?Sized> *mut T {
     /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
     /// the returned offset is correct in all terms other than alignment.
     ///
+    /// When this is called during compile-time evaluation (which is unstable), the implementation
+    /// may return `usize::MAX` in cases where that can never happen at runtime. This is because the
+    /// actual alignment of pointers is not known yet during compile-time, so an offset with
+    /// guaranteed alignment can sometimes not be computed. For example, a buffer declared as `[u8;
+    /// N]` might be allocated at an odd or an even address, but at compile-time this is not yet
+    /// known, so the execution has to be correct for either choice. It is therefore impossible to
+    /// find an offset that is guaranteed to be 2-aligned. (This behavior is subject to change, as usual
+    /// for unstable APIs.)
+    ///
     /// # Panics
     ///
     /// The function panics if `align` is not a power-of-two.
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 643b7971a66..2d5e091feaa 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -3786,11 +3786,8 @@ impl<T> [T] {
     /// maintained.
     ///
     /// This method splits the slice into three distinct slices: prefix, correctly aligned middle
-    /// slice of a new type, and the suffix slice. How exactly the slice is split up is not
-    /// specified; the middle part may be smaller than necessary. However, if this fails to return a
-    /// maximal middle part, that is because code is running in a context where performance does not
-    /// matter, such as a sanitizer attempting to find alignment bugs. Regular code running
-    /// in a default (debug or release) execution *will* return a maximal middle part.
+    /// slice of a new type, and the suffix slice. The middle part will be as big as possible under
+    /// the given alignment constraint and element size.
     ///
     /// This method has no purpose when either input element `T` or output element `U` are
     /// zero-sized and will return the original slice without splitting anything.
@@ -3854,11 +3851,8 @@ impl<T> [T] {
     /// types is maintained.
     ///
     /// This method splits the slice into three distinct slices: prefix, correctly aligned middle
-    /// slice of a new type, and the suffix slice. How exactly the slice is split up is not
-    /// specified; the middle part may be smaller than necessary. However, if this fails to return a
-    /// maximal middle part, that is because code is running in a context where performance does not
-    /// matter, such as a sanitizer attempting to find alignment bugs. Regular code running
-    /// in a default (debug or release) execution *will* return a maximal middle part.
+    /// slice of a new type, and the suffix slice. The middle part will be as big as possible under
+    /// the given alignment constraint and element size.
     ///
     /// This method has no purpose when either input element `T` or output element `U` are
     /// zero-sized and will return the original slice without splitting anything.
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 694cc34cdc1..4373a1721e1 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -248,10 +248,10 @@ pub struct DirBuilder {
 ///
 /// ```no_run
 /// use std::fs;
-/// use std::net::SocketAddr;
 ///
 /// fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
-///     let foo: SocketAddr = String::from_utf8_lossy(&fs::read("address.txt")?).parse()?;
+///     let data: Vec<u8> = fs::read("image.jpg")?;
+///     assert_eq!(data[0..3], [0xFF, 0xD8, 0xFF]);
 ///     Ok(())
 /// }
 /// ```
@@ -290,11 +290,11 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
 ///
 /// ```no_run
 /// use std::fs;
-/// use std::net::SocketAddr;
 /// use std::error::Error;
 ///
 /// fn main() -> Result<(), Box<dyn Error>> {
-///     let foo: SocketAddr = fs::read_to_string("address.txt")?.parse()?;
+///     let message: String = fs::read_to_string("message.txt")?;
+///     println!("{}", message);
 ///     Ok(())
 /// }
 /// ```
diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs
index 665d8602c08..2d13230ffba 100644
--- a/library/std/src/io/buffered/bufwriter.rs
+++ b/library/std/src/io/buffered/bufwriter.rs
@@ -554,35 +554,38 @@ impl<W: ?Sized + Write> Write for BufWriter<W> {
             // same underlying buffer, as otherwise the buffers wouldn't fit in memory). If the
             // computation overflows, then surely the input cannot fit in our buffer, so we forward
             // to the inner writer's `write_vectored` method to let it handle it appropriately.
-            let saturated_total_len =
-                bufs.iter().fold(0usize, |acc, b| acc.saturating_add(b.len()));
+            let mut saturated_total_len: usize = 0;
 
-            if saturated_total_len > self.spare_capacity() {
-                // Flush if the total length of the input exceeds our buffer's spare capacity.
-                // If we would have overflowed, this condition also holds, and we need to flush.
-                self.flush_buf()?;
+            for buf in bufs {
+                saturated_total_len = saturated_total_len.saturating_add(buf.len());
+
+                if saturated_total_len > self.spare_capacity() && !self.buf.is_empty() {
+                    // Flush if the total length of the input exceeds our buffer's spare capacity.
+                    // If we would have overflowed, this condition also holds, and we need to flush.
+                    self.flush_buf()?;
+                }
+
+                if saturated_total_len >= self.buf.capacity() {
+                    // Forward to our inner writer if the total length of the input is greater than or
+                    // equal to our buffer capacity. If we would have overflowed, this condition also
+                    // holds, and we punt to the inner writer.
+                    self.panicked = true;
+                    let r = self.get_mut().write_vectored(bufs);
+                    self.panicked = false;
+                    return r;
+                }
             }
 
-            if saturated_total_len >= self.buf.capacity() {
-                // Forward to our inner writer if the total length of the input is greater than or
-                // equal to our buffer capacity. If we would have overflowed, this condition also
-                // holds, and we punt to the inner writer.
-                self.panicked = true;
-                let r = self.get_mut().write_vectored(bufs);
-                self.panicked = false;
-                r
-            } else {
-                // `saturated_total_len < self.buf.capacity()` implies that we did not saturate.
+            // `saturated_total_len < self.buf.capacity()` implies that we did not saturate.
 
-                // SAFETY: We checked whether or not the spare capacity was large enough above. If
-                // it was, then we're safe already. If it wasn't, we flushed, making sufficient
-                // room for any input <= the buffer size, which includes this input.
-                unsafe {
-                    bufs.iter().for_each(|b| self.write_to_buffer_unchecked(b));
-                };
+            // SAFETY: We checked whether or not the spare capacity was large enough above. If
+            // it was, then we're safe already. If it wasn't, we flushed, making sufficient
+            // room for any input <= the buffer size, which includes this input.
+            unsafe {
+                bufs.iter().for_each(|b| self.write_to_buffer_unchecked(b));
+            };
 
-                Ok(saturated_total_len)
-            }
+            Ok(saturated_total_len)
         } else {
             let mut iter = bufs.iter();
             let mut total_written = if let Some(buf) = iter.by_ref().find(|&buf| !buf.is_empty()) {
diff --git a/library/std/src/io/buffered/linewritershim.rs b/library/std/src/io/buffered/linewritershim.rs
index 7eadfd41366..c3ac7855d44 100644
--- a/library/std/src/io/buffered/linewritershim.rs
+++ b/library/std/src/io/buffered/linewritershim.rs
@@ -175,6 +175,10 @@ impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W> {
         }
 
         // Find the buffer containing the last newline
+        // FIXME: This is overly slow if there are very many bufs and none contain
+        // newlines. e.g. writev() on Linux only writes up to 1024 slices, so
+        // scanning the rest is wasted effort. This makes write_all_vectored()
+        // quadratic.
         let last_newline_buf_idx = bufs
             .iter()
             .enumerate()
@@ -215,9 +219,14 @@ impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W> {
 
         // Don't try to reconstruct the exact amount written; just bail
         // in the event of a partial write
-        let lines_len = lines.iter().map(|buf| buf.len()).sum();
-        if flushed < lines_len {
-            return Ok(flushed);
+        let mut lines_len: usize = 0;
+        for buf in lines {
+            // With overlapping/duplicate slices the total length may in theory
+            // exceed usize::MAX
+            lines_len = lines_len.saturating_add(buf.len());
+            if flushed < lines_len {
+                return Ok(flushed);
+            }
         }
 
         // Now that the write has succeeded, buffer the rest (or as much of the
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index 455de6d98ba..42fc0053030 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -128,8 +128,8 @@ impl Write for StdoutRaw {
     }
 
     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        let total = bufs.iter().map(|b| b.len()).sum();
-        handle_ebadf(self.0.write_vectored(bufs), total)
+        let total = || bufs.iter().map(|b| b.len()).sum();
+        handle_ebadf_lazy(self.0.write_vectored(bufs), total)
     }
 
     #[inline]
@@ -160,8 +160,8 @@ impl Write for StderrRaw {
     }
 
     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        let total = bufs.iter().map(|b| b.len()).sum();
-        handle_ebadf(self.0.write_vectored(bufs), total)
+        let total = || bufs.iter().map(|b| b.len()).sum();
+        handle_ebadf_lazy(self.0.write_vectored(bufs), total)
     }
 
     #[inline]
@@ -193,6 +193,13 @@ fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
     }
 }
 
+fn handle_ebadf_lazy<T>(r: io::Result<T>, default: impl FnOnce() -> T) -> io::Result<T> {
+    match r {
+        Err(ref e) if stdio::is_ebadf(e) => Ok(default()),
+        r => r,
+    }
+}
+
 /// A handle to the standard input stream of a process.
 ///
 /// Each handle is a shared reference to a global buffer of input data to this
diff --git a/rustfmt.toml b/rustfmt.toml
index e6cc298ec44..0b0674af8b4 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -37,7 +37,6 @@ ignore = [
     "src/tools/rustfmt",
 
     # these are ignored by a standard cargo fmt run
-    "compiler/rustc_codegen_cranelift/y.rs", # running rustfmt breaks this file
     "compiler/rustc_codegen_cranelift/scripts",
     "compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs", # uses edition 2024
 ]
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 6819508caaa..308e3235370 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -165,6 +165,7 @@ target | std | notes
 `i686-unknown-freebsd` | ✓ | 32-bit FreeBSD [^x86_32-floats-return-ABI]
 `i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 [^x86_32-floats-return-ABI]
 [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | 32-bit UEFI
+[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | ? |  | LoongArch64 Linux (LP64D ABI) with musl 1.2.3
 [`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * |  | LoongArch64 Bare-metal (LP64D ABI)
 [`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * |  | LoongArch64 Bare-metal (LP64S ABI)
 [`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs]
diff --git a/src/doc/unstable-book/src/language-features/asm-goto.md b/src/doc/unstable-book/src/language-features/asm-goto.md
new file mode 100644
index 00000000000..d72eb7c0c6e
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/asm-goto.md
@@ -0,0 +1,30 @@
+# `asm_goto`
+
+The tracking issue for this feature is: [#119364]
+
+[#119364]: https://github.com/rust-lang/rust/issues/119364
+
+------------------------
+
+This feature adds a `label <block>` operand type to `asm!`.
+
+Example:
+```rust,ignore (partial-example, x86-only)
+
+unsafe {
+    asm!(
+        "jmp {}",
+        label {
+            println!("Jumped from asm!");
+        }
+    );
+}
+```
+
+The block must have unit type or diverge.
+
+When `label <block>` is used together with `noreturn` option, it means that the
+assembly will not fallthrough. It's allowed to jump to a label within the
+assembly. In this case, the entire `asm!` expression will have an unit type as
+opposed to diverging, if not all label blocks diverge. The `asm!` expression
+still diverges if `noreturn` option is used and all label blocks diverge.
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 5a28f495381..80a30ac2727 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -314,21 +314,10 @@ pub(crate) fn run_global_ctxt(
     // typeck function bodies or run the default rustc lints.
     // (see `override_queries` in the `config`)
 
-    // HACK(jynelson) this calls an _extremely_ limited subset of `typeck`
-    // and might break if queries change their assumptions in the future.
-    tcx.sess.time("type_collecting", || {
-        tcx.hir().for_each_module(|module| tcx.ensure().collect_mod_item_types(module))
-    });
-
     // NOTE: These are copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
     let _ = tcx.sess.time("wf_checking", || {
         tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
     });
-    tcx.sess.time("item_types_checking", || {
-        tcx.hir().for_each_module(|module| {
-            let _ = tcx.ensure().check_mod_type_wf(module);
-        });
-    });
 
     if let Some(guar) = tcx.dcx().has_errors() {
         return Err(guar);
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index 245a903f998..65d922f03df 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -255,6 +255,9 @@ fn never_loop_expr<'tcx>(
             InlineAsmOperand::Const { .. } | InlineAsmOperand::SymFn { .. } | InlineAsmOperand::SymStatic { .. } => {
                 NeverLoopResult::Normal
             },
+            InlineAsmOperand::Label { block } => {
+                never_loop_block(cx, block, local_labels, main_loop_id)
+            }
         })),
         ExprKind::OffsetOf(_, _)
         | ExprKind::Yield(_, _)
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index ef61b303f9c..f7f5f7ca35f 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -833,6 +833,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                             self.hash_body(anon_const.body);
                         },
                         InlineAsmOperand::SymStatic { path, def_id: _ } => self.hash_qpath(path),
+                        InlineAsmOperand::Label { block } => self.hash_block(block),
                     }
                 }
             },
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 22108df0f26..fc54baf1a67 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -341,6 +341,8 @@ fn main() {
     // (`install_ice_hook` might change `RUST_BACKTRACE`.)
     let env_snapshot = env::vars_os().collect::<Vec<_>>();
 
+    let args = rustc_driver::args::raw_args(&early_dcx).unwrap_or_else(|_| std::process::exit(rustc_driver::EXIT_FAILURE));
+
     // If the environment asks us to actually be rustc, then do that.
     if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") {
         // Earliest rustc setup.
@@ -358,7 +360,7 @@ fn main() {
 
         // We cannot use `rustc_driver::main` as we need to adjust the CLI arguments.
         run_compiler(
-            env::args().collect(),
+            args,
             target_crate,
             &mut MiriBeRustCompilerCalls { target_crate },
             using_internal_features,
@@ -381,7 +383,7 @@ fn main() {
 
     // If user has explicitly enabled/disabled isolation
     let mut isolation_enabled: Option<bool> = None;
-    for arg in env::args() {
+    for arg in args {
         if rustc_args.is_empty() {
             // Very first arg: binary name.
             rustc_args.push(arg);
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 490fa6f5535..f2dc6c14058 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -8,7 +8,6 @@ use std::fmt;
 use std::path::Path;
 use std::process;
 
-use either::Either;
 use rand::rngs::StdRng;
 use rand::Rng;
 use rand::SeedableRng;
@@ -957,7 +956,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
             // to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
             // foreign function
             // Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
-            let args = ecx.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
+            let args = ecx.copy_fn_args(args); // FIXME: Should `InPlace` arguments be reset to uninit?
             let link_name = ecx.item_link_name(instance.def_id());
             return ecx.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind);
         }
@@ -976,7 +975,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
         ret: Option<mir::BasicBlock>,
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx> {
-        let args = ecx.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
+        let args = ecx.copy_fn_args(args); // FIXME: Should `InPlace` arguments be reset to uninit?
         ecx.emulate_dyn_sym(fn_val, abi, &args, dest, ret, unwind)
     }
 
@@ -1329,18 +1328,12 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
 
     fn protect_in_place_function_argument(
         ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        place: &PlaceTy<'tcx, Provenance>,
+        place: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx> {
         // If we have a borrow tracker, we also have it set up protection so that all reads *and
         // writes* during this call are insta-UB.
         let protected_place = if ecx.machine.borrow_tracker.is_some() {
-            // Have to do `to_op` first because a `Place::Local` doesn't imply the local doesn't have an address.
-            if let Either::Left(place) = ecx.place_to_op(place)?.as_mplace_or_imm() {
-                ecx.protect_place(&place)?.into()
-            } else {
-                // Locals that don't have their address taken are as protected as they can ever be.
-                place.clone()
-            }
+            ecx.protect_place(&place)?.into()
         } else {
             // No borrow tracker.
             place.clone()
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index cd3976ea657..91bbf5041ff 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -183,8 +183,8 @@
 "ui/async-await/issue-67651.rs",
 "ui/async-await/issue-67765-async-diagnostic.rs",
 "ui/async-await/issue-68112.rs",
-"ui/async-await/issue-68523.rs",
 "ui/async-await/issue-68523-start.rs",
+"ui/async-await/issue-68523.rs",
 "ui/async-await/issue-69446-fnmut-capture.rs",
 "ui/async-await/issue-70594.rs",
 "ui/async-await/issue-70818.rs",
@@ -342,8 +342,8 @@
 "ui/borrowck/issue-52967-edition-2018-needs-two-phase-borrows.rs",
 "ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.rs",
 "ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs",
-"ui/borrowck/issue-54499-field-mutation-of-moved-out.rs",
 "ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs",
+"ui/borrowck/issue-54499-field-mutation-of-moved-out.rs",
 "ui/borrowck/issue-54499-field-mutation-of-never-init.rs",
 "ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs",
 "ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs",
@@ -360,9 +360,9 @@
 "ui/borrowck/issue-71546.rs",
 "ui/borrowck/issue-7573.rs",
 "ui/borrowck/issue-80772.rs",
+"ui/borrowck/issue-81365-1.rs",
 "ui/borrowck/issue-81365-10.rs",
 "ui/borrowck/issue-81365-11.rs",
-"ui/borrowck/issue-81365-1.rs",
 "ui/borrowck/issue-81365-2.rs",
 "ui/borrowck/issue-81365-3.rs",
 "ui/borrowck/issue-81365-4.rs",
@@ -392,6 +392,9 @@
 "ui/borrowck/issue-95079-missing-move-in-nested-closure.rs",
 "ui/box/issue-82446.rs",
 "ui/box/issue-95036.rs",
+"ui/c-variadic/issue-32201.rs",
+"ui/c-variadic/issue-86053-1.rs",
+"ui/c-variadic/issue-86053-2.rs",
 "ui/cast/issue-106883-is-empty.rs",
 "ui/cast/issue-10991.rs",
 "ui/cast/issue-17444.rs",
@@ -399,19 +402,19 @@
 "ui/cast/issue-85586.rs",
 "ui/cast/issue-88621.rs",
 "ui/cast/issue-89497.rs",
+"ui/closure-expected-type/issue-24421.rs",
 "ui/closure_context/issue-26046-fn-mut.rs",
 "ui/closure_context/issue-26046-fn-once.rs",
 "ui/closure_context/issue-42065.rs",
-"ui/closure-expected-type/issue-24421.rs",
 "ui/closures/2229_closure_analysis/issue-118144.rs",
 "ui/closures/2229_closure_analysis/issue-87378.rs",
 "ui/closures/2229_closure_analysis/issue-87987.rs",
 "ui/closures/2229_closure_analysis/issue-88118-2.rs",
-"ui/closures/2229_closure_analysis/issue_88118.rs",
 "ui/closures/2229_closure_analysis/issue-88476.rs",
 "ui/closures/2229_closure_analysis/issue-89606.rs",
 "ui/closures/2229_closure_analysis/issue-90465.rs",
 "ui/closures/2229_closure_analysis/issue-92724-needsdrop-query-cycle.rs",
+"ui/closures/2229_closure_analysis/issue_88118.rs",
 "ui/closures/2229_closure_analysis/match/issue-87097.rs",
 "ui/closures/2229_closure_analysis/match/issue-87426.rs",
 "ui/closures/2229_closure_analysis/match/issue-87988.rs",
@@ -644,8 +647,8 @@
 "ui/const-generics/issues/issue-99641.rs",
 "ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs",
 "ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs",
-"ui/const-generics/parser-error-recovery/issue-89013.rs",
 "ui/const-generics/parser-error-recovery/issue-89013-type.rs",
+"ui/const-generics/parser-error-recovery/issue-89013.rs",
 "ui/const-generics/type-dependent/issue-61936.rs",
 "ui/const-generics/type-dependent/issue-63695.rs",
 "ui/const-generics/type-dependent/issue-67144-1.rs",
@@ -689,13 +692,13 @@
 "ui/consts/const-eval/issue-91827-extern-types-field-offset.rs",
 "ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs",
 "ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs",
+"ui/consts/const-mut-refs/issue-76510.rs",
 "ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.rs",
 "ui/consts/const_in_pattern/issue-44333.rs",
 "ui/consts/const_in_pattern/issue-53708.rs",
 "ui/consts/const_in_pattern/issue-62614.rs",
 "ui/consts/const_in_pattern/issue-65466.rs",
 "ui/consts/const_in_pattern/issue-73431.rs",
-"ui/consts/const-mut-refs/issue-76510.rs",
 "ui/consts/control-flow/issue-46843.rs",
 "ui/consts/control-flow/issue-50577.rs",
 "ui/consts/extra-const-ub/issue-100771.rs",
@@ -714,9 +717,9 @@
 "ui/consts/issue-17074.rs",
 "ui/consts/issue-17458.rs",
 "ui/consts/issue-17718-borrow-interior.rs",
-"ui/consts/issue-17718-constants-not-static.rs",
 "ui/consts/issue-17718-const-bad-values.rs",
 "ui/consts/issue-17718-const-borrow.rs",
+"ui/consts/issue-17718-constants-not-static.rs",
 "ui/consts/issue-17718-references.rs",
 "ui/consts/issue-17718.rs",
 "ui/consts/issue-17756.rs",
@@ -841,9 +844,6 @@
 "ui/coroutine/issue-91477.rs",
 "ui/coroutine/issue-93161.rs",
 "ui/cross-crate/issue-64872/issue-64872.rs",
-"ui/c-variadic/issue-32201.rs",
-"ui/c-variadic/issue-86053-1.rs",
-"ui/c-variadic/issue-86053-2.rs",
 "ui/cycle-trait/issue-12511.rs",
 "ui/debuginfo/issue-105386-debuginfo-ub.rs",
 "ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs",
@@ -902,15 +902,6 @@
 "ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs",
 "ui/did_you_mean/issue-87830-try-brackets-for-arrays.rs",
 "ui/drop/auxiliary/issue-10028.rs",
-"ui/dropck/issue-24805-dropck-itemless.rs",
-"ui/dropck/issue-28498-ugeh-with-lifetime-param.rs",
-"ui/dropck/issue-28498-ugeh-with-passed-to-fn.rs",
-"ui/dropck/issue-28498-ugeh-with-trait-bound.rs",
-"ui/dropck/issue-29844.rs",
-"ui/dropck/issue-34053.rs",
-"ui/dropck/issue-38868.rs",
-"ui/dropck/issue-54943-1.rs",
-"ui/dropck/issue-54943-2.rs",
 "ui/drop/issue-100276.rs",
 "ui/drop/issue-10028.rs",
 "ui/drop/issue-103107.rs",
@@ -929,6 +920,15 @@
 "ui/drop/issue-90752-raw-ptr-shenanigans.rs",
 "ui/drop/issue-90752.rs",
 "ui/drop/issue-979.rs",
+"ui/dropck/issue-24805-dropck-itemless.rs",
+"ui/dropck/issue-28498-ugeh-with-lifetime-param.rs",
+"ui/dropck/issue-28498-ugeh-with-passed-to-fn.rs",
+"ui/dropck/issue-28498-ugeh-with-trait-bound.rs",
+"ui/dropck/issue-29844.rs",
+"ui/dropck/issue-34053.rs",
+"ui/dropck/issue-38868.rs",
+"ui/dropck/issue-54943-1.rs",
+"ui/dropck/issue-54943-2.rs",
 "ui/dst/issue-113447.rs",
 "ui/dst/issue-90528-unsizing-not-suggestion-110063.rs",
 "ui/dst/issue-90528-unsizing-suggestion-1.rs",
@@ -1014,14 +1014,14 @@
 "ui/fn/issue-3904.rs",
 "ui/fn/issue-39259.rs",
 "ui/fn/issue-80179.rs",
-"ui/foreign/issue-74120-lowering-of-ffi-block-bodies.rs",
-"ui/foreign/issue-91370-foreign-fn-block-impl.rs",
-"ui/foreign/issue-99276-same-type-lifetimes.rs",
-"ui/for/issue-20605.rs",
 "ui/for-loop-while/issue-1257.rs",
 "ui/for-loop-while/issue-2216.rs",
 "ui/for-loop-while/issue-51345.rs",
 "ui/for-loop-while/issue-69841.rs",
+"ui/for/issue-20605.rs",
+"ui/foreign/issue-74120-lowering-of-ffi-block-bodies.rs",
+"ui/foreign/issue-91370-foreign-fn-block-impl.rs",
+"ui/foreign/issue-99276-same-type-lifetimes.rs",
 "ui/function-pointer/issue-102289.rs",
 "ui/functions-closures/closure-expected-type/issue-38714.rs",
 "ui/generic-associated-types/bugs/issue-100013.rs",
@@ -1084,8 +1084,8 @@
 "ui/generic-associated-types/issue-87258_b.rs",
 "ui/generic-associated-types/issue-87429-2.rs",
 "ui/generic-associated-types/issue-87429-associated-type-default.rs",
-"ui/generic-associated-types/issue-87429.rs",
 "ui/generic-associated-types/issue-87429-specialization.rs",
+"ui/generic-associated-types/issue-87429.rs",
 "ui/generic-associated-types/issue-87748.rs",
 "ui/generic-associated-types/issue-87750.rs",
 "ui/generic-associated-types/issue-88287.rs",
@@ -1095,9 +1095,9 @@
 "ui/generic-associated-types/issue-88595.rs",
 "ui/generic-associated-types/issue-89008.rs",
 "ui/generic-associated-types/issue-89352.rs",
-"ui/generic-associated-types/issue-90014.rs",
-"ui/generic-associated-types/issue-90014-tait2.rs",
 "ui/generic-associated-types/issue-90014-tait.rs",
+"ui/generic-associated-types/issue-90014-tait2.rs",
+"ui/generic-associated-types/issue-90014.rs",
 "ui/generic-associated-types/issue-90729.rs",
 "ui/generic-associated-types/issue-91139.rs",
 "ui/generic-associated-types/issue-91883.rs",
@@ -1119,8 +1119,8 @@
 "ui/generics/issue-333.rs",
 "ui/generics/issue-59508-1.rs",
 "ui/generics/issue-59508.rs",
-"ui/generics/issue-61631-default-type-param-cannot-reference-self.rs",
 "ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.rs",
+"ui/generics/issue-61631-default-type-param-cannot-reference-self.rs",
 "ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs",
 "ui/generics/issue-79605.rs",
 "ui/generics/issue-80512-param-reordering-with-defaults.rs",
@@ -1179,9 +1179,6 @@
 "ui/hygiene/issue-47312.rs",
 "ui/hygiene/issue-61574-const-parameters.rs",
 "ui/hygiene/issue-77523-def-site-async-await.rs",
-"ui/implied-bounds/issue-100690.rs",
-"ui/implied-bounds/issue-101951.rs",
-"ui/implied-bounds/issue-110161.rs",
 "ui/impl-trait/explicit-generic-args-with-impl-trait/issue-87718.rs",
 "ui/impl-trait/in-trait/issue-102140.rs",
 "ui/impl-trait/in-trait/issue-102301.rs",
@@ -1261,6 +1258,9 @@
 "ui/impl-trait/issues/issue-92305.rs",
 "ui/impl-trait/issues/issue-93788.rs",
 "ui/impl-trait/issues/issue-99348-impl-compatibility.rs",
+"ui/implied-bounds/issue-100690.rs",
+"ui/implied-bounds/issue-101951.rs",
+"ui/implied-bounds/issue-110161.rs",
 "ui/imports/auxiliary/issue-114682-2-extern.rs",
 "ui/imports/auxiliary/issue-114682-3-extern.rs",
 "ui/imports/auxiliary/issue-114682-4-extern.rs",
@@ -1368,8 +1368,8 @@
 "ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.rs",
 "ui/inference/need_type_info/issue-109905.rs",
 "ui/inference/need_type_info/issue-113264-incorrect-impl-trait-in-path-suggestion.rs",
-"ui/infinite/issue-41731-infinite-macro-println.rs",
 "ui/infinite/issue-41731-infinite-macro-print.rs",
+"ui/infinite/issue-41731-infinite-macro-println.rs",
 "ui/intrinsics/issue-28575.rs",
 "ui/intrinsics/issue-84297-reifying-copy.rs",
 "ui/invalid/issue-114435-layout-type-err.rs",
@@ -1386,8 +1386,8 @@
 "ui/issues/auxiliary/issue-11508.rs",
 "ui/issues/auxiliary/issue-11529.rs",
 "ui/issues/auxiliary/issue-11680.rs",
-"ui/issues/auxiliary/issue-12133-dylib2.rs",
 "ui/issues/auxiliary/issue-12133-dylib.rs",
+"ui/issues/auxiliary/issue-12133-dylib2.rs",
 "ui/issues/auxiliary/issue-12133-rlib.rs",
 "ui/issues/auxiliary/issue-12612-1.rs",
 "ui/issues/auxiliary/issue-12612-2.rs",
@@ -1554,8 +1554,8 @@
 "ui/issues/issue-13497-2.rs",
 "ui/issues/issue-13497.rs",
 "ui/issues/issue-13507-2.rs",
-"ui/issues/issue-13620.rs",
 "ui/issues/issue-1362.rs",
+"ui/issues/issue-13620.rs",
 "ui/issues/issue-13665.rs",
 "ui/issues/issue-13703.rs",
 "ui/issues/issue-13763.rs",
@@ -1649,8 +1649,8 @@
 "ui/issues/issue-16819.rs",
 "ui/issues/issue-16922-rpass.rs",
 "ui/issues/issue-16939.rs",
-"ui/issues/issue-16966.rs",
 "ui/issues/issue-1696.rs",
+"ui/issues/issue-16966.rs",
 "ui/issues/issue-16994.rs",
 "ui/issues/issue-17001.rs",
 "ui/issues/issue-17033.rs",
@@ -1729,8 +1729,8 @@
 "ui/issues/issue-18952.rs",
 "ui/issues/issue-18959.rs",
 "ui/issues/issue-18988.rs",
-"ui/issues/issue-19001.rs",
 "ui/issues/issue-1900.rs",
+"ui/issues/issue-19001.rs",
 "ui/issues/issue-19037.rs",
 "ui/issues/issue-19086.rs",
 "ui/issues/issue-19097.rs",
@@ -1826,8 +1826,8 @@
 "ui/issues/issue-21622.rs",
 "ui/issues/issue-21634.rs",
 "ui/issues/issue-21655.rs",
-"ui/issues/issue-21701.rs",
 "ui/issues/issue-2170-exe.rs",
+"ui/issues/issue-21701.rs",
 "ui/issues/issue-21763.rs",
 "ui/issues/issue-21891.rs",
 "ui/issues/issue-2190-1.rs",
@@ -1863,15 +1863,15 @@
 "ui/issues/issue-22777.rs",
 "ui/issues/issue-22781.rs",
 "ui/issues/issue-22789.rs",
-"ui/issues/issue-22814.rs",
 "ui/issues/issue-2281-part1.rs",
+"ui/issues/issue-22814.rs",
 "ui/issues/issue-2284.rs",
 "ui/issues/issue-22864-1.rs",
 "ui/issues/issue-22864-2.rs",
 "ui/issues/issue-22872.rs",
 "ui/issues/issue-22874.rs",
-"ui/issues/issue-22886.rs",
 "ui/issues/issue-2288.rs",
+"ui/issues/issue-22886.rs",
 "ui/issues/issue-22894.rs",
 "ui/issues/issue-22933-1.rs",
 "ui/issues/issue-22933-2.rs",
@@ -1884,9 +1884,9 @@
 "ui/issues/issue-23073.rs",
 "ui/issues/issue-2311-2.rs",
 "ui/issues/issue-2311.rs",
+"ui/issues/issue-2312.rs",
 "ui/issues/issue-23122-1.rs",
 "ui/issues/issue-23122-2.rs",
-"ui/issues/issue-2312.rs",
 "ui/issues/issue-2316-c.rs",
 "ui/issues/issue-23173.rs",
 "ui/issues/issue-23189.rs",
@@ -1917,8 +1917,8 @@
 "ui/issues/issue-23649-2.rs",
 "ui/issues/issue-23649-3.rs",
 "ui/issues/issue-23699.rs",
-"ui/issues/issue-23808.rs",
 "ui/issues/issue-2380-b.rs",
+"ui/issues/issue-23808.rs",
 "ui/issues/issue-2383.rs",
 "ui/issues/issue-23891.rs",
 "ui/issues/issue-23898.rs",
@@ -1981,8 +1981,8 @@
 "ui/issues/issue-25746-bool-transmute.rs",
 "ui/issues/issue-25757.rs",
 "ui/issues/issue-25810.rs",
-"ui/issues/issue-25901.rs",
 "ui/issues/issue-2590.rs",
+"ui/issues/issue-25901.rs",
 "ui/issues/issue-26056.rs",
 "ui/issues/issue-26093.rs",
 "ui/issues/issue-26095.rs",
@@ -2041,10 +2041,10 @@
 "ui/issues/issue-28433.rs",
 "ui/issues/issue-28472.rs",
 "ui/issues/issue-2848.rs",
+"ui/issues/issue-2849.rs",
 "ui/issues/issue-28498-must-work-ex1.rs",
 "ui/issues/issue-28498-must-work-ex2.rs",
 "ui/issues/issue-28498-ugeh-ex1.rs",
-"ui/issues/issue-2849.rs",
 "ui/issues/issue-28550.rs",
 "ui/issues/issue-28561.rs",
 "ui/issues/issue-28568.rs",
@@ -2062,8 +2062,8 @@
 "ui/issues/issue-28999.rs",
 "ui/issues/issue-29030.rs",
 "ui/issues/issue-29037.rs",
-"ui/issues/issue-29048.rs",
 "ui/issues/issue-2904.rs",
+"ui/issues/issue-29048.rs",
 "ui/issues/issue-29053.rs",
 "ui/issues/issue-29071-2.rs",
 "ui/issues/issue-29071.rs",
@@ -2075,8 +2075,8 @@
 "ui/issues/issue-2935.rs",
 "ui/issues/issue-29466.rs",
 "ui/issues/issue-29485.rs",
-"ui/issues/issue-29516.rs",
 "ui/issues/issue-2951.rs",
+"ui/issues/issue-29516.rs",
 "ui/issues/issue-29522.rs",
 "ui/issues/issue-29540.rs",
 "ui/issues/issue-29663.rs",
@@ -2101,10 +2101,10 @@
 "ui/issues/issue-30255.rs",
 "ui/issues/issue-3026.rs",
 "ui/issues/issue-3029.rs",
-"ui/issues/issue-30371.rs",
 "ui/issues/issue-3037.rs",
-"ui/issues/issue-30380.rs",
+"ui/issues/issue-30371.rs",
 "ui/issues/issue-3038.rs",
+"ui/issues/issue-30380.rs",
 "ui/issues/issue-3052.rs",
 "ui/issues/issue-30530.rs",
 "ui/issues/issue-30589.rs",
@@ -2226,8 +2226,8 @@
 "ui/issues/issue-37131.rs",
 "ui/issues/issue-37311-type-length-limit/issue-37311.rs",
 "ui/issues/issue-37510.rs",
-"ui/issues/issue-37534.rs",
 "ui/issues/issue-3753.rs",
+"ui/issues/issue-37534.rs",
 "ui/issues/issue-37576.rs",
 "ui/issues/issue-3763.rs",
 "ui/issues/issue-37665.rs",
@@ -2254,8 +2254,8 @@
 "ui/issues/issue-3888-2.rs",
 "ui/issues/issue-38919.rs",
 "ui/issues/issue-38942.rs",
-"ui/issues/issue-38954.rs",
 "ui/issues/issue-3895.rs",
+"ui/issues/issue-38954.rs",
 "ui/issues/issue-38987.rs",
 "ui/issues/issue-39089.rs",
 "ui/issues/issue-39175.rs",
@@ -2265,8 +2265,8 @@
 "ui/issues/issue-39687.rs",
 "ui/issues/issue-39709.rs",
 "ui/issues/issue-3979-2.rs",
-"ui/issues/issue-3979.rs",
 "ui/issues/issue-3979-xcrate.rs",
+"ui/issues/issue-3979.rs",
 "ui/issues/issue-39808.rs",
 "ui/issues/issue-39827.rs",
 "ui/issues/issue-39848.rs",
@@ -2341,9 +2341,9 @@
 "ui/issues/issue-43250.rs",
 "ui/issues/issue-43291.rs",
 "ui/issues/issue-4333.rs",
+"ui/issues/issue-4335.rs",
 "ui/issues/issue-43355.rs",
 "ui/issues/issue-43357.rs",
-"ui/issues/issue-4335.rs",
 "ui/issues/issue-43420-no-over-suggest.rs",
 "ui/issues/issue-43424.rs",
 "ui/issues/issue-43431.rs",
@@ -2372,8 +2372,8 @@
 "ui/issues/issue-44851.rs",
 "ui/issues/issue-4517.rs",
 "ui/issues/issue-4541.rs",
-"ui/issues/issue-45425.rs",
 "ui/issues/issue-4542.rs",
+"ui/issues/issue-45425.rs",
 "ui/issues/issue-4545.rs",
 "ui/issues/issue-45510.rs",
 "ui/issues/issue-45562.rs",
@@ -2402,8 +2402,8 @@
 "ui/issues/issue-47309.rs",
 "ui/issues/issue-4734.rs",
 "ui/issues/issue-4735.rs",
-"ui/issues/issue-47364.rs",
 "ui/issues/issue-4736.rs",
+"ui/issues/issue-47364.rs",
 "ui/issues/issue-47377.rs",
 "ui/issues/issue-47380.rs",
 "ui/issues/issue-47486.rs",
@@ -2412,8 +2412,8 @@
 "ui/issues/issue-47638.rs",
 "ui/issues/issue-47673.rs",
 "ui/issues/issue-47703-1.rs",
-"ui/issues/issue-47703.rs",
 "ui/issues/issue-47703-tuple.rs",
+"ui/issues/issue-47703.rs",
 "ui/issues/issue-47715.rs",
 "ui/issues/issue-47722.rs",
 "ui/issues/issue-48006.rs",
@@ -2561,8 +2561,8 @@
 "ui/issues/issue-59756.rs",
 "ui/issues/issue-5988.rs",
 "ui/issues/issue-5997-outer-generic-parameter/issue-5997-enum.rs",
-"ui/issues/issue-5997-outer-generic-parameter/issue-5997.rs",
 "ui/issues/issue-5997-outer-generic-parameter/issue-5997-struct.rs",
+"ui/issues/issue-5997-outer-generic-parameter/issue-5997.rs",
 "ui/issues/issue-60218.rs",
 "ui/issues/issue-60622.rs",
 "ui/issues/issue-60989.rs",
@@ -2837,8 +2837,8 @@
 "ui/lint/unused/issue-103320-must-use-ops.rs",
 "ui/lint/unused/issue-104397.rs",
 "ui/lint/unused/issue-105061-array-lint.rs",
-"ui/lint/unused/issue-105061.rs",
 "ui/lint/unused/issue-105061-should-lint.rs",
+"ui/lint/unused/issue-105061.rs",
 "ui/lint/unused/issue-117142-invalid-remove-parens.rs",
 "ui/lint/unused/issue-117284-arg-in-macro.rs",
 "ui/lint/unused/issue-119383-if-let-guard.rs",
@@ -2862,8 +2862,8 @@
 "ui/lint/use-redundant/issue-92904.rs",
 "ui/loops/issue-43162.rs",
 "ui/loops/issue-50576.rs",
-"ui/loops/issue-69225-layout-repeated-checked-add.rs",
 "ui/loops/issue-69225-SCEVAddExpr-wrap-flag.rs",
+"ui/loops/issue-69225-layout-repeated-checked-add.rs",
 "ui/loops/issue-82916.rs",
 "ui/lowering/issue-121108.rs",
 "ui/lowering/issue-96847.rs",
@@ -3016,7 +3016,6 @@
 "ui/mir/issue-29227.rs",
 "ui/mir/issue-46845.rs",
 "ui/mir/issue-60390.rs",
-"ui/mir/issue66339.rs",
 "ui/mir/issue-66851.rs",
 "ui/mir/issue-66930.rs",
 "ui/mir/issue-67639-normalization-ice.rs",
@@ -3043,6 +3042,7 @@
 "ui/mir/issue-92893.rs",
 "ui/mir/issue-99852.rs",
 "ui/mir/issue-99866.rs",
+"ui/mir/issue66339.rs",
 "ui/mir/validate/issue-95978-validator-lifetime-comparison.rs",
 "ui/mismatched_types/issue-106182.rs",
 "ui/mismatched_types/issue-112036.rs",
@@ -3053,10 +3053,10 @@
 "ui/mismatched_types/issue-26480.rs",
 "ui/mismatched_types/issue-35030.rs",
 "ui/mismatched_types/issue-36053-2.rs",
-"ui/mismatched_types/issue-38371.rs",
 "ui/mismatched_types/issue-38371-unfixable.rs",
-"ui/mismatched_types/issue-47706.rs",
+"ui/mismatched_types/issue-38371.rs",
 "ui/mismatched_types/issue-47706-trait.rs",
+"ui/mismatched_types/issue-47706.rs",
 "ui/mismatched_types/issue-74918-missing-lifetime.rs",
 "ui/mismatched_types/issue-75361-mismatched-impl.rs",
 "ui/mismatched_types/issue-84976.rs",
@@ -3414,8 +3414,8 @@
 "ui/parser/issues/issue-73568-lifetime-after-mut.rs",
 "ui/parser/issues/issue-75599.rs",
 "ui/parser/issues/issue-76437-async.rs",
-"ui/parser/issues/issue-76437-const-async.rs",
 "ui/parser/issues/issue-76437-const-async-unsafe.rs",
+"ui/parser/issues/issue-76437-const-async.rs",
 "ui/parser/issues/issue-76437-const.rs",
 "ui/parser/issues/issue-76437-pub-crate-unsafe.rs",
 "ui/parser/issues/issue-76437-unsafe.rs",
@@ -3561,16 +3561,10 @@
 "ui/privacy/issue-57264-2.rs",
 "ui/privacy/issue-75062-fieldless-tuple-struct.rs",
 "ui/privacy/issue-75906.rs",
-"ui/privacy/issue-75907_b.rs",
 "ui/privacy/issue-75907.rs",
+"ui/privacy/issue-75907_b.rs",
 "ui/privacy/issue-79593.rs",
 "ui/privacy/issue-92755.rs",
-"ui/process/issue-13304.rs",
-"ui/process/issue-14456.rs",
-"ui/process/issue-14940.rs",
-"ui/process/issue-16272.rs",
-"ui/process/issue-20091.rs",
-"ui/process/issue-30490.rs",
 "ui/proc-macro/auxiliary/issue-104884.rs",
 "ui/proc-macro/auxiliary/issue-107113.rs",
 "ui/proc-macro/auxiliary/issue-118809.rs",
@@ -3619,8 +3613,14 @@
 "ui/proc-macro/issue-86781-bad-inner-doc.rs",
 "ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.rs",
 "ui/proc-macro/issue-91800.rs",
-"ui/ptr_ops/issue-80309.rs",
+"ui/process/issue-13304.rs",
+"ui/process/issue-14456.rs",
+"ui/process/issue-14940.rs",
+"ui/process/issue-16272.rs",
+"ui/process/issue-20091.rs",
+"ui/process/issue-30490.rs",
 "ui/ptr_ops/issue-80309-safe.rs",
+"ui/ptr_ops/issue-80309.rs",
 "ui/pub/issue-33174-restricted-type-in-public-interface.rs",
 "ui/query-system/issue-83479.rs",
 "ui/range/issue-54505-no-literals.rs",
@@ -3698,8 +3698,8 @@
 "ui/resolve/issue-21221-3.rs",
 "ui/resolve/issue-21221-4.rs",
 "ui/resolve/issue-22692.rs",
-"ui/resolve/issue-23305.rs",
 "ui/resolve/issue-2330.rs",
+"ui/resolve/issue-23305.rs",
 "ui/resolve/issue-2356.rs",
 "ui/resolve/issue-23716.rs",
 "ui/resolve/issue-24968.rs",
@@ -3820,10 +3820,6 @@
 "ui/span/issue-25199.rs",
 "ui/span/issue-26656.rs",
 "ui/span/issue-27522.rs",
-"ui/span/issue28498-reject-ex1.rs",
-"ui/span/issue28498-reject-lifetime-param.rs",
-"ui/span/issue28498-reject-passed-to-fn.rs",
-"ui/span/issue28498-reject-trait-bound.rs",
 "ui/span/issue-29106.rs",
 "ui/span/issue-29595.rs",
 "ui/span/issue-33884.rs",
@@ -3838,6 +3834,10 @@
 "ui/span/issue-43927-non-ADT-derive.rs",
 "ui/span/issue-71363.rs",
 "ui/span/issue-81800.rs",
+"ui/span/issue28498-reject-ex1.rs",
+"ui/span/issue28498-reject-lifetime-param.rs",
+"ui/span/issue28498-reject-passed-to-fn.rs",
+"ui/span/issue28498-reject-trait-bound.rs",
 "ui/specialization/issue-111232.rs",
 "ui/specialization/issue-33017.rs",
 "ui/specialization/issue-35376.rs",
@@ -4124,8 +4124,8 @@
 "ui/traits/object/issue-44454-3.rs",
 "ui/traits/suggest-dereferences/issue-39029.rs",
 "ui/traits/suggest-dereferences/issue-62530.rs",
-"ui/traits/trait-upcasting/issue-11515.rs",
 "ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs",
+"ui/traits/trait-upcasting/issue-11515.rs",
 "ui/traits/vtable/issue-91807.rs",
 "ui/traits/vtable/issue-97381.rs",
 "ui/transmutability/arrays/issue-103783-array-length.rs",
@@ -4163,8 +4163,8 @@
 "ui/type-alias-impl-trait/issue-58951.rs",
 "ui/type-alias-impl-trait/issue-60371.rs",
 "ui/type-alias-impl-trait/issue-60407.rs",
-"ui/type-alias-impl-trait/issue-60564.rs",
 "ui/type-alias-impl-trait/issue-60564-working.rs",
+"ui/type-alias-impl-trait/issue-60564.rs",
 "ui/type-alias-impl-trait/issue-60662.rs",
 "ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs",
 "ui/type-alias-impl-trait/issue-63263-closure-return.rs",
@@ -4208,10 +4208,26 @@
 "ui/type-alias/issue-62263-self-in-atb.rs",
 "ui/type-alias/issue-62305-self-assoc-ty.rs",
 "ui/type-alias/issue-62364-self-ty-arg.rs",
+"ui/type-inference/issue-113283-alllocator-trait-eq.rs",
+"ui/type-inference/issue-30225.rs",
 "ui/type/ascription/issue-34255-1.rs",
 "ui/type/ascription/issue-47666.rs",
 "ui/type/ascription/issue-54516.rs",
 "ui/type/ascription/issue-60933.rs",
+"ui/type/issue-100584.rs",
+"ui/type/issue-101866.rs",
+"ui/type/issue-102598.rs",
+"ui/type/issue-103271.rs",
+"ui/type/issue-58355.rs",
+"ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs",
+"ui/type/issue-91268.rs",
+"ui/type/issue-94187-verbose-type-name.rs",
+"ui/type/type-check/issue-116967-cannot-coerce-returned-result.rs",
+"ui/type/type-check/issue-22897.rs",
+"ui/type/type-check/issue-40294.rs",
+"ui/type/type-check/issue-41314.rs",
+"ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs",
+"ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs",
 "ui/typeck/auxiliary/issue-29181.rs",
 "ui/typeck/auxiliary/issue-36708.rs",
 "ui/typeck/auxiliary/issue-81943-lib.rs",
@@ -4316,25 +4332,9 @@
 "ui/typeck/issue-96738.rs",
 "ui/typeck/issue-98260.rs",
 "ui/typeck/issue-98982.rs",
-"ui/type-inference/issue-113283-alllocator-trait-eq.rs",
-"ui/type-inference/issue-30225.rs",
-"ui/type/issue-100584.rs",
-"ui/type/issue-101866.rs",
-"ui/type/issue-102598.rs",
-"ui/type/issue-103271.rs",
-"ui/type/issue-58355.rs",
-"ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs",
-"ui/type/issue-91268.rs",
-"ui/type/issue-94187-verbose-type-name.rs",
 "ui/typeof/issue-100183.rs",
 "ui/typeof/issue-29184.rs",
 "ui/typeof/issue-42060.rs",
-"ui/type/type-check/issue-116967-cannot-coerce-returned-result.rs",
-"ui/type/type-check/issue-22897.rs",
-"ui/type/type-check/issue-40294.rs",
-"ui/type/type-check/issue-41314.rs",
-"ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs",
-"ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs",
 "ui/unboxed-closures/issue-18652.rs",
 "ui/unboxed-closures/issue-18661.rs",
 "ui/unboxed-closures/issue-30906.rs",
@@ -4355,6 +4355,11 @@
 "ui/unsafe/issue-47412.rs",
 "ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs",
 "ui/unsafe/issue-87414-query-cycle.rs",
+"ui/unsized-locals/issue-30276-feature-flagged.rs",
+"ui/unsized-locals/issue-30276.rs",
+"ui/unsized-locals/issue-50940-with-feature.rs",
+"ui/unsized-locals/issue-50940.rs",
+"ui/unsized-locals/issue-67981.rs",
 "ui/unsized/issue-115203.rs",
 "ui/unsized/issue-115809.rs",
 "ui/unsized/issue-30355.rs",
@@ -4367,11 +4372,6 @@
 "ui/unsized/issue-91801.rs",
 "ui/unsized/issue-91803.rs",
 "ui/unsized/issue-97732.rs",
-"ui/unsized-locals/issue-30276-feature-flagged.rs",
-"ui/unsized-locals/issue-30276.rs",
-"ui/unsized-locals/issue-50940.rs",
-"ui/unsized-locals/issue-50940-with-feature.rs",
-"ui/unsized-locals/issue-67981.rs",
 "ui/use/issue-18986.rs",
 "ui/use/issue-60976-extern-use-primitive-type.rs",
 "ui/wf/issue-103573.rs",
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index b4ccddda0d8..39b14adfea4 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -104,9 +104,18 @@ pub fn check(path: &Path, bless: bool, bad: &mut bool) {
 
     // the list of files in ui tests that are allowed to start with `issue-XXXX`
     // BTreeSet because we would like a stable ordering so --bless works
-    let allowed_issue_names = BTreeSet::from(
-        include!("issues.txt").map(|path| path.replace("/", std::path::MAIN_SEPARATOR_STR)),
-    );
+    let issues_list =
+        include!("issues.txt").map(|path| path.replace("/", std::path::MAIN_SEPARATOR_STR));
+    let issues: Vec<String> = Vec::from(issues_list.clone());
+    let is_sorted = issues.windows(2).all(|w| w[0] < w[1]);
+    if !is_sorted && !bless {
+        tidy_error!(
+            bad,
+            "`src/tools/tidy/src/issues.txt` is not in order, mostly because you modified it manually,
+            please only update it with command `x test tidy --bless`"
+        );
+    }
+    let allowed_issue_names = BTreeSet::from(issues_list);
 
     let mut remaining_issue_names: BTreeSet<String> = allowed_issue_names.clone();
 
diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs
index 4af94730b7d..b0f8ebd5920 100644
--- a/tests/assembly/targets/targets-elf.rs
+++ b/tests/assembly/targets/targets-elf.rs
@@ -234,6 +234,9 @@
 //@ revisions: loongarch64_unknown_linux_gnu
 //@ [loongarch64_unknown_linux_gnu] compile-flags: --target loongarch64-unknown-linux-gnu
 //@ [loongarch64_unknown_linux_gnu] needs-llvm-components: loongarch
+//@ revisions: loongarch64_unknown_linux_musl
+//@ [loongarch64_unknown_linux_musl] compile-flags: --target loongarch64-unknown-linux-musl
+//@ [loongarch64_unknown_linux_musl] needs-llvm-components: loongarch
 //@ revisions: loongarch64_unknown_none
 //@ [loongarch64_unknown_none] compile-flags: --target loongarch64-unknown-none
 //@ [loongarch64_unknown_none] needs-llvm-components: loongarch
diff --git a/tests/codegen/asm-goto.rs b/tests/codegen/asm-goto.rs
new file mode 100644
index 00000000000..e522d0da5b4
--- /dev/null
+++ b/tests/codegen/asm-goto.rs
@@ -0,0 +1,51 @@
+//@ compile-flags: -O
+//@ only-x86_64
+
+#![crate_type = "rlib"]
+#![feature(asm_goto)]
+
+use std::arch::asm;
+
+#[no_mangle]
+pub extern "C" fn panicky() {}
+
+struct Foo;
+
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!();
+    }
+}
+
+// CHECK-LABEL: @asm_goto
+#[no_mangle]
+pub unsafe fn asm_goto() {
+    // CHECK: callbr void asm sideeffect alignstack inteldialect "
+    // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]]
+    asm!("jmp {}", label {});
+}
+
+// CHECK-LABEL: @asm_goto_with_outputs
+#[no_mangle]
+pub unsafe fn asm_goto_with_outputs() -> u64 {
+    let out: u64;
+    // CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect "
+    // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]]
+    asm!("{} /* {} */", out(reg) out, label { return 1; });
+    // CHECK: [[JUMPBB]]:
+    // CHECK-NEXT: [[RET:%.+]] = phi i64 [ [[RES]], %[[FALLTHROUGHBB]] ], [ 1, %start ]
+    // CHECK-NEXT: ret i64 [[RET]]
+    out
+}
+
+// CHECK-LABEL: @asm_goto_noreturn
+#[no_mangle]
+pub unsafe fn asm_goto_noreturn() -> u64 {
+    let out: u64;
+    // CHECK: callbr void asm sideeffect alignstack inteldialect "
+    // CHECK-NEXT: to label %unreachable [label %[[JUMPBB:[a-b0-9]+]]]
+    asm!("jmp {}", label { return 1; }, options(noreturn));
+    // CHECK: [[JUMPBB]]:
+    // CHECK-NEXT: ret i64 1
+    out
+}
diff --git a/tests/codegen/enum/uninhabited_enum_default_branch.rs b/tests/codegen/enum/uninhabited_enum_default_branch.rs
new file mode 100644
index 00000000000..5f318f18dec
--- /dev/null
+++ b/tests/codegen/enum/uninhabited_enum_default_branch.rs
@@ -0,0 +1,24 @@
+//@ compile-flags: -O
+
+#![crate_type = "lib"]
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Int(u32);
+
+const A: Int = Int(201);
+const B: Int = Int(270);
+const C: Int = Int(153);
+
+// CHECK-LABEL: @foo(
+// CHECK-SAME: [[TMP0:%.*]])
+// CHECK-NEXT:  start:
+// CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[TMP0]], -201
+// CHECK-NEXT:    icmp ult i32 [[TMP1]], 70
+// CHECK-NEXT:    icmp eq i32 [[TMP0]], 153
+// CHECK-NEXT:    [[SPEC_SELECT:%.*]] = or i1
+// CHECK-NEXT:    ret i1 [[SPEC_SELECT]]
+#[no_mangle]
+pub fn foo(x: Int) -> bool {
+    (x >= A && x <= B)
+        || x == C
+}
diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-abort.diff
index 080478ea884..bd346af6d16 100644
--- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-abort.diff
+++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-abort.diff
@@ -69,7 +69,7 @@
           StorageLive(_6);
           _6 = ((*_1).4: std::option::Option<usize>);
           _7 = discriminant(_6);
-          switchInt(move _7) -> [1: bb4, otherwise: bb6];
+          switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb9];
       }
   
       bb4: {
@@ -135,5 +135,9 @@
           StorageDead(_6);
           return;
       }
+  
+      bb9: {
+          unreachable;
+      }
   }
   
diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-unwind.diff
index ff8933fca8b..422cbeaa224 100644
--- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-unwind.diff
+++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.panic-unwind.diff
@@ -69,7 +69,7 @@
           StorageLive(_6);
           _6 = ((*_1).4: std::option::Option<usize>);
           _7 = discriminant(_6);
-          switchInt(move _7) -> [1: bb4, otherwise: bb6];
+          switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb9];
       }
   
       bb4: {
@@ -135,5 +135,9 @@
           StorageDead(_6);
           return;
       }
+  
+      bb9: {
+          unreachable;
+      }
   }
   
diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir
index f7be8b75db7..bc12002490a 100644
--- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir
@@ -33,13 +33,13 @@ fn num_to_digit(_1: char) -> u32 {
         _3 = &_2;
         StorageLive(_4);
         _4 = discriminant(_2);
-        StorageDead(_3);
-        StorageDead(_2);
-        switchInt(move _4) -> [1: bb2, otherwise: bb7];
+        switchInt(move _4) -> [1: bb2, 0: bb6, otherwise: bb8];
     }
 
     bb2: {
         StorageDead(_4);
+        StorageDead(_3);
+        StorageDead(_2);
         StorageLive(_5);
         _5 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind unreachable];
     }
@@ -47,7 +47,7 @@ fn num_to_digit(_1: char) -> u32 {
     bb3: {
         StorageLive(_6);
         _6 = discriminant(_5);
-        switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb6];
+        switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb8];
     }
 
     bb4: {
@@ -58,20 +58,22 @@ fn num_to_digit(_1: char) -> u32 {
         _0 = move ((_5 as Some).0: u32);
         StorageDead(_6);
         StorageDead(_5);
-        goto -> bb8;
+        goto -> bb7;
     }
 
     bb6: {
-        unreachable;
+        StorageDead(_4);
+        StorageDead(_3);
+        StorageDead(_2);
+        _0 = const 0_u32;
+        goto -> bb7;
     }
 
     bb7: {
-        StorageDead(_4);
-        _0 = const 0_u32;
-        goto -> bb8;
+        return;
     }
 
     bb8: {
-        return;
+        unreachable;
     }
 }
diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir
index e76fe992ac7..6c7e10a4525 100644
--- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir
@@ -33,13 +33,13 @@ fn num_to_digit(_1: char) -> u32 {
         _3 = &_2;
         StorageLive(_4);
         _4 = discriminant(_2);
-        StorageDead(_3);
-        StorageDead(_2);
-        switchInt(move _4) -> [1: bb2, otherwise: bb7];
+        switchInt(move _4) -> [1: bb2, 0: bb6, otherwise: bb8];
     }
 
     bb2: {
         StorageDead(_4);
+        StorageDead(_3);
+        StorageDead(_2);
         StorageLive(_5);
         _5 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind continue];
     }
@@ -47,7 +47,7 @@ fn num_to_digit(_1: char) -> u32 {
     bb3: {
         StorageLive(_6);
         _6 = discriminant(_5);
-        switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb6];
+        switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb8];
     }
 
     bb4: {
@@ -58,20 +58,22 @@ fn num_to_digit(_1: char) -> u32 {
         _0 = move ((_5 as Some).0: u32);
         StorageDead(_6);
         StorageDead(_5);
-        goto -> bb8;
+        goto -> bb7;
     }
 
     bb6: {
-        unreachable;
+        StorageDead(_4);
+        StorageDead(_3);
+        StorageDead(_2);
+        _0 = const 0_u32;
+        goto -> bb7;
     }
 
     bb7: {
-        StorageDead(_4);
-        _0 = const 0_u32;
-        goto -> bb8;
+        return;
     }
 
     bb8: {
-        return;
+        unreachable;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff
index 5c586fbc2fc..84181462f67 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff
@@ -58,16 +58,20 @@
 +         _2 = const Option::<Layout>::None;
           StorageLive(_10);
 -         _10 = discriminant(_2);
--         switchInt(move _10) -> [0: bb1, 1: bb2, otherwise: bb6];
+-         switchInt(move _10) -> [0: bb2, 1: bb3, otherwise: bb1];
 +         _10 = const 0_isize;
-+         switchInt(const 0_isize) -> [0: bb1, 1: bb2, otherwise: bb6];
++         switchInt(const 0_isize) -> [0: bb2, 1: bb3, otherwise: bb1];
       }
   
       bb1: {
-          _11 = option::unwrap_failed() -> unwind unreachable;
+          unreachable;
       }
   
       bb2: {
+          _11 = option::unwrap_failed() -> unwind unreachable;
+      }
+  
+      bb3: {
 -         _1 = move ((_2 as Some).0: std::alloc::Layout);
 +         _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }};
           StorageDead(_10);
@@ -82,21 +86,21 @@
 +         _7 = const {ALLOC1<imm>: &std::alloc::Global};
           StorageLive(_8);
 -         _8 = _1;
--         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb3, unwind unreachable];
+-         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb4, unwind unreachable];
 +         _8 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }};
-+         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb3, unwind unreachable];
++         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind unreachable];
       }
   
-      bb3: {
+      bb4: {
           StorageDead(_8);
           StorageDead(_7);
           StorageLive(_12);
           StorageLive(_15);
           _12 = discriminant(_6);
-          switchInt(move _12) -> [0: bb5, 1: bb4, otherwise: bb6];
+          switchInt(move _12) -> [0: bb6, 1: bb5, otherwise: bb1];
       }
   
-      bb4: {
+      bb5: {
           _15 = const "called `Result::unwrap()` on an `Err` value";
           StorageLive(_16);
           StorageLive(_17);
@@ -106,7 +110,7 @@
           _14 = result::unwrap_failed(move _15, move _16) -> unwind unreachable;
       }
   
-      bb5: {
+      bb6: {
           _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
           StorageDead(_15);
           StorageDead(_12);
@@ -127,10 +131,6 @@
 +         nop;
           return;
       }
-  
-      bb6: {
-          unreachable;
-      }
   }
 + 
 + ALLOC0 (size: 8, align: 4) {
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff
index bfb2319dac1..820d02e26cd 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff
@@ -43,9 +43,9 @@
 +         _2 = const Option::<Layout>::None;
           StorageLive(_10);
 -         _10 = discriminant(_2);
--         switchInt(move _10) -> [0: bb2, 1: bb3, otherwise: bb5];
+-         switchInt(move _10) -> [0: bb3, 1: bb4, otherwise: bb2];
 +         _10 = const 0_isize;
-+         switchInt(const 0_isize) -> [0: bb2, 1: bb3, otherwise: bb5];
++         switchInt(const 0_isize) -> [0: bb3, 1: bb4, otherwise: bb2];
       }
   
       bb1: {
@@ -68,10 +68,14 @@
       }
   
       bb2: {
-          _11 = option::unwrap_failed() -> unwind continue;
+          unreachable;
       }
   
       bb3: {
+          _11 = option::unwrap_failed() -> unwind continue;
+      }
+  
+      bb4: {
 -         _1 = move ((_2 as Some).0: std::alloc::Layout);
 +         _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }};
           StorageDead(_10);
@@ -86,20 +90,16 @@
 +         _7 = const {ALLOC1<imm>: &std::alloc::Global};
           StorageLive(_8);
 -         _8 = _1;
--         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb4, unwind continue];
+-         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb5, unwind continue];
 +         _8 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }};
-+         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind continue];
++         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(4 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x00000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb5, unwind continue];
       }
   
-      bb4: {
+      bb5: {
           StorageDead(_8);
           StorageDead(_7);
           _5 = Result::<NonNull<[u8]>, std::alloc::AllocError>::unwrap(move _6) -> [return: bb1, unwind continue];
       }
-  
-      bb5: {
-          unreachable;
-      }
   }
 + 
 + ALLOC0 (size: 8, align: 4) {
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff
index ce55a8265e5..f478f7cb903 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff
@@ -58,16 +58,20 @@
 +         _2 = const Option::<Layout>::None;
           StorageLive(_10);
 -         _10 = discriminant(_2);
--         switchInt(move _10) -> [0: bb1, 1: bb2, otherwise: bb6];
+-         switchInt(move _10) -> [0: bb2, 1: bb3, otherwise: bb1];
 +         _10 = const 0_isize;
-+         switchInt(const 0_isize) -> [0: bb1, 1: bb2, otherwise: bb6];
++         switchInt(const 0_isize) -> [0: bb2, 1: bb3, otherwise: bb1];
       }
   
       bb1: {
-          _11 = option::unwrap_failed() -> unwind unreachable;
+          unreachable;
       }
   
       bb2: {
+          _11 = option::unwrap_failed() -> unwind unreachable;
+      }
+  
+      bb3: {
 -         _1 = move ((_2 as Some).0: std::alloc::Layout);
 +         _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }};
           StorageDead(_10);
@@ -82,21 +86,21 @@
 +         _7 = const {ALLOC1<imm>: &std::alloc::Global};
           StorageLive(_8);
 -         _8 = _1;
--         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb3, unwind unreachable];
+-         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb4, unwind unreachable];
 +         _8 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }};
-+         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb3, unwind unreachable];
++         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind unreachable];
       }
   
-      bb3: {
+      bb4: {
           StorageDead(_8);
           StorageDead(_7);
           StorageLive(_12);
           StorageLive(_15);
           _12 = discriminant(_6);
-          switchInt(move _12) -> [0: bb5, 1: bb4, otherwise: bb6];
+          switchInt(move _12) -> [0: bb6, 1: bb5, otherwise: bb1];
       }
   
-      bb4: {
+      bb5: {
           _15 = const "called `Result::unwrap()` on an `Err` value";
           StorageLive(_16);
           StorageLive(_17);
@@ -106,7 +110,7 @@
           _14 = result::unwrap_failed(move _15, move _16) -> unwind unreachable;
       }
   
-      bb5: {
+      bb6: {
           _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>);
           StorageDead(_15);
           StorageDead(_12);
@@ -127,10 +131,6 @@
 +         nop;
           return;
       }
-  
-      bb6: {
-          unreachable;
-      }
   }
 + 
 + ALLOC0 (size: 16, align: 8) {
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff
index ddf4223bb49..1fba8b5059a 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff
@@ -43,9 +43,9 @@
 +         _2 = const Option::<Layout>::None;
           StorageLive(_10);
 -         _10 = discriminant(_2);
--         switchInt(move _10) -> [0: bb2, 1: bb3, otherwise: bb5];
+-         switchInt(move _10) -> [0: bb3, 1: bb4, otherwise: bb2];
 +         _10 = const 0_isize;
-+         switchInt(const 0_isize) -> [0: bb2, 1: bb3, otherwise: bb5];
++         switchInt(const 0_isize) -> [0: bb3, 1: bb4, otherwise: bb2];
       }
   
       bb1: {
@@ -68,10 +68,14 @@
       }
   
       bb2: {
-          _11 = option::unwrap_failed() -> unwind continue;
+          unreachable;
       }
   
       bb3: {
+          _11 = option::unwrap_failed() -> unwind continue;
+      }
+  
+      bb4: {
 -         _1 = move ((_2 as Some).0: std::alloc::Layout);
 +         _1 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }};
           StorageDead(_10);
@@ -86,20 +90,16 @@
 +         _7 = const {ALLOC1<imm>: &std::alloc::Global};
           StorageLive(_8);
 -         _8 = _1;
--         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb4, unwind continue];
+-         _6 = std::alloc::Global::alloc_impl(move _7, move _8, const false) -> [return: bb5, unwind continue];
 +         _8 = const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }};
-+         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb4, unwind continue];
++         _6 = std::alloc::Global::alloc_impl(const {ALLOC1<imm>: &std::alloc::Global}, const Layout {{ size: Indirect { alloc_id: ALLOC0, offset: Size(8 bytes) }: usize, align: std::ptr::Alignment(Scalar(0x0000000000000000): std::ptr::alignment::AlignmentEnum) }}, const false) -> [return: bb5, unwind continue];
       }
   
-      bb4: {
+      bb5: {
           StorageDead(_8);
           StorageDead(_7);
           _5 = Result::<NonNull<[u8]>, std::alloc::AllocError>::unwrap(move _6) -> [return: bb1, unwind continue];
       }
-  
-      bb5: {
-          unreachable;
-      }
   }
 + 
 + ALLOC0 (size: 16, align: 8) {
diff --git a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff b/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff
index ab3d91ab918..d0abebff214 100644
--- a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff
+++ b/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff
@@ -52,17 +52,21 @@
           StorageLive(_9);
           StorageLive(_10);
           _8 = discriminant(_1);
-          switchInt(move _8) -> [0: bb5, 1: bb4, otherwise: bb6];
+          switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb1];
       }
   
       bb1: {
+          unreachable;
+      }
+  
+      bb2: {
           _7 = ((_2 as Continue).0: i32);
           _0 = Result::<i32, i32>::Ok(_7);
           StorageDead(_2);
           return;
       }
   
-      bb2: {
+      bb3: {
           _5 = ((_2 as Break).0: std::result::Result<std::convert::Infallible, i32>);
           StorageLive(_6);
           _6 = _5;
@@ -73,34 +77,30 @@
           return;
       }
   
-      bb3: {
+      bb4: {
           StorageDead(_10);
           StorageDead(_9);
           StorageDead(_8);
           StorageDead(_3);
           _4 = discriminant(_2);
--         switchInt(move _4) -> [0: bb1, 1: bb2, otherwise: bb6];
-+         goto -> bb1;
+-         switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb1];
++         goto -> bb2;
       }
   
-      bb4: {
+      bb5: {
           _10 = ((_1 as Err).0: i32);
           StorageLive(_11);
           _11 = Result::<Infallible, i32>::Err(_10);
           _2 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _11);
           StorageDead(_11);
--         goto -> bb3;
+-         goto -> bb4;
 +         goto -> bb7;
       }
   
-      bb5: {
+      bb6: {
           _9 = ((_1 as Ok).0: i32);
           _2 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(_9);
-          goto -> bb3;
-      }
-  
-      bb6: {
-          unreachable;
+          goto -> bb4;
 +     }
 + 
 +     bb7: {
@@ -109,7 +109,7 @@
 +         StorageDead(_8);
 +         StorageDead(_3);
 +         _4 = discriminant(_2);
-+         goto -> bb2;
++         goto -> bb3;
       }
   }
   
diff --git a/tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff b/tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff
index 1ac527e9338..f7495862992 100644
--- a/tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff
+++ b/tests/mir-opt/separate_const_switch.too_complex.JumpThreading.diff
@@ -27,54 +27,54 @@
       bb0: {
           StorageLive(_2);
           _3 = discriminant(_1);
-          switchInt(move _3) -> [0: bb2, 1: bb1, otherwise: bb7];
+          switchInt(move _3) -> [0: bb3, 1: bb2, otherwise: bb1];
       }
   
       bb1: {
+          unreachable;
+      }
+  
+      bb2: {
           _5 = ((_1 as Err).0: usize);
           _2 = ControlFlow::<usize, i32>::Break(_5);
--         goto -> bb3;
+-         goto -> bb4;
 +         goto -> bb8;
       }
   
-      bb2: {
+      bb3: {
           _4 = ((_1 as Ok).0: i32);
           _2 = ControlFlow::<usize, i32>::Continue(_4);
-          goto -> bb3;
+          goto -> bb4;
       }
   
-      bb3: {
+      bb4: {
           _6 = discriminant(_2);
--         switchInt(move _6) -> [0: bb5, 1: bb4, otherwise: bb7];
-+         goto -> bb5;
+-         switchInt(move _6) -> [0: bb6, 1: bb5, otherwise: bb1];
++         goto -> bb6;
       }
   
-      bb4: {
+      bb5: {
           StorageLive(_8);
           _8 = ((_2 as Break).0: usize);
           _0 = const Option::<i32>::None;
           StorageDead(_8);
-          goto -> bb6;
+          goto -> bb7;
       }
   
-      bb5: {
+      bb6: {
           _7 = ((_2 as Continue).0: i32);
           _0 = Option::<i32>::Some(_7);
-          goto -> bb6;
+          goto -> bb7;
       }
   
-      bb6: {
+      bb7: {
           StorageDead(_2);
           return;
-      }
-  
-      bb7: {
-          unreachable;
 +     }
 + 
 +     bb8: {
 +         _6 = discriminant(_2);
-+         goto -> bb4;
++         goto -> bb5;
       }
   }
   
diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff
index 1566d7197ac..c520a159f47 100644
--- a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff
+++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff
@@ -23,12 +23,12 @@
           StorageDead(_3);
           StorageDead(_2);
           _5 = discriminant((_1.0: std::option::Option<u8>));
-          switchInt(move _5) -> [1: bb1, otherwise: bb3];
+          switchInt(move _5) -> [1: bb1, 0: bb3, otherwise: bb5];
       }
   
       bb1: {
           _4 = discriminant((_1.1: std::option::Option<T>));
-          switchInt(move _4) -> [0: bb2, otherwise: bb3];
+          switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb5];
       }
   
       bb2: {
@@ -46,5 +46,9 @@
           StorageDead(_1);
           return;
       }
+  
+      bb5: {
+          unreachable;
+      }
   }
   
diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff
index ba5262b0ee1..686581591fc 100644
--- a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff
+++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff
@@ -23,12 +23,12 @@
           StorageDead(_3);
           StorageDead(_2);
           _5 = discriminant((_1.0: std::option::Option<u8>));
-          switchInt(move _5) -> [1: bb1, otherwise: bb3];
+          switchInt(move _5) -> [1: bb1, 0: bb3, otherwise: bb5];
       }
   
       bb1: {
           _4 = discriminant((_1.1: std::option::Option<T>));
-          switchInt(move _4) -> [0: bb2, otherwise: bb3];
+          switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb5];
       }
   
       bb2: {
@@ -46,5 +46,9 @@
           StorageDead(_1);
           return;
       }
+  
+      bb5: {
+          unreachable;
+      }
   }
   
diff --git a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-abort.diff
index 5a3544f8538..1b7517c8d01 100644
--- a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.diff
+++ b/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-abort.diff
@@ -31,7 +31,7 @@
           _4 = &(_1.1: Test3);
           _5 = discriminant((*_4));
 -         switchInt(move _5) -> [0: bb3, 1: bb4, 2: bb5, 3: bb2, otherwise: bb1];
-+         switchInt(move _5) -> [0: bb12, 1: bb12, 2: bb5, 3: bb2, otherwise: bb12];
++         switchInt(move _5) -> [0: bb1, 1: bb1, 2: bb5, 3: bb2, otherwise: bb1];
       }
   
       bb1: {
@@ -73,7 +73,7 @@
           StorageLive(_9);
           _10 = discriminant((_1.1: Test3));
 -         switchInt(move _10) -> [0: bb8, 1: bb9, 2: bb10, 3: bb7, otherwise: bb1];
-+         switchInt(move _10) -> [0: bb12, 1: bb12, 2: bb10, 3: bb7, otherwise: bb12];
++         switchInt(move _10) -> [0: bb1, 1: bb1, 2: bb10, 3: bb7, otherwise: bb1];
       }
   
       bb7: {
@@ -110,10 +110,6 @@
           _0 = const ();
           StorageDead(_1);
           return;
-+     }
-+ 
-+     bb12: {
-+         unreachable;
       }
   }
   
diff --git a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-unwind.diff
new file mode 100644
index 00000000000..1b7517c8d01
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-unwind.diff
@@ -0,0 +1,115 @@
+- // MIR for `byref` before UninhabitedEnumBranching
++ // MIR for `byref` after UninhabitedEnumBranching
+  
+  fn byref() -> () {
+      let mut _0: ();
+      let _1: Plop;
+      let mut _2: Test3;
+      let _3: &str;
+      let mut _4: &Test3;
+      let mut _5: isize;
+      let _6: &str;
+      let _7: &str;
+      let _8: &str;
+      let _9: &str;
+      let mut _10: isize;
+      let _11: &str;
+      let _12: &str;
+      let _13: &str;
+      scope 1 {
+          debug plop => _1;
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test3::C;
+          _1 = Plop { xx: const 51_u32, test3: move _2 };
+          StorageDead(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          _4 = &(_1.1: Test3);
+          _5 = discriminant((*_4));
+-         switchInt(move _5) -> [0: bb3, 1: bb4, 2: bb5, 3: bb2, otherwise: bb1];
++         switchInt(move _5) -> [0: bb1, 1: bb1, 2: bb5, 3: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          StorageLive(_8);
+          _8 = const "D";
+          _3 = &(*_8);
+          StorageDead(_8);
+          goto -> bb6;
+      }
+  
+      bb3: {
+          _3 = const "A(Empty)";
+          goto -> bb6;
+      }
+  
+      bb4: {
+          StorageLive(_6);
+          _6 = const "B(Empty)";
+          _3 = &(*_6);
+          StorageDead(_6);
+          goto -> bb6;
+      }
+  
+      bb5: {
+          StorageLive(_7);
+          _7 = const "C";
+          _3 = &(*_7);
+          StorageDead(_7);
+          goto -> bb6;
+      }
+  
+      bb6: {
+          StorageDead(_4);
+          StorageDead(_3);
+          StorageLive(_9);
+          _10 = discriminant((_1.1: Test3));
+-         switchInt(move _10) -> [0: bb8, 1: bb9, 2: bb10, 3: bb7, otherwise: bb1];
++         switchInt(move _10) -> [0: bb1, 1: bb1, 2: bb10, 3: bb7, otherwise: bb1];
+      }
+  
+      bb7: {
+          StorageLive(_13);
+          _13 = const "D";
+          _9 = &(*_13);
+          StorageDead(_13);
+          goto -> bb11;
+      }
+  
+      bb8: {
+          _9 = const "A(Empty)";
+          goto -> bb11;
+      }
+  
+      bb9: {
+          StorageLive(_11);
+          _11 = const "B(Empty)";
+          _9 = &(*_11);
+          StorageDead(_11);
+          goto -> bb11;
+      }
+  
+      bb10: {
+          StorageLive(_12);
+          _12 = const "C";
+          _9 = &(*_12);
+          StorageDead(_12);
+          goto -> bb11;
+      }
+  
+      bb11: {
+          StorageDead(_9);
+          _0 = const ();
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-abort.diff
index 121374553ed..f9a43480917 100644
--- a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.diff
+++ b/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-abort.diff
@@ -13,8 +13,7 @@
           StorageLive(_2);
           _2 = Test2::D;
           _3 = discriminant(_2);
--         switchInt(move _3) -> [4: bb3, 5: bb2, otherwise: bb1];
-+         switchInt(move _3) -> [4: bb3, 5: bb2, otherwise: bb5];
+          switchInt(move _3) -> [4: bb3, 5: bb2, otherwise: bb1];
       }
   
       bb1: {
@@ -39,10 +38,6 @@
           StorageDead(_1);
           _0 = const ();
           return;
-+     }
-+ 
-+     bb5: {
-+         unreachable;
       }
   }
   
diff --git a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-unwind.diff
new file mode 100644
index 00000000000..f9a43480917
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-unwind.diff
@@ -0,0 +1,43 @@
+- // MIR for `custom_discriminant` before UninhabitedEnumBranching
++ // MIR for `custom_discriminant` after UninhabitedEnumBranching
+  
+  fn custom_discriminant() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test2;
+      let mut _3: isize;
+      let _4: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test2::D;
+          _3 = discriminant(_2);
+          switchInt(move _3) -> [4: bb3, 5: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          StorageLive(_4);
+          _4 = const "E";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb4;
+      }
+  
+      bb3: {
+          _1 = const "D";
+          goto -> bb4;
+      }
+  
+      bb4: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-abort.diff
new file mode 100644
index 00000000000..383fde4d787
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-abort.diff
@@ -0,0 +1,53 @@
+- // MIR for `otherwise_t1` before UninhabitedEnumBranching
++ // MIR for `otherwise_t1` after UninhabitedEnumBranching
+  
+  fn otherwise_t1() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test1;
+      let mut _3: isize;
+      let _4: &str;
+      let _5: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test1::C;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
++         switchInt(move _3) -> [0: bb5, 1: bb5, 2: bb1, otherwise: bb5];
+      }
+  
+      bb1: {
+          StorageLive(_5);
+          _5 = const "C";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb4;
+      }
+  
+      bb2: {
+          _1 = const "A(Empty)";
+          goto -> bb4;
+      }
+  
+      bb3: {
+          StorageLive(_4);
+          _4 = const "B(Empty)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb4;
+      }
+  
+      bb4: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
++     }
++ 
++     bb5: {
++         unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-unwind.diff
new file mode 100644
index 00000000000..383fde4d787
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-unwind.diff
@@ -0,0 +1,53 @@
+- // MIR for `otherwise_t1` before UninhabitedEnumBranching
++ // MIR for `otherwise_t1` after UninhabitedEnumBranching
+  
+  fn otherwise_t1() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test1;
+      let mut _3: isize;
+      let _4: &str;
+      let _5: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test1::C;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
++         switchInt(move _3) -> [0: bb5, 1: bb5, 2: bb1, otherwise: bb5];
+      }
+  
+      bb1: {
+          StorageLive(_5);
+          _5 = const "C";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb4;
+      }
+  
+      bb2: {
+          _1 = const "A(Empty)";
+          goto -> bb4;
+      }
+  
+      bb3: {
+          StorageLive(_4);
+          _4 = const "B(Empty)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb4;
+      }
+  
+      bb4: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
++     }
++ 
++     bb5: {
++         unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-abort.diff
new file mode 100644
index 00000000000..3a2dc19db71
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-abort.diff
@@ -0,0 +1,44 @@
+- // MIR for `otherwise_t2` before UninhabitedEnumBranching
++ // MIR for `otherwise_t2` after UninhabitedEnumBranching
+  
+  fn otherwise_t2() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test2;
+      let mut _3: isize;
+      let _4: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test2::D;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [4: bb2, otherwise: bb1];
++         switchInt(move _3) -> [4: bb2, 5: bb1, otherwise: bb4];
+      }
+  
+      bb1: {
+          StorageLive(_4);
+          _4 = const "E";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb3;
+      }
+  
+      bb2: {
+          _1 = const "D";
+          goto -> bb3;
+      }
+  
+      bb3: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
++     }
++ 
++     bb4: {
++         unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-unwind.diff
new file mode 100644
index 00000000000..3a2dc19db71
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-unwind.diff
@@ -0,0 +1,44 @@
+- // MIR for `otherwise_t2` before UninhabitedEnumBranching
++ // MIR for `otherwise_t2` after UninhabitedEnumBranching
+  
+  fn otherwise_t2() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test2;
+      let mut _3: isize;
+      let _4: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test2::D;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [4: bb2, otherwise: bb1];
++         switchInt(move _3) -> [4: bb2, 5: bb1, otherwise: bb4];
+      }
+  
+      bb1: {
+          StorageLive(_4);
+          _4 = const "E";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb3;
+      }
+  
+      bb2: {
+          _1 = const "D";
+          goto -> bb3;
+      }
+  
+      bb3: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
++     }
++ 
++     bb4: {
++         unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-abort.diff
new file mode 100644
index 00000000000..5dc1e2b73f6
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-abort.diff
@@ -0,0 +1,53 @@
+- // MIR for `otherwise_t3` before UninhabitedEnumBranching
++ // MIR for `otherwise_t3` after UninhabitedEnumBranching
+  
+  fn otherwise_t3() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test3;
+      let mut _3: isize;
+      let _4: &str;
+      let _5: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test3::C;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
++         switchInt(move _3) -> [0: bb5, 1: bb5, otherwise: bb1];
+      }
+  
+      bb1: {
+          StorageLive(_5);
+          _5 = const "C";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb4;
+      }
+  
+      bb2: {
+          _1 = const "A(Empty)";
+          goto -> bb4;
+      }
+  
+      bb3: {
+          StorageLive(_4);
+          _4 = const "B(Empty)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb4;
+      }
+  
+      bb4: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
++     }
++ 
++     bb5: {
++         unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-unwind.diff
new file mode 100644
index 00000000000..5dc1e2b73f6
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-unwind.diff
@@ -0,0 +1,53 @@
+- // MIR for `otherwise_t3` before UninhabitedEnumBranching
++ // MIR for `otherwise_t3` after UninhabitedEnumBranching
+  
+  fn otherwise_t3() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test3;
+      let mut _3: isize;
+      let _4: &str;
+      let _5: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test3::C;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
++         switchInt(move _3) -> [0: bb5, 1: bb5, otherwise: bb1];
+      }
+  
+      bb1: {
+          StorageLive(_5);
+          _5 = const "C";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb4;
+      }
+  
+      bb2: {
+          _1 = const "A(Empty)";
+          goto -> bb4;
+      }
+  
+      bb3: {
+          StorageLive(_4);
+          _4 = const "B(Empty)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb4;
+      }
+  
+      bb4: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
++     }
++ 
++     bb5: {
++         unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-abort.diff
new file mode 100644
index 00000000000..1352dda4971
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-abort.diff
@@ -0,0 +1,48 @@
+- // MIR for `otherwise_t4` before UninhabitedEnumBranching
++ // MIR for `otherwise_t4` after UninhabitedEnumBranching
+  
+  fn otherwise_t4() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test4;
+      let mut _3: isize;
+      let _4: &str;
+      let _5: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test4::C;
+          _3 = discriminant(_2);
+          switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
+      }
+  
+      bb1: {
+          StorageLive(_5);
+          _5 = const "CD";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb4;
+      }
+  
+      bb2: {
+          _1 = const "A(i32)";
+          goto -> bb4;
+      }
+  
+      bb3: {
+          StorageLive(_4);
+          _4 = const "B(i32)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb4;
+      }
+  
+      bb4: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-unwind.diff
new file mode 100644
index 00000000000..1352dda4971
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-unwind.diff
@@ -0,0 +1,48 @@
+- // MIR for `otherwise_t4` before UninhabitedEnumBranching
++ // MIR for `otherwise_t4` after UninhabitedEnumBranching
+  
+  fn otherwise_t4() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test4;
+      let mut _3: isize;
+      let _4: &str;
+      let _5: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test4::C;
+          _3 = discriminant(_2);
+          switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
+      }
+  
+      bb1: {
+          StorageLive(_5);
+          _5 = const "CD";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb4;
+      }
+  
+      bb2: {
+          _1 = const "A(i32)";
+          goto -> bb4;
+      }
+  
+      bb3: {
+          StorageLive(_4);
+          _4 = const "B(i32)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb4;
+      }
+  
+      bb4: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff
new file mode 100644
index 00000000000..40dd961fbac
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff
@@ -0,0 +1,62 @@
+- // MIR for `otherwise_t4_uninhabited_default` before UninhabitedEnumBranching
++ // MIR for `otherwise_t4_uninhabited_default` after UninhabitedEnumBranching
+  
+  fn otherwise_t4_uninhabited_default() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test4;
+      let mut _3: isize;
+      let _4: &str;
+      let _5: &str;
+      let _6: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test4::C;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb1];
++         switchInt(move _3) -> [0: bb2, 1: bb3, 2: bb4, 3: bb1, otherwise: bb6];
+      }
+  
+      bb1: {
+          StorageLive(_6);
+          _6 = const "D";
+          _1 = &(*_6);
+          StorageDead(_6);
+          goto -> bb5;
+      }
+  
+      bb2: {
+          _1 = const "A(i32)";
+          goto -> bb5;
+      }
+  
+      bb3: {
+          StorageLive(_4);
+          _4 = const "B(i32)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb5;
+      }
+  
+      bb4: {
+          StorageLive(_5);
+          _5 = const "C";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb5;
+      }
+  
+      bb5: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
++     }
++ 
++     bb6: {
++         unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff
new file mode 100644
index 00000000000..40dd961fbac
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff
@@ -0,0 +1,62 @@
+- // MIR for `otherwise_t4_uninhabited_default` before UninhabitedEnumBranching
++ // MIR for `otherwise_t4_uninhabited_default` after UninhabitedEnumBranching
+  
+  fn otherwise_t4_uninhabited_default() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test4;
+      let mut _3: isize;
+      let _4: &str;
+      let _5: &str;
+      let _6: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test4::C;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb1];
++         switchInt(move _3) -> [0: bb2, 1: bb3, 2: bb4, 3: bb1, otherwise: bb6];
+      }
+  
+      bb1: {
+          StorageLive(_6);
+          _6 = const "D";
+          _1 = &(*_6);
+          StorageDead(_6);
+          goto -> bb5;
+      }
+  
+      bb2: {
+          _1 = const "A(i32)";
+          goto -> bb5;
+      }
+  
+      bb3: {
+          StorageLive(_4);
+          _4 = const "B(i32)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb5;
+      }
+  
+      bb4: {
+          StorageLive(_5);
+          _5 = const "C";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb5;
+      }
+  
+      bb5: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
++     }
++ 
++     bb6: {
++         unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-abort.diff
new file mode 100644
index 00000000000..ac39f6be6c6
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-abort.diff
@@ -0,0 +1,75 @@
+- // MIR for `otherwise_t4_uninhabited_default_2` before UninhabitedEnumBranching
++ // MIR for `otherwise_t4_uninhabited_default_2` after UninhabitedEnumBranching
+  
+  fn otherwise_t4_uninhabited_default_2() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test4;
+      let mut _3: isize;
+      let _4: &str;
+      let _5: &str;
+      let _6: &str;
+      let _7: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test4::C;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [0: bb2, 1: bb5, 2: bb6, otherwise: bb1];
++         switchInt(move _3) -> [0: bb2, 1: bb5, 2: bb6, 3: bb1, otherwise: bb8];
+      }
+  
+      bb1: {
+          StorageLive(_7);
+          _7 = const "A(other)D";
+          _1 = &(*_7);
+          StorageDead(_7);
+          goto -> bb7;
+      }
+  
+      bb2: {
+          switchInt(((_2 as A).0: i32)) -> [1: bb3, 2: bb4, otherwise: bb1];
+      }
+  
+      bb3: {
+          _1 = const "A(1)";
+          goto -> bb7;
+      }
+  
+      bb4: {
+          StorageLive(_4);
+          _4 = const "A(2)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb7;
+      }
+  
+      bb5: {
+          StorageLive(_5);
+          _5 = const "B(i32)";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb7;
+      }
+  
+      bb6: {
+          StorageLive(_6);
+          _6 = const "C";
+          _1 = &(*_6);
+          StorageDead(_6);
+          goto -> bb7;
+      }
+  
+      bb7: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
++     }
++ 
++     bb8: {
++         unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-unwind.diff
new file mode 100644
index 00000000000..ac39f6be6c6
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-unwind.diff
@@ -0,0 +1,75 @@
+- // MIR for `otherwise_t4_uninhabited_default_2` before UninhabitedEnumBranching
++ // MIR for `otherwise_t4_uninhabited_default_2` after UninhabitedEnumBranching
+  
+  fn otherwise_t4_uninhabited_default_2() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test4;
+      let mut _3: isize;
+      let _4: &str;
+      let _5: &str;
+      let _6: &str;
+      let _7: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test4::C;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [0: bb2, 1: bb5, 2: bb6, otherwise: bb1];
++         switchInt(move _3) -> [0: bb2, 1: bb5, 2: bb6, 3: bb1, otherwise: bb8];
+      }
+  
+      bb1: {
+          StorageLive(_7);
+          _7 = const "A(other)D";
+          _1 = &(*_7);
+          StorageDead(_7);
+          goto -> bb7;
+      }
+  
+      bb2: {
+          switchInt(((_2 as A).0: i32)) -> [1: bb3, 2: bb4, otherwise: bb1];
+      }
+  
+      bb3: {
+          _1 = const "A(1)";
+          goto -> bb7;
+      }
+  
+      bb4: {
+          StorageLive(_4);
+          _4 = const "A(2)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb7;
+      }
+  
+      bb5: {
+          StorageLive(_5);
+          _5 = const "B(i32)";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb7;
+      }
+  
+      bb6: {
+          StorageLive(_6);
+          _6 = const "C";
+          _1 = &(*_6);
+          StorageDead(_6);
+          goto -> bb7;
+      }
+  
+      bb7: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
++     }
++ 
++     bb8: {
++         unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff
new file mode 100644
index 00000000000..8180428a6f4
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff
@@ -0,0 +1,66 @@
+- // MIR for `otherwise_t5_uninhabited_default` before UninhabitedEnumBranching
++ // MIR for `otherwise_t5_uninhabited_default` after UninhabitedEnumBranching
+  
+  fn otherwise_t5_uninhabited_default() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test5<T>;
+      let mut _3: i8;
+      let _4: &str;
+      let _5: &str;
+      let _6: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test5::<T>::C;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [255: bb2, 0: bb3, 5: bb4, otherwise: bb1];
++         switchInt(move _3) -> [255: bb2, 0: bb3, 5: bb4, 3: bb1, otherwise: bb7];
+      }
+  
+      bb1: {
+          StorageLive(_6);
+          _6 = const "D";
+          _1 = &(*_6);
+          StorageDead(_6);
+          goto -> bb5;
+      }
+  
+      bb2: {
+          _1 = const "A(T)";
+          goto -> bb5;
+      }
+  
+      bb3: {
+          StorageLive(_4);
+          _4 = const "B(T)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb5;
+      }
+  
+      bb4: {
+          StorageLive(_5);
+          _5 = const "C";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb5;
+      }
+  
+      bb5: {
+          drop(_2) -> [return: bb6, unwind unreachable];
+      }
+  
+      bb6: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
++     }
++ 
++     bb7: {
++         unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff
new file mode 100644
index 00000000000..b13d5816aed
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff
@@ -0,0 +1,70 @@
+- // MIR for `otherwise_t5_uninhabited_default` before UninhabitedEnumBranching
++ // MIR for `otherwise_t5_uninhabited_default` after UninhabitedEnumBranching
+  
+  fn otherwise_t5_uninhabited_default() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test5<T>;
+      let mut _3: i8;
+      let _4: &str;
+      let _5: &str;
+      let _6: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test5::<T>::C;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [255: bb2, 0: bb3, 5: bb4, otherwise: bb1];
++         switchInt(move _3) -> [255: bb2, 0: bb3, 5: bb4, 3: bb1, otherwise: bb8];
+      }
+  
+      bb1: {
+          StorageLive(_6);
+          _6 = const "D";
+          _1 = &(*_6);
+          StorageDead(_6);
+          goto -> bb5;
+      }
+  
+      bb2: {
+          _1 = const "A(T)";
+          goto -> bb5;
+      }
+  
+      bb3: {
+          StorageLive(_4);
+          _4 = const "B(T)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb5;
+      }
+  
+      bb4: {
+          StorageLive(_5);
+          _5 = const "C";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb5;
+      }
+  
+      bb5: {
+          drop(_2) -> [return: bb6, unwind: bb7];
+      }
+  
+      bb6: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
+      }
+  
+      bb7 (cleanup): {
+          resume;
++     }
++ 
++     bb8: {
++         unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_enum_branching.rs b/tests/mir-opt/uninhabited_enum_branching.rs
index 08eca57afc6..6de001be979 100644
--- a/tests/mir-opt/uninhabited_enum_branching.rs
+++ b/tests/mir-opt/uninhabited_enum_branching.rs
@@ -1,4 +1,6 @@
 //@ unit-test: UninhabitedEnumBranching
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+
 enum Empty {}
 
 // test matching an enum with uninhabited variants
@@ -23,6 +25,21 @@ enum Test3 {
     D,
 }
 
+enum Test4 {
+    A(i32),
+    B(i32),
+    C,
+    D,
+}
+
+#[repr(i8)]
+enum Test5<T> {
+    A(T) = -1,
+    B(T) = 0,
+    C = 5,
+    D = 3,
+}
+
 struct Plop {
     xx: u32,
     test3: Test3,
@@ -46,8 +63,8 @@ fn simple() {
 fn custom_discriminant() {
     // CHECK-LABEL: fn custom_discriminant(
     // CHECK: [[discr:_.*]] = discriminant(
-    // CHECK: switchInt(move [[discr]]) -> [4: bb3, 5: bb2, otherwise: bb5];
-    // CHECK: bb5: {
+    // CHECK: switchInt(move [[discr]]) -> [4: bb3, 5: bb2, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
     // CHECK-NEXT: unreachable;
     match Test2::D {
         Test2::D => "D",
@@ -55,6 +72,111 @@ fn custom_discriminant() {
     };
 }
 
+// EMIT_MIR uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.diff
+fn otherwise_t1() {
+    // CHECK-LABEL: fn otherwise_t1(
+    // CHECK: [[discr:_.*]] = discriminant(
+    // CHECK: switchInt(move [[discr]]) -> [0: bb5, 1: bb5, 2: bb1, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
+    // CHECK-NEXT: unreachable;
+    match Test1::C {
+        Test1::A(_) => "A(Empty)",
+        Test1::B(_) => "B(Empty)",
+        _ => "C",
+    };
+}
+
+// EMIT_MIR uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.diff
+fn otherwise_t2() {
+    // CHECK-LABEL: fn otherwise_t2(
+    // CHECK: [[discr:_.*]] = discriminant(
+    // CHECK: switchInt(move [[discr]]) -> [4: bb2, 5: bb1, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
+    // CHECK-NEXT: unreachable;
+    match Test2::D {
+        Test2::D => "D",
+        _ => "E",
+    };
+}
+
+// EMIT_MIR uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.diff
+fn otherwise_t3() {
+    // CHECK-LABEL: fn otherwise_t3(
+    // CHECK: [[discr:_.*]] = discriminant(
+    // CHECK: switchInt(move [[discr]]) -> [0: bb5, 1: bb5, otherwise: bb1];
+    // CHECK: bb1: {
+    // CHECK-NOT: unreachable;
+    // CHECK: }
+    // CHECK: bb5: {
+    // CHECK-NEXT: unreachable;
+    match Test3::C {
+        Test3::A(_) => "A(Empty)",
+        Test3::B(_) => "B(Empty)",
+        _ => "C",
+    };
+}
+
+// EMIT_MIR uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.diff
+fn otherwise_t4_uninhabited_default() {
+    // CHECK-LABEL: fn otherwise_t4_uninhabited_default(
+    // CHECK: [[discr:_.*]] = discriminant(
+    // CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb3, 2: bb4, 3: bb1, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
+    // CHECK-NEXT: unreachable;
+    match Test4::C {
+        Test4::A(_) => "A(i32)",
+        Test4::B(_) => "B(i32)",
+        Test4::C => "C",
+        _ => "D",
+    };
+}
+
+// EMIT_MIR uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.diff
+fn otherwise_t4_uninhabited_default_2() {
+    // CHECK-LABEL: fn otherwise_t4_uninhabited_default_2(
+    // CHECK: [[discr:_.*]] = discriminant(
+    // CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb5, 2: bb6, 3: bb1, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
+    // CHECK-NEXT: unreachable;
+    match Test4::C {
+        Test4::A(1) => "A(1)",
+        Test4::A(2) => "A(2)",
+        Test4::B(_) => "B(i32)",
+        Test4::C => "C",
+        _ => "A(other)D",
+    };
+}
+
+// EMIT_MIR uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.diff
+fn otherwise_t4() {
+    // CHECK-LABEL: fn otherwise_t4(
+    // CHECK: [[discr:_.*]] = discriminant(
+    // CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb3, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
+    // CHECK-NOT: unreachable;
+    // CHECK: }
+    match Test4::C {
+        Test4::A(_) => "A(i32)",
+        Test4::B(_) => "B(i32)",
+        _ => "CD",
+    };
+}
+
+// EMIT_MIR uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.diff
+fn otherwise_t5_uninhabited_default<T>() {
+    // CHECK-LABEL: fn otherwise_t5_uninhabited_default(
+    // CHECK: [[discr:_.*]] = discriminant(
+    // CHECK: switchInt(move [[discr]]) -> [255: bb2, 0: bb3, 5: bb4, 3: bb1, otherwise: [[unreachable:bb.*]]];
+    // CHECK: [[unreachable]]: {
+    // CHECK-NEXT: unreachable;
+    match Test5::<T>::C {
+        Test5::A(_) => "A(T)",
+        Test5::B(_) => "B(T)",
+        Test5::C => "C",
+        _ => "D",
+    };
+}
+
 // EMIT_MIR uninhabited_enum_branching.byref.UninhabitedEnumBranching.diff
 fn byref() {
     // CHECK-LABEL: fn byref(
@@ -69,6 +191,9 @@ fn byref() {
         Test3::D => "D",
     };
 
+    // CHECK: [[unreachable]]: {
+    // CHECK-NEXT: unreachable;
+
     // CHECK: [[discr:_.*]] = discriminant(
     // CHECK: switchInt(move [[discr]]) -> [0: [[unreachable]], 1: [[unreachable]], 2: bb10, 3: bb7, otherwise: [[unreachable]]];
     match plop.test3 {
@@ -77,13 +202,17 @@ fn byref() {
         Test3::C => "C",
         Test3::D => "D",
     };
-
-    // CHECK: [[unreachable]]: {
-    // CHECK-NEXT: unreachable;
 }
 
 fn main() {
     simple();
     custom_discriminant();
+    otherwise_t1();
+    otherwise_t2();
+    otherwise_t3();
+    otherwise_t4_uninhabited_default();
+    otherwise_t4_uninhabited_default_2();
+    otherwise_t4();
+    otherwise_t5_uninhabited_default::<i32>();
     byref();
 }
diff --git a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-abort.diff
index 6ce61e15287..674d3a25504 100644
--- a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.diff
+++ b/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-abort.diff
@@ -15,7 +15,7 @@
           _2 = Test1::C;
           _3 = discriminant(_2);
 -         switchInt(move _3) -> [0: bb3, 1: bb4, 2: bb2, otherwise: bb1];
-+         switchInt(move _3) -> [0: bb6, 1: bb6, 2: bb2, otherwise: bb6];
++         switchInt(move _3) -> [0: bb1, 1: bb1, 2: bb2, otherwise: bb1];
       }
   
       bb1: {
@@ -48,10 +48,6 @@
           StorageDead(_1);
           _0 = const ();
           return;
-+     }
-+ 
-+     bb6: {
-+         unreachable;
       }
   }
   
diff --git a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-unwind.diff
new file mode 100644
index 00000000000..674d3a25504
--- /dev/null
+++ b/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-unwind.diff
@@ -0,0 +1,53 @@
+- // MIR for `simple` before UninhabitedEnumBranching
++ // MIR for `simple` after UninhabitedEnumBranching
+  
+  fn simple() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let mut _2: Test1;
+      let mut _3: isize;
+      let _4: &str;
+      let _5: &str;
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          _2 = Test1::C;
+          _3 = discriminant(_2);
+-         switchInt(move _3) -> [0: bb3, 1: bb4, 2: bb2, otherwise: bb1];
++         switchInt(move _3) -> [0: bb1, 1: bb1, 2: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          unreachable;
+      }
+  
+      bb2: {
+          StorageLive(_5);
+          _5 = const "C";
+          _1 = &(*_5);
+          StorageDead(_5);
+          goto -> bb5;
+      }
+  
+      bb3: {
+          _1 = const "A(Empty)";
+          goto -> bb5;
+      }
+  
+      bb4: {
+          StorageLive(_4);
+          _4 = const "B(Empty)";
+          _1 = &(*_4);
+          StorageDead(_4);
+          goto -> bb5;
+      }
+  
+      bb5: {
+          StorageDead(_2);
+          StorageDead(_1);
+          _0 = const ();
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff
index 79948139f88..28a8c251d95 100644
--- a/tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff
+++ b/tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff
@@ -9,7 +9,7 @@
       bb0: {
           _2 = discriminant(_1);
 -         switchInt(move _2) -> [0: bb2, 1: bb3, otherwise: bb1];
-+         switchInt(move _2) -> [0: bb5, 1: bb3, otherwise: bb1];
++         switchInt(move _2) -> [0: bb5, 1: bb3, 2: bb1, otherwise: bb5];
       }
   
       bb1: {
diff --git a/tests/rustdoc-ui/issue-110629-private-type-cycle-dyn.stderr b/tests/rustdoc-ui/issue-110629-private-type-cycle-dyn.stderr
index d056dde00ea..9394b019e11 100644
--- a/tests/rustdoc-ui/issue-110629-private-type-cycle-dyn.stderr
+++ b/tests/rustdoc-ui/issue-110629-private-type-cycle-dyn.stderr
@@ -8,17 +8,11 @@ LL | type Bar<'a, 'b> = Box<dyn PartialEq<Bar<'a, 'b>>>;
    = note: type aliases cannot be recursive
    = help: consider using a struct, enum, or union instead to break the cycle
    = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
-note: cycle used when collecting item types in top-level module
+note: cycle used when checking that `Bar` is well-formed
   --> $DIR/issue-110629-private-type-cycle-dyn.rs:1:1
    |
-LL | / type Bar<'a, 'b> = Box<dyn PartialEq<Bar<'a, 'b>>>;
-LL | |
-LL | |
-LL | | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
-...  |
-LL | |     assert!(bar(&meh) == bar(&muh));
-LL | | }
-   | |_^
+LL | type Bar<'a, 'b> = Box<dyn PartialEq<Bar<'a, 'b>>>;
+   | ^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to 1 previous error
diff --git a/tests/rustdoc-ui/issues/issue-105742.stderr b/tests/rustdoc-ui/issues/issue-105742.stderr
index d5a9031075f..0f01bc59759 100644
--- a/tests/rustdoc-ui/issues/issue-105742.stderr
+++ b/tests/rustdoc-ui/issues/issue-105742.stderr
@@ -465,38 +465,6 @@ LL |     Output = <Self as SVec>::Item> as SVec>::Item<T>,
    |                                                  +++
 
 error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:61:38
-   |
-LL |     fn len(&self) -> <Self as SVec>::Item;
-   |                                      ^^^^ expected 1 lifetime argument
-   |
-note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/issue-105742.rs:59:10
-   |
-LL |     type Item<'a, T>;
-   |          ^^^^ --
-help: add missing lifetime argument
-   |
-LL |     fn len(&self) -> <Self as SVec>::Item<'_>;
-   |                                          ++++
-
-error[E0107]: missing generics for associated type `SVec::Item`
-  --> $DIR/issue-105742.rs:61:38
-   |
-LL |     fn len(&self) -> <Self as SVec>::Item;
-   |                                      ^^^^ expected 1 generic argument
-   |
-note: associated type defined here, with 1 generic parameter: `T`
-  --> $DIR/issue-105742.rs:59:10
-   |
-LL |     type Item<'a, T>;
-   |          ^^^^     -
-help: add missing generic argument
-   |
-LL |     fn len(&self) -> <Self as SVec>::Item<T>;
-   |                                          +++
-
-error[E0107]: missing generics for associated type `SVec::Item`
   --> $DIR/issue-105742.rs:15:21
    |
 LL |     <Self as SVec>::Item,
@@ -632,6 +600,38 @@ help: add missing generic argument
 LL |     Output = <Self as SVec>::Item> as SVec>::Item<T>,
    |                                                  +++
 
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:61:38
+   |
+LL |     fn len(&self) -> <Self as SVec>::Item;
+   |                                      ^^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/issue-105742.rs:59:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^ --
+help: add missing lifetime argument
+   |
+LL |     fn len(&self) -> <Self as SVec>::Item<'_>;
+   |                                          ++++
+
+error[E0107]: missing generics for associated type `SVec::Item`
+  --> $DIR/issue-105742.rs:61:38
+   |
+LL |     fn len(&self) -> <Self as SVec>::Item;
+   |                                      ^^^^ expected 1 generic argument
+   |
+note: associated type defined here, with 1 generic parameter: `T`
+  --> $DIR/issue-105742.rs:59:10
+   |
+LL |     type Item<'a, T>;
+   |          ^^^^     -
+help: add missing generic argument
+   |
+LL |     fn len(&self) -> <Self as SVec>::Item<T>;
+   |                                          +++
+
 error: aborting due to 37 previous errors
 
 Some errors have detailed explanations: E0038, E0107.
diff --git a/tests/ui/asm/aarch64/parse-error.stderr b/tests/ui/asm/aarch64/parse-error.stderr
index 46984a1fe1c..539c134472f 100644
--- a/tests/ui/asm/aarch64/parse-error.stderr
+++ b/tests/ui/asm/aarch64/parse-error.stderr
@@ -130,17 +130,17 @@ LL |         asm!("{1}", in("x0") foo, const bar);
    |                     |
    |                     explicit register argument
 
-error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `""`
+error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `""`
   --> $DIR/parse-error.rs:66:29
    |
 LL |         asm!("", options(), "");
-   |                             ^^ expected one of 9 possible tokens
+   |                             ^^ expected one of 10 possible tokens
 
-error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `"{}"`
+error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `"{}"`
   --> $DIR/parse-error.rs:68:33
    |
 LL |         asm!("{}", in(reg) foo, "{}", out(reg) foo);
-   |                                 ^^^^ expected one of 9 possible tokens
+   |                                 ^^^^ expected one of 10 possible tokens
 
 error: asm template must be a string literal
   --> $DIR/parse-error.rs:70:14
diff --git a/tests/ui/asm/parse-error.rs b/tests/ui/asm/parse-error.rs
index 6f32293511b..a0251c6763b 100644
--- a/tests/ui/asm/parse-error.rs
+++ b/tests/ui/asm/parse-error.rs
@@ -142,3 +142,5 @@ global_asm!(format!("{{{}}}", 0), const FOO);
 //~^ ERROR asm template must be a string literal
 global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
 //~^ ERROR asm template must be a string literal
+global_asm!("{}", label {});
+//~^ ERROR expected operand, options, or additional template string
diff --git a/tests/ui/asm/parse-error.stderr b/tests/ui/asm/parse-error.stderr
index 075d28e176a..80ee5191dbb 100644
--- a/tests/ui/asm/parse-error.stderr
+++ b/tests/ui/asm/parse-error.stderr
@@ -176,17 +176,17 @@ LL |         asm!("{a}", a = const foo, a = const bar);
    |
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
 
-error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `""`
+error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `""`
   --> $DIR/parse-error.rs:82:29
    |
 LL |         asm!("", options(), "");
-   |                             ^^ expected one of 9 possible tokens
+   |                             ^^ expected one of 10 possible tokens
 
-error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `"{}"`
+error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `"{}"`
   --> $DIR/parse-error.rs:84:33
    |
 LL |         asm!("{}", in(reg) foo, "{}", out(reg) foo);
-   |                                 ^^^^ expected one of 9 possible tokens
+   |                                 ^^^^ expected one of 10 possible tokens
 
 error: asm template must be a string literal
   --> $DIR/parse-error.rs:86:14
@@ -362,6 +362,12 @@ LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
    |
    = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
+error: expected operand, options, or additional template string
+  --> $DIR/parse-error.rs:145:19
+   |
+LL | global_asm!("{}", label {});
+   |                   ^^^^^^^^ expected operand, options, or additional template string
+
 error[E0435]: attempt to use a non-constant value in a constant
   --> $DIR/parse-error.rs:39:37
    |
@@ -407,6 +413,6 @@ LL |     let mut bar = 0;
 LL |         asm!("{a}", a = const foo, a = const bar);
    |                                              ^^^ non-constant value
 
-error: aborting due to 63 previous errors
+error: aborting due to 64 previous errors
 
 For more information about this error, try `rustc --explain E0435`.
diff --git a/tests/ui/asm/x86_64/bad-options.rs b/tests/ui/asm/x86_64/bad-options.rs
index a6d5022ecf1..f9cc13cfc5a 100644
--- a/tests/ui/asm/x86_64/bad-options.rs
+++ b/tests/ui/asm/x86_64/bad-options.rs
@@ -1,5 +1,7 @@
 //@ only-x86_64
 
+#![feature(asm_unwind, asm_goto)]
+
 use std::arch::{asm, global_asm};
 
 fn main() {
@@ -14,6 +16,8 @@ fn main() {
         //~^ ERROR asm with the `pure` option must have at least one output
         asm!("{}", out(reg) foo, options(noreturn));
         //~^ ERROR asm outputs are not allowed with the `noreturn` option
+        asm!("{}", label {}, options(may_unwind));
+        //~^ ERROR asm labels are not allowed with the `may_unwind` option
     }
 
     unsafe {
diff --git a/tests/ui/asm/x86_64/bad-options.stderr b/tests/ui/asm/x86_64/bad-options.stderr
index e2351840eef..aa167e7913c 100644
--- a/tests/ui/asm/x86_64/bad-options.stderr
+++ b/tests/ui/asm/x86_64/bad-options.stderr
@@ -1,35 +1,41 @@
 error: the `nomem` and `readonly` options are mutually exclusive
-  --> $DIR/bad-options.rs:8:18
+  --> $DIR/bad-options.rs:10:18
    |
 LL |         asm!("", options(nomem, readonly));
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the `pure` and `noreturn` options are mutually exclusive
-  --> $DIR/bad-options.rs:10:18
+  --> $DIR/bad-options.rs:12:18
    |
 LL |         asm!("", options(pure, nomem, noreturn));
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: asm with the `pure` option must have at least one output
-  --> $DIR/bad-options.rs:10:18
+  --> $DIR/bad-options.rs:12:18
    |
 LL |         asm!("", options(pure, nomem, noreturn));
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: asm with the `pure` option must have at least one output
-  --> $DIR/bad-options.rs:13:33
+  --> $DIR/bad-options.rs:15:33
    |
 LL |         asm!("{}", in(reg) foo, options(pure, nomem));
    |                                 ^^^^^^^^^^^^^^^^^^^^
 
 error: asm outputs are not allowed with the `noreturn` option
-  --> $DIR/bad-options.rs:15:20
+  --> $DIR/bad-options.rs:17:20
    |
 LL |         asm!("{}", out(reg) foo, options(noreturn));
    |                    ^^^^^^^^^^^^
 
+error: asm labels are not allowed with the `may_unwind` option
+  --> $DIR/bad-options.rs:19:20
+   |
+LL |         asm!("{}", label {}, options(may_unwind));
+   |                    ^^^^^^^^
+
 error: asm with `clobber_abi` must specify explicit registers for outputs
-  --> $DIR/bad-options.rs:22:20
+  --> $DIR/bad-options.rs:26:20
    |
 LL |         asm!("{}", out(reg) foo, clobber_abi("C"));
    |                    ^^^^^^^^^^^^  ---------------- clobber_abi
@@ -37,7 +43,7 @@ LL |         asm!("{}", out(reg) foo, clobber_abi("C"));
    |                    generic outputs
 
 error: asm with `clobber_abi` must specify explicit registers for outputs
-  --> $DIR/bad-options.rs:24:20
+  --> $DIR/bad-options.rs:28:20
    |
 LL |         asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
    |                    ^^^^^^^^^^^^  ----------------  ---------------- clobber_abi
@@ -46,43 +52,43 @@ LL |         asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
    |                    generic outputs
 
 error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
-  --> $DIR/bad-options.rs:31:25
+  --> $DIR/bad-options.rs:35:25
    |
 LL | global_asm!("", options(nomem));
    |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
-  --> $DIR/bad-options.rs:33:25
+  --> $DIR/bad-options.rs:37:25
    |
 LL | global_asm!("", options(readonly));
    |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
-  --> $DIR/bad-options.rs:35:25
+  --> $DIR/bad-options.rs:39:25
    |
 LL | global_asm!("", options(noreturn));
    |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
-  --> $DIR/bad-options.rs:37:25
+  --> $DIR/bad-options.rs:41:25
    |
 LL | global_asm!("", options(pure));
    |                         ^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
-  --> $DIR/bad-options.rs:39:25
+  --> $DIR/bad-options.rs:43:25
    |
 LL | global_asm!("", options(nostack));
    |                         ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
-  --> $DIR/bad-options.rs:41:25
+  --> $DIR/bad-options.rs:45:25
    |
 LL | global_asm!("", options(preserves_flags));
    |                         ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: invalid ABI for `clobber_abi`
-  --> $DIR/bad-options.rs:20:18
+  --> $DIR/bad-options.rs:24:18
    |
 LL |         asm!("", clobber_abi("foo"));
    |                  ^^^^^^^^^^^^^^^^^^
@@ -90,12 +96,12 @@ LL |         asm!("", clobber_abi("foo"));
    = note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64`
 
 error: `C` ABI specified multiple times
-  --> $DIR/bad-options.rs:24:52
+  --> $DIR/bad-options.rs:28:52
    |
 LL |         asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
    |                                  ----------------  ^^^^^^^^^^^^^^^^
    |                                  |
    |                                  previously specified here
 
-error: aborting due to 15 previous errors
+error: aborting due to 16 previous errors
 
diff --git a/tests/ui/asm/x86_64/goto.mirunsafeck.stderr b/tests/ui/asm/x86_64/goto.mirunsafeck.stderr
new file mode 100644
index 00000000000..fe189c14f0a
--- /dev/null
+++ b/tests/ui/asm/x86_64/goto.mirunsafeck.stderr
@@ -0,0 +1,23 @@
+warning: unreachable statement
+  --> $DIR/goto.rs:99:9
+   |
+LL | /         asm!(
+LL | |             "jmp {}",
+LL | |             label {
+LL | |                 return;
+LL | |             },
+LL | |             options(noreturn)
+LL | |         );
+   | |_________- any code following this expression is unreachable
+LL |           unreachable!();
+   |           ^^^^^^^^^^^^^^ unreachable statement
+   |
+note: the lint level is defined here
+  --> $DIR/goto.rs:89:8
+   |
+LL | #[warn(unreachable_code)]
+   |        ^^^^^^^^^^^^^^^^
+   = note: this warning originates in the macro `unreachable` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/asm/x86_64/goto.rs b/tests/ui/asm/x86_64/goto.rs
new file mode 100644
index 00000000000..6a567efbb2c
--- /dev/null
+++ b/tests/ui/asm/x86_64/goto.rs
@@ -0,0 +1,111 @@
+//@ only-x86_64
+//@ run-pass
+//@ needs-asm-support
+//@ revisions: mirunsafeck thirunsafeck
+//@ [thirunsafeck]compile-flags: -Z thir-unsafeck
+
+#![deny(unreachable_code)]
+#![feature(asm_goto)]
+
+use std::arch::asm;
+
+fn goto_fallthough() {
+    unsafe {
+        asm!(
+            "/* {} */",
+            label {
+                unreachable!();
+            }
+        )
+    }
+}
+
+fn goto_jump() {
+    unsafe {
+        let mut value = false;
+        asm!(
+            "jmp {}",
+            label {
+                value = true;
+            }
+        );
+        assert!(value);
+    }
+}
+
+// asm goto with outputs cause miscompilation in LLVM. UB can be triggered
+// when outputs are used inside the label block when optimisation is enabled.
+// See: https://github.com/llvm/llvm-project/issues/74483
+/*
+fn goto_out_fallthrough() {
+    unsafe {
+        let mut out: usize;
+        asm!(
+            "lea {}, [{} + 1]",
+            "/* {} */",
+            out(reg) out,
+            in(reg) 0x12345678usize,
+            label {
+                unreachable!();
+            }
+        );
+        assert_eq!(out, 0x12345679);
+    }
+}
+
+fn goto_out_jump() {
+    unsafe {
+        let mut value = false;
+        let mut out: usize;
+        asm!(
+            "lea {}, [{} + 1]",
+            "jmp {}",
+            out(reg) out,
+            in(reg) 0x12345678usize,
+            label {
+                value = true;
+                assert_eq!(out, 0x12345679);
+            }
+        );
+        assert!(value);
+    }
+}
+*/
+
+fn goto_noreturn() {
+    unsafe {
+        let a;
+        asm!(
+            "jmp {}",
+            label {
+                a = 1;
+            },
+            options(noreturn)
+        );
+        assert_eq!(a, 1);
+    }
+}
+
+#[warn(unreachable_code)]
+fn goto_noreturn_diverge() {
+    unsafe {
+        asm!(
+            "jmp {}",
+            label {
+                return;
+            },
+            options(noreturn)
+        );
+        unreachable!();
+        //~^ WARN unreachable statement
+    }
+}
+
+fn main() {
+    goto_fallthough();
+    goto_jump();
+    // goto_out_fallthrough();
+    // goto_out_jump();
+    goto_noreturn();
+    goto_noreturn_diverge();
+}
diff --git a/tests/ui/asm/x86_64/goto.thirunsafeck.stderr b/tests/ui/asm/x86_64/goto.thirunsafeck.stderr
new file mode 100644
index 00000000000..fe189c14f0a
--- /dev/null
+++ b/tests/ui/asm/x86_64/goto.thirunsafeck.stderr
@@ -0,0 +1,23 @@
+warning: unreachable statement
+  --> $DIR/goto.rs:99:9
+   |
+LL | /         asm!(
+LL | |             "jmp {}",
+LL | |             label {
+LL | |                 return;
+LL | |             },
+LL | |             options(noreturn)
+LL | |         );
+   | |_________- any code following this expression is unreachable
+LL |           unreachable!();
+   |           ^^^^^^^^^^^^^^ unreachable statement
+   |
+note: the lint level is defined here
+  --> $DIR/goto.rs:89:8
+   |
+LL | #[warn(unreachable_code)]
+   |        ^^^^^^^^^^^^^^^^
+   = note: this warning originates in the macro `unreachable` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr
index a2ad4cbde01..a495e94bd9a 100644
--- a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr
+++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr
@@ -26,17 +26,11 @@ note: ...which requires computing normalized predicates of `Foo`...
 LL | struct Foo {
    | ^^^^^^^^^^
    = note: ...which again requires computing predicates of `Foo`, completing the cycle
-note: cycle used when collecting item types in top-level module
-  --> $DIR/cycle-iat-inside-of-adt.rs:3:1
+note: cycle used when checking that `Foo` is well-formed
+  --> $DIR/cycle-iat-inside-of-adt.rs:7:1
    |
-LL | / #![feature(inherent_associated_types)]
-LL | | #![allow(incomplete_features)]
-LL | | // FIXME(inherent_associated_types): This should pass.
-LL | |
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
+LL | struct Foo {
+   | ^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr
index b3d55fea14b..e7292c08ebd 100644
--- a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr
+++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr
@@ -20,19 +20,23 @@ note: ...which requires computing normalized predicates of `user`...
 LL | fn user<T>() where S<T>::P: std::fmt::Debug {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which again requires computing predicates of `user`, completing the cycle
-note: cycle used when collecting item types in top-level module
-  --> $DIR/cycle-iat-inside-of-where-predicate.rs:3:1
-   |
-LL | / #![feature(inherent_associated_types)]
-LL | | #![allow(incomplete_features)]
-LL | |
-LL | | // FIXME(inherent_associated_types): This shouldn't lead to a cycle error.
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
+note: cycle used when checking that `user` is well-formed
+  --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1
+   |
+LL | fn user<T>() where S<T>::P: std::fmt::Debug {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error: aborting due to 1 previous error
+error[E0392]: type parameter `T` is never used
+  --> $DIR/cycle-iat-inside-of-where-predicate.rs:10:10
+   |
+LL | struct S<T>;
+   |          ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0391`.
+Some errors have detailed explanations: E0391, E0392.
+For more information about an error, try `rustc --explain E0391`.
diff --git a/tests/ui/associated-inherent-types/issue-109071.no_gate.stderr b/tests/ui/associated-inherent-types/issue-109071.no_gate.stderr
index b8366b15a8a..72d3f5c6d4d 100644
--- a/tests/ui/associated-inherent-types/issue-109071.no_gate.stderr
+++ b/tests/ui/associated-inherent-types/issue-109071.no_gate.stderr
@@ -20,16 +20,6 @@ help: add missing generic argument
 LL | impl<T> Windows<T> {
    |                +++
 
-error[E0658]: inherent associated types are unstable
-  --> $DIR/issue-109071.rs:8:5
-   |
-LL |     type Item = &[T];
-   |     ^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
-   = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
 error[E0223]: ambiguous associated type
   --> $DIR/issue-109071.rs:15:22
    |
@@ -43,6 +33,16 @@ LL |     fn T() -> Option<<Windows<T> as IntoAsyncIterator>::Item> {}
 LL |     fn T() -> Option<<Windows<T> as IntoIterator>::Item> {}
    |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+error[E0658]: inherent associated types are unstable
+  --> $DIR/issue-109071.rs:8:5
+   |
+LL |     type Item = &[T];
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
+   = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
 error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0107, E0223, E0637, E0658.
diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr
index 9816d11a40a..6345ef4b798 100644
--- a/tests/ui/associated-type-bounds/duplicate.stderr
+++ b/tests/ui/associated-type-bounds/duplicate.stderr
@@ -198,6 +198,17 @@ LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
    |                              |
    |                              `Item` bound here first
 
+error[E0282]: type annotations needed
+  --> $DIR/duplicate.rs:136:5
+   |
+LL |     iter::empty()
+   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
+   |
+help: consider specifying the generic argument
+   |
+LL |     iter::empty::<T>()
+   |                +++++
+
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:139:42
    |
@@ -206,6 +217,17 @@ LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
    |                              |
    |                              `Item` bound here first
 
+error[E0282]: type annotations needed
+  --> $DIR/duplicate.rs:141:5
+   |
+LL |     iter::empty()
+   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
+   |
+help: consider specifying the generic argument
+   |
+LL |     iter::empty::<T>()
+   |                +++++
+
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:144:45
    |
@@ -214,6 +236,17 @@ LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
    |                              |
    |                              `Item` bound here first
 
+error[E0282]: type annotations needed
+  --> $DIR/duplicate.rs:146:5
+   |
+LL |     iter::empty()
+   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
+   |
+help: consider specifying the generic argument
+   |
+LL |     iter::empty::<T>()
+   |                +++++
+
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:149:40
    |
@@ -377,6 +410,16 @@ LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:197:34
+   |
+LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
+   |                      ----------  ^^^^^^^^^^ re-bound here
+   |                      |
+   |                      `Item` bound here first
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:201:34
    |
 LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
@@ -395,6 +438,16 @@ LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:201:34
+   |
+LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
+   |                      ----------  ^^^^^^^^^^ re-bound here
+   |                      |
+   |                      `Item` bound here first
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:205:37
    |
 LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
@@ -413,6 +466,16 @@ LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:205:37
+   |
+LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
+   |                      -------------  ^^^^^^^^^^^^^ re-bound here
+   |                      |
+   |                      `Item` bound here first
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:211:29
    |
 LL |     T: Iterator<Item: Copy, Item: Send>,
@@ -455,6 +518,16 @@ LL |     Self: Iterator<Item: Copy, Item: Send>,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:229:32
+   |
+LL |     Self: Iterator<Item: Copy, Item: Send>,
+   |                    ----------  ^^^^^^^^^^ re-bound here
+   |                    |
+   |                    `Item` bound here first
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:237:32
    |
 LL |     Self: Iterator<Item: Copy, Item: Copy>,
@@ -473,6 +546,16 @@ LL |     Self: Iterator<Item: Copy, Item: Copy>,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:237:32
+   |
+LL |     Self: Iterator<Item: Copy, Item: Copy>,
+   |                    ----------  ^^^^^^^^^^ re-bound here
+   |                    |
+   |                    `Item` bound here first
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:245:35
    |
 LL |     Self: Iterator<Item: 'static, Item: 'static>,
@@ -491,6 +574,16 @@ LL |     Self: Iterator<Item: 'static, Item: 'static>,
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/duplicate.rs:245:35
+   |
+LL |     Self: Iterator<Item: 'static, Item: 'static>,
+   |                    -------------  ^^^^^^^^^^^^^ re-bound here
+   |                    |
+   |                    `Item` bound here first
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:252:34
    |
 LL |     type A: Iterator<Item: Copy, Item: Send>;
@@ -514,99 +607,6 @@ LL |     type A: Iterator<Item: 'static, Item: 'static>;
    |                      |
    |                      `Item` bound here first
 
-error[E0282]: type annotations needed
-  --> $DIR/duplicate.rs:136:5
-   |
-LL |     iter::empty()
-   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
-   |
-help: consider specifying the generic argument
-   |
-LL |     iter::empty::<T>()
-   |                +++++
-
-error[E0282]: type annotations needed
-  --> $DIR/duplicate.rs:141:5
-   |
-LL |     iter::empty()
-   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
-   |
-help: consider specifying the generic argument
-   |
-LL |     iter::empty::<T>()
-   |                +++++
-
-error[E0282]: type annotations needed
-  --> $DIR/duplicate.rs:146:5
-   |
-LL |     iter::empty()
-   |     ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
-   |
-help: consider specifying the generic argument
-   |
-LL |     iter::empty::<T>()
-   |                +++++
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:197:34
-   |
-LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:201:34
-   |
-LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
-   |                      ----------  ^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:205:37
-   |
-LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
-   |                      -------------  ^^^^^^^^^^^^^ re-bound here
-   |                      |
-   |                      `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:229:32
-   |
-LL |     Self: Iterator<Item: Copy, Item: Send>,
-   |                    ----------  ^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:237:32
-   |
-LL |     Self: Iterator<Item: Copy, Item: Copy>,
-   |                    ----------  ^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:245:35
-   |
-LL |     Self: Iterator<Item: 'static, Item: 'static>,
-   |                    -------------  ^^^^^^^^^^^^^ re-bound here
-   |                    |
-   |                    `Item` bound here first
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error: aborting due to 72 previous errors
 
 Some errors have detailed explanations: E0282, E0719.
diff --git a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr
index d361643f024..c5260adbed4 100644
--- a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr
+++ b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr
@@ -10,6 +10,23 @@ LL | fn get<T:Get,U:Get>(x: T, y: U) -> <Example as Get>::Value {}
    |                                    ~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0223]: ambiguous associated type
+  --> $DIR/associated-types-in-ambiguous-context.rs:13:23
+   |
+LL |     fn grab(&self) -> Grab::Value;
+   |                       ^^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Grab>::Value`
+
+error[E0223]: ambiguous associated type
+  --> $DIR/associated-types-in-ambiguous-context.rs:16:22
+   |
+LL |     fn get(&self) -> Get::Value;
+   |                      ^^^^^^^^^^
+   |
+help: if there were a type named `Example` that implemented `Get`, you could use the fully-qualified path
+   |
+LL |     fn get(&self) -> <Example as Get>::Value;
+   |                      ~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0223]: ambiguous associated type
   --> $DIR/associated-types-in-ambiguous-context.rs:22:17
    |
 LL | trait Foo where Foo::Assoc: Bar {
@@ -33,23 +50,6 @@ LL | type X = <OsString as Deref>::Target;
    |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      and N other candidates
 
-error[E0223]: ambiguous associated type
-  --> $DIR/associated-types-in-ambiguous-context.rs:13:23
-   |
-LL |     fn grab(&self) -> Grab::Value;
-   |                       ^^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Grab>::Value`
-
-error[E0223]: ambiguous associated type
-  --> $DIR/associated-types-in-ambiguous-context.rs:16:22
-   |
-LL |     fn get(&self) -> Get::Value;
-   |                      ^^^^^^^^^^
-   |
-help: if there were a type named `Example` that implemented `Get`, you could use the fully-qualified path
-   |
-LL |     fn get(&self) -> <Example as Get>::Value;
-   |                      ~~~~~~~~~~~~~~~~~~~~~~~
-
 error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr
index b32018a6a2d..fcac95732d1 100644
--- a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr
+++ b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr
@@ -74,26 +74,6 @@ LL | static TY_STATIC_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
    |                         not allowed in type signatures
    |                         help: replace with the correct type: `Bar<i32, 3>`
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/in-signature.rs:35:21
-   |
-LL |     const ARR: [u8; _];
-   |                     ^ not allowed in type signatures
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/in-signature.rs:39:25
-   |
-LL |     const ARR: Bar<i32, _>;
-   |                         ^ not allowed in type signatures
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/in-signature.rs:43:20
-   |
-LL |     const ARR: Bar<_, _>;
-   |                    ^  ^ not allowed in type signatures
-   |                    |
-   |                    not allowed in type signatures
-
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
   --> $DIR/in-signature.rs:51:23
    |
@@ -114,6 +94,26 @@ LL |     type Assoc = Bar<_, _>;
    |                      |
    |                      not allowed in type signatures
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
+  --> $DIR/in-signature.rs:35:21
+   |
+LL |     const ARR: [u8; _];
+   |                     ^ not allowed in type signatures
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
+  --> $DIR/in-signature.rs:39:25
+   |
+LL |     const ARR: Bar<i32, _>;
+   |                         ^ not allowed in type signatures
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
+  --> $DIR/in-signature.rs:43:20
+   |
+LL |     const ARR: Bar<_, _>;
+   |                    ^  ^ not allowed in type signatures
+   |                    |
+   |                    not allowed in type signatures
+
 error: aborting due to 15 previous errors
 
 For more information about this error, try `rustc --explain E0121`.
diff --git a/tests/ui/const-generics/issues/issue-71202.rs b/tests/ui/const-generics/issues/issue-71202.rs
index 57fd72b1284..0f955414d84 100644
--- a/tests/ui/const-generics/issues/issue-71202.rs
+++ b/tests/ui/const-generics/issues/issue-71202.rs
@@ -25,7 +25,7 @@ impl<T: Copy> DataHolder<T> {
         }
 
         <IsCopy<T>>::VALUE
-    } as usize] = [];
+    } as usize] = []; //~ ERROR unconstrained generic constant
 }
 
 fn main() {}
diff --git a/tests/ui/const-generics/issues/issue-71202.stderr b/tests/ui/const-generics/issues/issue-71202.stderr
index 2aa9e344067..437b808c893 100644
--- a/tests/ui/const-generics/issues/issue-71202.stderr
+++ b/tests/ui/const-generics/issues/issue-71202.stderr
@@ -29,5 +29,30 @@ LL | |     } as usize] = [];
                    <IsCopy<T>>::VALUE
                } as usize]:`
 
-error: aborting due to 1 previous error
+error: unconstrained generic constant
+  --> $DIR/issue-71202.rs:28:19
+   |
+LL |     } as usize] = [];
+   |                   ^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); 1 - {
+                   trait NotCopy {
+                       const VALUE: bool = false;
+                   }
+           
+                   impl<__Type: ?Sized> NotCopy for __Type {}
+           
+                   struct IsCopy<__Type: ?Sized>(PhantomData<__Type>);
+           
+                   impl<__Type> IsCopy<__Type>
+                   where
+                       __Type: Sized + Copy,
+                   {
+                       const VALUE: bool = true;
+                   }
+           
+                   <IsCopy<T>>::VALUE
+               } as usize]:`
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-eval/infinite_loop.stderr b/tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr
index 37cd94bf7b7..d664ae88323 100644
--- a/tests/ui/consts/const-eval/infinite_loop.stderr
+++ b/tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr
@@ -1,5 +1,5 @@
 error: constant evaluation is taking a long time
-  --> $DIR/infinite_loop.rs:12:9
+  --> $DIR/infinite_loop.rs:15:9
    |
 LL | /         while n != 0 {
 LL | |
@@ -10,7 +10,7 @@ LL | |         }
    = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
            If your compilation actually takes a long time, you can safely allow the lint.
 help: the constant being evaluated
-  --> $DIR/infinite_loop.rs:10:18
+  --> $DIR/infinite_loop.rs:13:18
    |
 LL |       let s = [(); {
    |  __________________^
diff --git a/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr b/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr
new file mode 100644
index 00000000000..d664ae88323
--- /dev/null
+++ b/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr
@@ -0,0 +1,27 @@
+error: constant evaluation is taking a long time
+  --> $DIR/infinite_loop.rs:15:9
+   |
+LL | /         while n != 0 {
+LL | |
+LL | |             n = if n % 2 == 0 { n / 2 } else { 3 * n + 1 };
+LL | |         }
+   | |_________^
+   |
+   = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
+           If your compilation actually takes a long time, you can safely allow the lint.
+help: the constant being evaluated
+  --> $DIR/infinite_loop.rs:13:18
+   |
+LL |       let s = [(); {
+   |  __________________^
+LL | |         let mut n = 113383; // #20 in https://oeis.org/A006884
+LL | |         while n != 0 {
+LL | |
+...  |
+LL | |         n
+LL | |     }];
+   | |_____^
+   = note: `#[deny(long_running_const_eval)]` on by default
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/consts/const-eval/infinite_loop.rs b/tests/ui/consts/const-eval/infinite_loop.rs
index 44456f1ce47..f8cb79b63db 100644
--- a/tests/ui/consts/const-eval/infinite_loop.rs
+++ b/tests/ui/consts/const-eval/infinite_loop.rs
@@ -1,8 +1,11 @@
 //! This test tests two things at once:
 //! 1. we error if a const evaluation hits the deny-by-default lint limit
 //! 2. we do not ICE on invalid follow-up code
+//! 3. no ICE when run with `-Z unstable-options` (issue 122177)
 
-//@ compile-flags: -Z tiny-const-eval-limit
+//@revisions: eval_limit no_ice
+//@[no_ice] compile-flags: -Z tiny-const-eval-limit -Z unstable-options
+//@[eval_limit] compile-flags: -Z tiny-const-eval-limit
 
 fn main() {
     // Tests the Collatz conjecture with an incorrect base case (0 instead of 1).
diff --git a/tests/ui/consts/different-fn-ptr-binders-during-ctfe.rs b/tests/ui/consts/different-fn-ptr-binders-during-ctfe.rs
new file mode 100644
index 00000000000..b378542e573
--- /dev/null
+++ b/tests/ui/consts/different-fn-ptr-binders-during-ctfe.rs
@@ -0,0 +1,6 @@
+const fn cmp(x: fn(&'static ()), y: for<'a> fn(&'a ())) -> bool {
+    x == y
+    //~^ ERROR pointers cannot be reliably compared during const eval
+}
+
+fn main() {}
diff --git a/tests/ui/consts/different-fn-ptr-binders-during-ctfe.stderr b/tests/ui/consts/different-fn-ptr-binders-during-ctfe.stderr
new file mode 100644
index 00000000000..43a7b9ce66c
--- /dev/null
+++ b/tests/ui/consts/different-fn-ptr-binders-during-ctfe.stderr
@@ -0,0 +1,10 @@
+error: pointers cannot be reliably compared during const eval
+  --> $DIR/different-fn-ptr-binders-during-ctfe.rs:2:5
+   |
+LL |     x == y
+   |     ^^^^^^
+   |
+   = note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/consts/issue-103790.stderr b/tests/ui/consts/issue-103790.stderr
index 55bc9675401..abe7366483b 100644
--- a/tests/ui/consts/issue-103790.stderr
+++ b/tests/ui/consts/issue-103790.stderr
@@ -48,17 +48,11 @@ note: ...which requires computing type of `S::S`...
 LL | struct S<const S: (), const S: S = { S }>;
    |                                ^
    = note: ...which again requires computing type of `S`, completing the cycle
-note: cycle used when collecting item types in top-level module
-  --> $DIR/issue-103790.rs:1:1
+note: cycle used when checking that `S` is well-formed
+  --> $DIR/issue-103790.rs:4:1
    |
-LL | / #![feature(generic_const_exprs)]
-LL | | #![allow(incomplete_features)]
-LL | |
-LL | | struct S<const S: (), const S: S = { S }>;
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
+LL | struct S<const S: (), const S: S = { S }>;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: `()` is forbidden as the type of a const generic parameter
diff --git a/tests/ui/consts/issue-36163.stderr b/tests/ui/consts/issue-36163.stderr
index de70a457f16..8a7a0981f41 100644
--- a/tests/ui/consts/issue-36163.stderr
+++ b/tests/ui/consts/issue-36163.stderr
@@ -20,17 +20,11 @@ note: ...which requires const-evaluating + checking `A`...
 LL | const A: isize = Foo::B as isize;
    |                  ^^^^^^^^^^^^^^^
    = note: ...which again requires simplifying constant for the type system `Foo::B::{constant#0}`, completing the cycle
-note: cycle used when collecting item types in top-level module
-  --> $DIR/issue-36163.rs:1:1
+note: cycle used when checking that `Foo` is well-formed
+  --> $DIR/issue-36163.rs:3:1
    |
-LL | / const A: isize = Foo::B as isize;
-LL | |
-LL | | enum Foo {
-LL | |     B = A,
-LL | | }
-LL | |
-LL | | fn main() {}
-   | |____________^
+LL | enum Foo {
+   | ^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/cycle-trait/cycle-trait-default-type-trait.stderr b/tests/ui/cycle-trait/cycle-trait-default-type-trait.stderr
index e8be9b0b913..c0b935567f8 100644
--- a/tests/ui/cycle-trait/cycle-trait-default-type-trait.stderr
+++ b/tests/ui/cycle-trait/cycle-trait-default-type-trait.stderr
@@ -5,15 +5,11 @@ LL | trait Foo<X = Box<dyn Foo>> {
    |                       ^^^
    |
    = note: ...which immediately requires computing type of `Foo::X` again
-note: cycle used when collecting item types in top-level module
+note: cycle used when checking that `Foo` is well-formed
   --> $DIR/cycle-trait-default-type-trait.rs:4:1
    |
-LL | / trait Foo<X = Box<dyn Foo>> {
-LL | |
-LL | | }
-LL | |
-LL | | fn main() { }
-   | |_____________^
+LL | trait Foo<X = Box<dyn Foo>> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/cycle-trait/cycle-trait-supertrait-direct.stderr b/tests/ui/cycle-trait/cycle-trait-supertrait-direct.stderr
index 8645b4ebccf..2e11a59c3a4 100644
--- a/tests/ui/cycle-trait/cycle-trait-supertrait-direct.stderr
+++ b/tests/ui/cycle-trait/cycle-trait-supertrait-direct.stderr
@@ -5,7 +5,7 @@ LL | trait Chromosome: Chromosome {
    |                   ^^^^^^^^^^
    |
    = note: ...which immediately requires computing the super predicates of `Chromosome` again
-note: cycle used when collecting item types in top-level module
+note: cycle used when checking that `Chromosome` is well-formed
   --> $DIR/cycle-trait-supertrait-direct.rs:3:1
    |
 LL | / trait Chromosome: Chromosome {
diff --git a/tests/ui/cycle-trait/issue-12511.stderr b/tests/ui/cycle-trait/issue-12511.stderr
index bc56b9904f5..0246bf21983 100644
--- a/tests/ui/cycle-trait/issue-12511.stderr
+++ b/tests/ui/cycle-trait/issue-12511.stderr
@@ -10,7 +10,7 @@ note: ...which requires computing the super predicates of `T2`...
 LL | trait T2 : T1 {
    |            ^^
    = note: ...which again requires computing the super predicates of `T1`, completing the cycle
-note: cycle used when collecting item types in top-level module
+note: cycle used when checking that `T1` is well-formed
   --> $DIR/issue-12511.rs:1:1
    |
 LL | / trait T1 : T2 {
diff --git a/tests/ui/delegation/not-supported.stderr b/tests/ui/delegation/not-supported.stderr
index f235767d50a..324b79f3c53 100644
--- a/tests/ui/delegation/not-supported.stderr
+++ b/tests/ui/delegation/not-supported.stderr
@@ -70,14 +70,14 @@ LL |         fn foo(&self, x: i32) -> i32 { x }
 LL |         reuse Trait::foo;
    |                      ^^^
 
-error: delegation with early bound generics is not supported yet
+error[E0049]: method `foo2` has 0 type parameters but its trait declaration has 1 type parameter
   --> $DIR/not-supported.rs:49:22
    |
 LL |         fn foo2<T>(&self, x: T) -> T { x }
-   |         ---------------------------- callee defined here
+   |                 - expected 1 type parameter
 ...
 LL |         reuse Trait::foo2 { &self.0 }
-   |                      ^^^^
+   |                      ^^^^ found 0 type parameters
 
 error: delegation with early bound generics is not supported yet
   --> $DIR/not-supported.rs:52:29
@@ -88,6 +88,15 @@ LL |         fn foo3<'a: 'a>(_: &'a u32) {}
 LL |         reuse <F as Trait>::foo3;
    |                             ^^^^
 
+error[E0195]: lifetime parameters or bounds on method `foo3` do not match the trait declaration
+  --> $DIR/not-supported.rs:52:29
+   |
+LL |         fn foo3<'a: 'a>(_: &'a u32) {}
+   |                -------- lifetimes in impl do not match this method in trait
+...
+LL |         reuse <F as Trait>::foo3;
+   |                             ^^^^ lifetimes do not match method in trait
+
 error: delegation with early bound generics is not supported yet
   --> $DIR/not-supported.rs:59:22
    |
@@ -98,6 +107,15 @@ LL |         reuse Trait::foo { &self.0 }
    |                      ^^^
 
 error: delegation with early bound generics is not supported yet
+  --> $DIR/not-supported.rs:49:22
+   |
+LL |         fn foo2<T>(&self, x: T) -> T { x }
+   |         ---------------------------- callee defined here
+...
+LL |         reuse Trait::foo2 { &self.0 }
+   |                      ^^^^
+
+error: delegation with early bound generics is not supported yet
   --> $DIR/not-supported.rs:74:21
    |
 LL |         pub fn opaque_arg(_: impl Trait) -> i32 { 0 }
@@ -160,24 +178,6 @@ LL |         pub reuse to_reuse2::foo;
 LL |     reuse to_reuse1::foo;
    |                      ^^^
 
-error[E0049]: method `foo2` has 0 type parameters but its trait declaration has 1 type parameter
-  --> $DIR/not-supported.rs:49:22
-   |
-LL |         fn foo2<T>(&self, x: T) -> T { x }
-   |                 - expected 1 type parameter
-...
-LL |         reuse Trait::foo2 { &self.0 }
-   |                      ^^^^ found 0 type parameters
-
-error[E0195]: lifetime parameters or bounds on method `foo3` do not match the trait declaration
-  --> $DIR/not-supported.rs:52:29
-   |
-LL |         fn foo3<'a: 'a>(_: &'a u32) {}
-   |                -------- lifetimes in impl do not match this method in trait
-...
-LL |         reuse <F as Trait>::foo3;
-   |                             ^^^^ lifetimes do not match method in trait
-
 error: aborting due to 19 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0049, E0195.
diff --git a/tests/ui/did_you_mean/bad-assoc-ty.stderr b/tests/ui/did_you_mean/bad-assoc-ty.stderr
index dc93762c9b1..b349332bcb9 100644
--- a/tests/ui/did_you_mean/bad-assoc-ty.stderr
+++ b/tests/ui/did_you_mean/bad-assoc-ty.stderr
@@ -272,6 +272,17 @@ help: use type parameters instead
 LL | struct L<F, T>(F) where F: Fn() -> T;
    |           +++                      ~
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/bad-assoc-ty.rs:82:38
+   |
+LL |     fn foo<F>(_: F) where F: Fn() -> _ {}
+   |                                      ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     fn foo<F, T>(_: F) where F: Fn() -> T {}
+   |             +++                         ~
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs
   --> $DIR/bad-assoc-ty.rs:62:30
    |
@@ -305,28 +316,6 @@ help: use type parameters instead
 LL | union O<F, T> where F: Fn() -> T {
    |          +++                   ~
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for traits
-  --> $DIR/bad-assoc-ty.rs:77:29
-   |
-LL | trait P<F> where F: Fn() -> _ {
-   |                             ^ not allowed in type signatures
-   |
-help: use type parameters instead
-   |
-LL | trait P<F, T> where F: Fn() -> T {
-   |          +++                   ~
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/bad-assoc-ty.rs:82:38
-   |
-LL |     fn foo<F>(_: F) where F: Fn() -> _ {}
-   |                                      ^ not allowed in type signatures
-   |
-help: use type parameters instead
-   |
-LL |     fn foo<F, T>(_: F) where F: Fn() -> T {}
-   |             +++                         ~
-
 error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
   --> $DIR/bad-assoc-ty.rs:73:5
    |
@@ -339,6 +328,17 @@ help: wrap the field type in `ManuallyDrop<...>`
 LL |     foo: std::mem::ManuallyDrop<F>,
    |          +++++++++++++++++++++++ +
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for traits
+  --> $DIR/bad-assoc-ty.rs:77:29
+   |
+LL | trait P<F> where F: Fn() -> _ {
+   |                             ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL | trait P<F, T> where F: Fn() -> T {
+   |          +++                   ~
+
 error: aborting due to 29 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0121, E0223, E0740.
diff --git a/tests/ui/error-codes/E0657.rs b/tests/ui/error-codes/E0657.rs
index cb11de13f73..212c1d9e581 100644
--- a/tests/ui/error-codes/E0657.rs
+++ b/tests/ui/error-codes/E0657.rs
@@ -8,7 +8,7 @@ impl<T> Id<T> for T {}
 
 fn free_fn_capture_hrtb_in_impl_trait()
     -> Box<for<'a> Id<impl Lt<'a>>>
-        //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level [E0657]
+        //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
 {
     Box::new(())
 }
@@ -17,7 +17,7 @@ struct Foo;
 impl Foo {
     fn impl_fn_capture_hrtb_in_impl_trait()
         -> Box<for<'a> Id<impl Lt<'a>>>
-            //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
+            //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
     {
         Box::new(())
     }
diff --git a/tests/ui/error-codes/E0657.stderr b/tests/ui/error-codes/E0657.stderr
index df76b45a589..c539007cdcf 100644
--- a/tests/ui/error-codes/E0657.stderr
+++ b/tests/ui/error-codes/E0657.stderr
@@ -1,14 +1,26 @@
-error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
   --> $DIR/E0657.rs:10:31
    |
 LL |     -> Box<for<'a> Id<impl Lt<'a>>>
    |                               ^^
+   |
+note: lifetime declared here
+  --> $DIR/E0657.rs:10:16
+   |
+LL |     -> Box<for<'a> Id<impl Lt<'a>>>
+   |                ^^
 
-error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
   --> $DIR/E0657.rs:19:35
    |
 LL |         -> Box<for<'a> Id<impl Lt<'a>>>
    |                                   ^^
+   |
+note: lifetime declared here
+  --> $DIR/E0657.rs:19:20
+   |
+LL |         -> Box<for<'a> Id<impl Lt<'a>>>
+   |                    ^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/error-codes/E0719.stderr b/tests/ui/error-codes/E0719.stderr
index f048a8aabd4..7e8329db1f4 100644
--- a/tests/ui/error-codes/E0719.stderr
+++ b/tests/ui/error-codes/E0719.stderr
@@ -17,14 +17,6 @@ LL | trait Foo: Iterator<Item = i32, Item = i32> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/E0719.rs:8:42
-   |
-LL | fn test() -> Box<dyn Iterator<Item = (), Item = Unit>> {
-   |                               ---------  ^^^^^^^^^^^ re-bound here
-   |                               |
-   |                               `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/E0719.rs:1:33
    |
 LL | trait Foo: Iterator<Item = i32, Item = i32> {}
@@ -35,6 +27,14 @@ LL | trait Foo: Iterator<Item = i32, Item = i32> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+  --> $DIR/E0719.rs:8:42
+   |
+LL | fn test() -> Box<dyn Iterator<Item = (), Item = Unit>> {
+   |                               ---------  ^^^^^^^^^^^ re-bound here
+   |                               |
+   |                               `Item` bound here first
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/E0719.rs:14:38
    |
 LL |     let _: &dyn Iterator<Item = i32, Item = i32>;
diff --git a/tests/ui/feature-gates/feature-gate-asm_goto.rs b/tests/ui/feature-gates/feature-gate-asm_goto.rs
new file mode 100644
index 00000000000..beac4590349
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-asm_goto.rs
@@ -0,0 +1,10 @@
+//@ only-x86_64
+
+use std::arch::asm;
+
+fn main() {
+    unsafe {
+        asm!("jmp {}", label {});
+        //~^ ERROR label operands for inline assembly are unstable
+    }
+}
diff --git a/tests/ui/feature-gates/feature-gate-asm_goto.stderr b/tests/ui/feature-gates/feature-gate-asm_goto.stderr
new file mode 100644
index 00000000000..62fd1a320d3
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-asm_goto.stderr
@@ -0,0 +1,13 @@
+error[E0658]: label operands for inline assembly are unstable
+  --> $DIR/feature-gate-asm_goto.rs:7:24
+   |
+LL |         asm!("jmp {}", label {});
+   |                        ^^^^^^^^
+   |
+   = note: see issue #119364 <https://github.com/rust-lang/rust/issues/119364> for more information
+   = help: add `#![feature(asm_goto)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr
index 7dfd79c7286..d8a85c8838d 100644
--- a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr
+++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr
@@ -18,6 +18,14 @@ LL |     type Bop = impl std::fmt::Debug;
    = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
+error: unconstrained opaque type
+  --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:6:16
+   |
+LL |     type Bar = impl std::fmt::Debug;
+   |                ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Bar` must be used in combination with a concrete type within the same impl
+
 error[E0658]: inherent associated types are unstable
   --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:14:5
    |
@@ -29,14 +37,6 @@ LL |     type Bop = impl std::fmt::Debug;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error: unconstrained opaque type
-  --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:6:16
-   |
-LL |     type Bar = impl std::fmt::Debug;
-   |                ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `Bar` must be used in combination with a concrete type within the same impl
-
-error: unconstrained opaque type
   --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:14:16
    |
 LL |     type Bop = impl std::fmt::Debug;
diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
index 5d598ec2969..c3f161469e3 100644
--- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
+++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
@@ -56,26 +56,6 @@ LL | impl Fn<()> for Foo {
    |
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-error[E0183]: manual implementations of `FnOnce` are experimental
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
-   |
-LL | impl FnOnce() for Foo1 {
-   |      ^^^^^^^^ manual implementations of `FnOnce` are experimental
-   |
-   = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-
-error[E0229]: associated type bindings are not allowed here
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
-   |
-LL | impl FnOnce() for Foo1 {
-   |      ^^^^^^^^ associated type not allowed here
-   |
-help: parenthesized trait syntax expands to `FnOnce<(), Output=()>`
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
-   |
-LL | impl FnOnce() for Foo1 {
-   |      ^^^^^^^^
-
 error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:26:6
    |
@@ -94,24 +74,6 @@ LL | impl FnMut<()> for Bar {
    |
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:35:6
-   |
-LL | impl FnOnce<()> for Baz {
-   |      ^^^^^^^^^^
-   |
-   = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
-   = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0183]: manual implementations of `FnOnce` are experimental
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:35:6
-   |
-LL | impl FnOnce<()> for Baz {
-   |      ^^^^^^^^^^ manual implementations of `FnOnce` are experimental
-   |
-   = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-
 error[E0277]: expected a `FnMut()` closure, found `Foo`
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:9:17
    |
@@ -135,6 +97,44 @@ LL |     extern "rust-call" fn call(self, args: ()) -> () {}
    = note: expected signature `extern "rust-call" fn(&Foo, ()) -> _`
               found signature `extern "rust-call" fn(Foo, ())`
 
+error[E0183]: manual implementations of `FnOnce` are experimental
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
+   |
+LL | impl FnOnce() for Foo1 {
+   |      ^^^^^^^^ manual implementations of `FnOnce` are experimental
+   |
+   = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
+
+error[E0229]: associated type bindings are not allowed here
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
+   |
+LL | impl FnOnce() for Foo1 {
+   |      ^^^^^^^^ associated type not allowed here
+   |
+help: parenthesized trait syntax expands to `FnOnce<(), Output=()>`
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
+   |
+LL | impl FnOnce() for Foo1 {
+   |      ^^^^^^^^
+
+error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:35:6
+   |
+LL | impl FnOnce<()> for Baz {
+   |      ^^^^^^^^^^
+   |
+   = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
+   = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0183]: manual implementations of `FnOnce` are experimental
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:35:6
+   |
+LL | impl FnOnce<()> for Baz {
+   |      ^^^^^^^^^^ manual implementations of `FnOnce` are experimental
+   |
+   = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
+
 error[E0046]: not all trait items implemented, missing: `Output`
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:1
    |
diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
index 8589d008a6b..65854ed7158 100644
--- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
+++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
@@ -1,3 +1,23 @@
+error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+  --> $DIR/gat-trait-path-missing-lifetime.rs:8:10
+   |
+LL |   fn foo<'a>(t : Self::Y<'a>) -> Self::Y<'a> { t }
+   |          -- expected 0 type parameters
+...
+LL |   fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
+   |          ^^  ^^
+   |          |
+   |          found 1 type parameter
+
+error[E0046]: not all trait items implemented, missing: `Y`
+  --> $DIR/gat-trait-path-missing-lifetime.rs:7:1
+   |
+LL |   type Y<'a>;
+   |   ---------- `Y` from trait
+...
+LL | impl<T> X for T {
+   | ^^^^^^^^^^^^^^^ missing `Y` in implementation
+
 error[E0107]: missing generics for associated type `X::Y`
   --> $DIR/gat-trait-path-missing-lifetime.rs:8:20
    |
@@ -31,26 +51,6 @@ help: add missing lifetime argument
 LL |   fn foo<'a, T1: X<Y<'a> = T1>>(t : T1) -> T1::Y<'a> {
    |                     ++++
 
-error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
-  --> $DIR/gat-trait-path-missing-lifetime.rs:8:10
-   |
-LL |   fn foo<'a>(t : Self::Y<'a>) -> Self::Y<'a> { t }
-   |          -- expected 0 type parameters
-...
-LL |   fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
-   |          ^^  ^^
-   |          |
-   |          found 1 type parameter
-
-error[E0046]: not all trait items implemented, missing: `Y`
-  --> $DIR/gat-trait-path-missing-lifetime.rs:7:1
-   |
-LL |   type Y<'a>;
-   |   ---------- `Y` from trait
-...
-LL | impl<T> X for T {
-   | ^^^^^^^^^^^^^^^ missing `Y` in implementation
-
 error: lifetime may not live long enough
   --> $DIR/gat-trait-path-missing-lifetime.rs:8:3
    |
diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
index bad2ae9c918..fcd3e7d9aac 100644
--- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
+++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
@@ -54,22 +54,6 @@ LL |   type Y<'a>;
    |        ^
 
 error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
-  --> $DIR/gat-trait-path-parenthesised-args.rs:18:27
-   |
-LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
-   |                           ^ expected 1 lifetime argument
-   |
-note: associated type defined here, with 1 lifetime parameter: `'a`
-  --> $DIR/gat-trait-path-parenthesised-args.rs:2:8
-   |
-LL |   type Y<'a>;
-   |        ^ --
-help: add missing lifetime argument
-   |
-LL | fn bar<'a>(arg: Box<dyn X<Y('_) = ()>>) {}
-   |                             ++
-
-error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/gat-trait-path-parenthesised-args.rs:5:27
    |
 LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
@@ -165,6 +149,22 @@ note: associated type defined here, with 1 lifetime parameter: `'a`
    |
 LL |   type Y<'a>;
    |        ^ --
+help: add missing lifetime argument
+   |
+LL | fn bar<'a>(arg: Box<dyn X<Y('_) = ()>>) {}
+   |                             ++
+
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+  --> $DIR/gat-trait-path-parenthesised-args.rs:18:27
+   |
+LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
+   |                           ^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/gat-trait-path-parenthesised-args.rs:2:8
+   |
+LL |   type Y<'a>;
+   |        ^ --
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: add missing lifetime argument
    |
diff --git a/tests/ui/generic-associated-types/issue-80433.stderr b/tests/ui/generic-associated-types/issue-80433.stderr
index 2bbf87ff1ff..1ca080f5df2 100644
--- a/tests/ui/generic-associated-types/issue-80433.stderr
+++ b/tests/ui/generic-associated-types/issue-80433.stderr
@@ -1,3 +1,14 @@
+error: missing required bound on `Output`
+  --> $DIR/issue-80433.rs:7:5
+   |
+LL |     type Output<'a>;
+   |     ^^^^^^^^^^^^^^^-
+   |                    |
+   |                    help: add the required where clause: `where Self: 'a`
+   |
+   = note: this bound is currently required to ensure that impls have maximum flexibility
+   = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
 error[E0107]: missing generics for associated type `TestMut::Output`
   --> $DIR/issue-80433.rs:21:47
    |
@@ -14,17 +25,6 @@ help: add missing lifetime argument
 LL | fn test_simpler<'a>(dst: &'a mut impl TestMut<Output<'a> = &'a mut f32>)
    |                                                     ++++
 
-error: missing required bound on `Output`
-  --> $DIR/issue-80433.rs:7:5
-   |
-LL |     type Output<'a>;
-   |     ^^^^^^^^^^^^^^^-
-   |                    |
-   |                    help: add the required where clause: `where Self: 'a`
-   |
-   = note: this bound is currently required to ensure that impls have maximum flexibility
-   = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
-
 error[E0499]: cannot borrow `*dst` as mutable more than once at a time
   --> $DIR/issue-80433.rs:25:10
    |
diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.stderr b/tests/ui/generic-associated-types/missing_lifetime_args.stderr
index 5980c60c51c..18c2d8c7eed 100644
--- a/tests/ui/generic-associated-types/missing_lifetime_args.stderr
+++ b/tests/ui/generic-associated-types/missing_lifetime_args.stderr
@@ -14,42 +14,6 @@ help: add missing lifetime arguments
 LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y<'_, '_> = (&'c u32, &'d u32)>>) {}
    |                                 ++++++++
 
-error[E0107]: struct takes 3 lifetime arguments but 2 lifetime arguments were supplied
-  --> $DIR/missing_lifetime_args.rs:17:26
-   |
-LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {}
-   |                          ^^^ --  -- supplied 2 lifetime arguments
-   |                          |
-   |                          expected 3 lifetime arguments
-   |
-note: struct defined here, with 3 lifetime parameters: `'a`, `'b`, `'c`
-  --> $DIR/missing_lifetime_args.rs:5:8
-   |
-LL | struct Foo<'a, 'b, 'c> {
-   |        ^^^ --  --  --
-help: add missing lifetime argument
-   |
-LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b, 'a>) {}
-   |                                    ++++
-
-error[E0107]: struct takes 3 lifetime arguments but 1 lifetime argument was supplied
-  --> $DIR/missing_lifetime_args.rs:20:16
-   |
-LL | fn f<'a>(_arg: Foo<'a>) {}
-   |                ^^^ -- supplied 1 lifetime argument
-   |                |
-   |                expected 3 lifetime arguments
-   |
-note: struct defined here, with 3 lifetime parameters: `'a`, `'b`, `'c`
-  --> $DIR/missing_lifetime_args.rs:5:8
-   |
-LL | struct Foo<'a, 'b, 'c> {
-   |        ^^^ --  --  --
-help: add missing lifetime arguments
-   |
-LL | fn f<'a>(_arg: Foo<'a, 'a, 'a>) {}
-   |                      ++++++++
-
 error[E0107]: missing generics for associated type `X::Y`
   --> $DIR/missing_lifetime_args.rs:11:32
    |
@@ -99,6 +63,42 @@ LL |     type Y<'a, 'b>;
    |          ^ ...because it contains the generic associated type `Y`
    = help: consider moving `Y` to another trait
 
+error[E0107]: struct takes 3 lifetime arguments but 2 lifetime arguments were supplied
+  --> $DIR/missing_lifetime_args.rs:17:26
+   |
+LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {}
+   |                          ^^^ --  -- supplied 2 lifetime arguments
+   |                          |
+   |                          expected 3 lifetime arguments
+   |
+note: struct defined here, with 3 lifetime parameters: `'a`, `'b`, `'c`
+  --> $DIR/missing_lifetime_args.rs:5:8
+   |
+LL | struct Foo<'a, 'b, 'c> {
+   |        ^^^ --  --  --
+help: add missing lifetime argument
+   |
+LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b, 'a>) {}
+   |                                    ++++
+
+error[E0107]: struct takes 3 lifetime arguments but 1 lifetime argument was supplied
+  --> $DIR/missing_lifetime_args.rs:20:16
+   |
+LL | fn f<'a>(_arg: Foo<'a>) {}
+   |                ^^^ -- supplied 1 lifetime argument
+   |                |
+   |                expected 3 lifetime arguments
+   |
+note: struct defined here, with 3 lifetime parameters: `'a`, `'b`, `'c`
+  --> $DIR/missing_lifetime_args.rs:5:8
+   |
+LL | struct Foo<'a, 'b, 'c> {
+   |        ^^^ --  --  --
+help: add missing lifetime arguments
+   |
+LL | fn f<'a>(_arg: Foo<'a, 'a, 'a>) {}
+   |                      ++++++++
+
 error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0038, E0107.
diff --git a/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.rs b/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.rs
index cd3acf9bc41..f74d7cf2811 100644
--- a/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.rs
+++ b/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.rs
@@ -1,16 +1,10 @@
 trait Foo {
+    //~^ ERROR cycle detected
     type Context<'c>
     where
         Self: 'c;
 }
 
 impl Foo for Box<dyn Foo> {}
-//~^ ERROR `Foo` cannot be made into an object
-//~| ERROR `Foo` cannot be made into an object
-//~| ERROR cycle detected
-//~| ERROR cycle detected
-//~| ERROR cycle detected
-//~| ERROR the trait bound `Box<(dyn Foo + 'static)>: Foo` is not satisfied
-//~| ERROR not all trait items implemented
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.stderr b/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.stderr
index 8e6b69f7461..29b226f16cb 100644
--- a/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.stderr
+++ b/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.stderr
@@ -1,119 +1,22 @@
-error[E0391]: cycle detected when computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:7:1: 7:26>`
-  --> $DIR/unknown-lifetime-ice-119827.rs:7:1
-   |
-LL | impl Foo for Box<dyn Foo> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires finding trait impls of `Foo`...
+error[E0391]: cycle detected when finding trait impls of `Foo`
   --> $DIR/unknown-lifetime-ice-119827.rs:1:1
    |
 LL | trait Foo {
    | ^^^^^^^^^
-   = note: ...which again requires computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:7:1: 7:26>`, completing the cycle
-note: cycle used when collecting item types in top-level module
-  --> $DIR/unknown-lifetime-ice-119827.rs:1:1
    |
-LL | / trait Foo {
-LL | |     type Context<'c>
-LL | |     where
-LL | |         Self: 'c;
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-error[E0391]: cycle detected when computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:7:1: 7:26>`
-  --> $DIR/unknown-lifetime-ice-119827.rs:7:1
+note: ...which requires computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:8:1: 8:26>`...
+  --> $DIR/unknown-lifetime-ice-119827.rs:8:1
    |
 LL | impl Foo for Box<dyn Foo> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: ...which immediately requires computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:7:1: 7:26>` again
-note: cycle used when collecting item types in top-level module
+   = note: ...which again requires finding trait impls of `Foo`, completing the cycle
+note: cycle used when checking that `Foo` is well-formed
   --> $DIR/unknown-lifetime-ice-119827.rs:1:1
    |
-LL | / trait Foo {
-LL | |     type Context<'c>
-LL | |     where
-LL | |         Self: 'c;
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-error[E0391]: cycle detected when computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:7:1: 7:26>`
-  --> $DIR/unknown-lifetime-ice-119827.rs:7:1
-   |
-LL | impl Foo for Box<dyn Foo> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: ...which immediately requires computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:7:1: 7:26>` again
-note: cycle used when collecting item types in top-level module
-  --> $DIR/unknown-lifetime-ice-119827.rs:1:1
-   |
-LL | / trait Foo {
-LL | |     type Context<'c>
-LL | |     where
-LL | |         Self: 'c;
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/unknown-lifetime-ice-119827.rs:7:22
-   |
-LL | impl Foo for Box<dyn Foo> {}
-   |                      ^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/unknown-lifetime-ice-119827.rs:2:10
-   |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     type Context<'c>
-   |          ^^^^^^^ ...because it contains the generic associated type `Context`
-   = help: consider moving `Context` to another trait
-   = help: only type `{type error}` implements the trait, consider using it directly instead
-
-error[E0277]: the trait bound `Box<(dyn Foo + 'static)>: Foo` is not satisfied
-  --> $DIR/unknown-lifetime-ice-119827.rs:7:14
-   |
-LL | impl Foo for Box<dyn Foo> {}
-   |              ^^^^^^^^^^^^ the trait `Foo` is not implemented for `Box<(dyn Foo + 'static)>`
-   |
-   = help: the trait `Foo` is implemented for `Box<(dyn Foo + 'static)>`
-
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/unknown-lifetime-ice-119827.rs:7:14
-   |
-LL | impl Foo for Box<dyn Foo> {}
-   |              ^^^^^^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/unknown-lifetime-ice-119827.rs:2:10
-   |
 LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     type Context<'c>
-   |          ^^^^^^^ ...because it contains the generic associated type `Context`
-   = help: consider moving `Context` to another trait
-   = help: only type `std::boxed::Box<(dyn Foo + 'static)>` implements the trait, consider using it directly instead
-
-error[E0046]: not all trait items implemented, missing: `Context`
-  --> $DIR/unknown-lifetime-ice-119827.rs:7:1
-   |
-LL |     type Context<'c>
-   |     ---------------- `Context` from trait
-...
-LL | impl Foo for Box<dyn Foo> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Context` in implementation
+   | ^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error: aborting due to 7 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0038, E0046, E0277, E0391.
-For more information about an error, try `rustc --explain E0038`.
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs b/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs
index 06c3d9ad434..a9ea657f10e 100644
--- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs
+++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs
@@ -2,19 +2,19 @@
 use std::fmt::Debug;
 
 fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
-    //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+    //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
     |x| x
     //~^ ERROR lifetime may not live long enough
 }
 
 fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
-    //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+    //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
     |x| x
     //~^ ERROR lifetime may not live long enough
 }
 
 fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
-    //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+    //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
     |x| x
     //~^ ERROR lifetime may not live long enough
 }
diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
index ebab9940493..bdb099619b7 100644
--- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
+++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
@@ -10,7 +10,7 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're
 LL | fn d() -> impl Fn() -> (impl Debug + 'static) {
    |                                      ~~~~~~~
 
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/impl-fn-hrtb-bounds.rs:4:41
    |
 LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
@@ -22,7 +22,16 @@ note: lifetime declared here
 LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
    |                   ^
 
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error: lifetime may not live long enough
+  --> $DIR/impl-fn-hrtb-bounds.rs:6:9
+   |
+LL |     |x| x
+   |      -- ^ returning this value requires that `'1` must outlive `'2`
+   |      ||
+   |      |return type of closure is impl Debug + '2
+   |      has type `&'1 u8`
+
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/impl-fn-hrtb-bounds.rs:10:52
    |
 LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
@@ -34,7 +43,16 @@ note: lifetime declared here
 LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
    |                    ^^
 
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error: lifetime may not live long enough
+  --> $DIR/impl-fn-hrtb-bounds.rs:12:9
+   |
+LL |     |x| x
+   |      -- ^ returning this value requires that `'1` must outlive `'2`
+   |      ||
+   |      |return type of closure is impl Debug + '2
+   |      has type `&'1 u8`
+
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/impl-fn-hrtb-bounds.rs:16:52
    |
 LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
@@ -47,24 +65,6 @@ LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
    |                    ^^
 
 error: lifetime may not live long enough
-  --> $DIR/impl-fn-hrtb-bounds.rs:6:9
-   |
-LL |     |x| x
-   |      -- ^ returning this value requires that `'1` must outlive `'2`
-   |      ||
-   |      |return type of closure is impl Debug + '2
-   |      has type `&'1 u8`
-
-error: lifetime may not live long enough
-  --> $DIR/impl-fn-hrtb-bounds.rs:12:9
-   |
-LL |     |x| x
-   |      -- ^ returning this value requires that `'1` must outlive `'2`
-   |      ||
-   |      |return type of closure is impl Debug + '2
-   |      has type `&'1 u8`
-
-error: lifetime may not live long enough
   --> $DIR/impl-fn-hrtb-bounds.rs:18:9
    |
 LL |     |x| x
@@ -75,4 +75,5 @@ LL |     |x| x
 
 error: aborting due to 7 previous errors
 
-For more information about this error, try `rustc --explain E0106`.
+Some errors have detailed explanations: E0106, E0657.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs
index a4a1f1dcee1..ef9d8733509 100644
--- a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs
+++ b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs
@@ -3,7 +3,7 @@ use std::fmt::Debug;
 
 fn a() -> impl Fn(&u8) -> impl Debug + '_ {
     //~^ ERROR ambiguous `+` in a type
-    //~| ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+    //~| ERROR cannot capture higher-ranked lifetime from outer `impl Trait`
     |x| x
     //~^ ERROR lifetime may not live long enough
 }
diff --git a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr
index e18e89700b4..3881b37a0cb 100644
--- a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr
+++ b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr
@@ -10,7 +10,7 @@ error: ambiguous `+` in a type
 LL | fn b() -> impl Fn() -> impl Debug + Send {
    |                        ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)`
 
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/impl-fn-parsing-ambiguities.rs:4:40
    |
 LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
@@ -33,3 +33,4 @@ LL |     |x| x
 
 error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0657`.
diff --git a/tests/ui/impl-trait/implicit-capture-late.stderr b/tests/ui/impl-trait/implicit-capture-late.stderr
index 2fb5ebb6541..080750f8497 100644
--- a/tests/ui/impl-trait/implicit-capture-late.stderr
+++ b/tests/ui/impl-trait/implicit-capture-late.stderr
@@ -1,4 +1,10 @@
-error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
+  --> $DIR/implicit-capture-late.rs:10:55
+   |
+LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
+   |                                                       ^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
+   |
+note: lifetime declared here
   --> $DIR/implicit-capture-late.rs:10:36
    |
 LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
diff --git a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs
new file mode 100644
index 00000000000..6f0dbd752b0
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs
@@ -0,0 +1,18 @@
+struct Wrapper<'rom>(T);
+//~^ ERROR cannot find type `T` in this scope
+
+trait Foo {
+    fn bar() -> Wrapper<impl Sized>;
+    //~^ ERROR missing lifetime specifier
+    //~| ERROR struct takes 0 generic arguments but 1 generic argument was supplied
+}
+
+impl Foo for () {
+    fn bar() -> i32 {
+        //~^ ERROR method `bar` has an incompatible type for trait
+        //~| ERROR method `bar` has an incompatible return type for trait
+        0
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
new file mode 100644
index 00000000000..d30557c8a7b
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
@@ -0,0 +1,67 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/opaque-and-lifetime-mismatch.rs:5:24
+   |
+LL |     fn bar() -> Wrapper<impl Sized>;
+   |                        ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
+   |
+LL |     fn bar() -> Wrapper<'static, impl Sized>;
+   |                         ++++++++
+
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/opaque-and-lifetime-mismatch.rs:1:22
+   |
+LL | struct Wrapper<'rom>(T);
+   |                      ^ not found in this scope
+   |
+help: you might be missing a type parameter
+   |
+LL | struct Wrapper<'rom, T>(T);
+   |                    +++
+
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/opaque-and-lifetime-mismatch.rs:5:17
+   |
+LL |     fn bar() -> Wrapper<impl Sized>;
+   |                 ^^^^^^^ ---------- help: remove this generic argument
+   |                 |
+   |                 expected 0 generic arguments
+   |
+note: struct defined here, with 0 generic parameters
+  --> $DIR/opaque-and-lifetime-mismatch.rs:1:8
+   |
+LL | struct Wrapper<'rom>(T);
+   |        ^^^^^^^
+
+error[E0053]: method `bar` has an incompatible return type for trait
+  --> $DIR/opaque-and-lifetime-mismatch.rs:11:17
+   |
+LL |     fn bar() -> i32 {
+   |                 ^^^
+   |                 |
+   |                 expected `Wrapper<'static>`, found `i32`
+   |                 return type in trait
+
+error[E0053]: method `bar` has an incompatible type for trait
+  --> $DIR/opaque-and-lifetime-mismatch.rs:11:17
+   |
+LL |     fn bar() -> i32 {
+   |                 ^^^
+   |                 |
+   |                 expected `Wrapper<'static>`, found `i32`
+   |                 help: change the output type to match the trait: `Wrapper<'static>`
+   |
+note: type in trait
+  --> $DIR/opaque-and-lifetime-mismatch.rs:5:17
+   |
+LL |     fn bar() -> Wrapper<impl Sized>;
+   |                 ^^^^^^^^^^^^^^^^^^^
+   = note: expected signature `fn() -> Wrapper<'static>`
+              found signature `fn() -> i32`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0053, E0106, E0107, E0412.
+For more information about an error, try `rustc --explain E0053`.
diff --git a/tests/ui/impl-trait/issues/issue-54895.rs b/tests/ui/impl-trait/issues/issue-54895.rs
index 8d7a1d56f83..13c0038ce43 100644
--- a/tests/ui/impl-trait/issues/issue-54895.rs
+++ b/tests/ui/impl-trait/issues/issue-54895.rs
@@ -13,7 +13,7 @@ impl<'a> Trait<'a> for X {
 }
 
 fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
-    //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+    //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
     X(())
 }
 
diff --git a/tests/ui/impl-trait/issues/issue-54895.stderr b/tests/ui/impl-trait/issues/issue-54895.stderr
index 999ffd52141..64b425328e3 100644
--- a/tests/ui/impl-trait/issues/issue-54895.stderr
+++ b/tests/ui/impl-trait/issues/issue-54895.stderr
@@ -1,4 +1,4 @@
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/issue-54895.rs:15:53
    |
 LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
@@ -12,3 +12,4 @@ LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> {
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0657`.
diff --git a/tests/ui/impl-trait/issues/issue-67830.rs b/tests/ui/impl-trait/issues/issue-67830.rs
index 6dc8935c777..939eca82a8f 100644
--- a/tests/ui/impl-trait/issues/issue-67830.rs
+++ b/tests/ui/impl-trait/issues/issue-67830.rs
@@ -19,7 +19,7 @@ where
 
 struct A;
 fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
-    //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+    //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
     Wrap(|a| Some(a).into_iter())
     //~^ ERROR implementation of `FnOnce` is not general enough
     //~| ERROR implementation of `FnOnce` is not general enough
diff --git a/tests/ui/impl-trait/issues/issue-67830.stderr b/tests/ui/impl-trait/issues/issue-67830.stderr
index 546198b8a10..ef513a40cf3 100644
--- a/tests/ui/impl-trait/issues/issue-67830.stderr
+++ b/tests/ui/impl-trait/issues/issue-67830.stderr
@@ -1,4 +1,4 @@
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/issue-67830.rs:21:62
    |
 LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> {
@@ -31,3 +31,4 @@ LL |     Wrap(|a| Some(a).into_iter())
 
 error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0657`.
diff --git a/tests/ui/impl-trait/issues/issue-88236-2.rs b/tests/ui/impl-trait/issues/issue-88236-2.rs
index f4354d1b2ae..7ff08d8174f 100644
--- a/tests/ui/impl-trait/issues/issue-88236-2.rs
+++ b/tests/ui/impl-trait/issues/issue-88236-2.rs
@@ -13,17 +13,17 @@ impl<'a> Hrtb<'a> for &'a () {
 }
 
 fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
-//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
 
 fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
-    //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+    //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
     &()
     //~^ ERROR implementation of `Hrtb` is not general enough
     //~| ERROR implementation of `Hrtb` is not general enough
 }
 
 fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
-    //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+    //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
     x
     //~^ ERROR implementation of `Hrtb` is not general enough
     //~| ERROR implementation of `Hrtb` is not general enough
diff --git a/tests/ui/impl-trait/issues/issue-88236-2.stderr b/tests/ui/impl-trait/issues/issue-88236-2.stderr
index 1e63338d6d1..09fd58056a5 100644
--- a/tests/ui/impl-trait/issues/issue-88236-2.stderr
+++ b/tests/ui/impl-trait/issues/issue-88236-2.stderr
@@ -1,4 +1,4 @@
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/issue-88236-2.rs:15:61
    |
 LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
@@ -10,7 +10,7 @@ note: lifetime declared here
 LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
    |                            ^^
 
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/issue-88236-2.rs:18:80
    |
 LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
@@ -22,18 +22,6 @@ note: lifetime declared here
 LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
    |                                               ^^
 
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
-  --> $DIR/issue-88236-2.rs:25:78
-   |
-LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
-   |                                                                              ^^
-   |
-note: lifetime declared here
-  --> $DIR/issue-88236-2.rs:25:45
-   |
-LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
-   |                                             ^^
-
 error: implementation of `Hrtb` is not general enough
   --> $DIR/issue-88236-2.rs:20:5
    |
@@ -52,6 +40,18 @@ LL |     &()
    = note: `Hrtb<'a>` would have to be implemented for the type `&()`
    = note: ...but `Hrtb<'0>` is actually implemented for the type `&'0 ()`, for some specific lifetime `'0`
 
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
+  --> $DIR/issue-88236-2.rs:25:78
+   |
+LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
+   |                                                                              ^^
+   |
+note: lifetime declared here
+  --> $DIR/issue-88236-2.rs:25:45
+   |
+LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
+   |                                             ^^
+
 error: lifetime may not live long enough
   --> $DIR/issue-88236-2.rs:27:5
    |
@@ -90,3 +90,4 @@ LL |     x
 
 error: aborting due to 8 previous errors
 
+For more information about this error, try `rustc --explain E0657`.
diff --git a/tests/ui/impl-trait/issues/issue-88236.rs b/tests/ui/impl-trait/issues/issue-88236.rs
index 36d12417354..e782a876573 100644
--- a/tests/ui/impl-trait/issues/issue-88236.rs
+++ b/tests/ui/impl-trait/issues/issue-88236.rs
@@ -13,6 +13,6 @@ impl<'a> Hrtb<'a> for &'a () {
 }
 
 fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
-//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
 
 fn main() {}
diff --git a/tests/ui/impl-trait/issues/issue-88236.stderr b/tests/ui/impl-trait/issues/issue-88236.stderr
index 6cf1a42d6a9..5dee5f88c89 100644
--- a/tests/ui/impl-trait/issues/issue-88236.stderr
+++ b/tests/ui/impl-trait/issues/issue-88236.stderr
@@ -1,4 +1,4 @@
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/issue-88236.rs:15:61
    |
 LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
@@ -12,3 +12,4 @@ LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0657`.
diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.rs b/tests/ui/impl-trait/nested-rpit-hrtb.rs
index a3eca741daa..c10bfbfe4dc 100644
--- a/tests/ui/impl-trait/nested-rpit-hrtb.rs
+++ b/tests/ui/impl-trait/nested-rpit-hrtb.rs
@@ -23,18 +23,18 @@ impl Qux<'_> for () {}
 
 // This is not supported.
 fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
-//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
 
 // This is not supported.
 fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
-//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
 
 fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
-//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
 //~| ERROR implementation of `Bar` is not general enough
 
 fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
-//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
 //~| ERROR: the trait bound `for<'a> &'a (): Qux<'_>` is not satisfied
 
 // This should resolve.
diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.stderr b/tests/ui/impl-trait/nested-rpit-hrtb.stderr
index 0e0f76874e3..2779694a517 100644
--- a/tests/ui/impl-trait/nested-rpit-hrtb.stderr
+++ b/tests/ui/impl-trait/nested-rpit-hrtb.stderr
@@ -29,7 +29,7 @@ help: consider introducing lifetime `'b` here
 LL | fn two_htrb_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
    |                          ++++
 
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/nested-rpit-hrtb.rs:25:69
    |
 LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
@@ -41,7 +41,7 @@ note: lifetime declared here
 LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {}
    |                                    ^^
 
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/nested-rpit-hrtb.rs:29:68
    |
 LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
@@ -53,7 +53,7 @@ note: lifetime declared here
 LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {}
    |                                       ^^
 
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/nested-rpit-hrtb.rs:32:74
    |
 LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
@@ -65,7 +65,16 @@ note: lifetime declared here
 LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
    |                                         ^^
 
-error: higher kinded lifetime bounds on nested opaque types are not supported yet
+error: implementation of `Bar` is not general enough
+  --> $DIR/nested-rpit-hrtb.rs:32:78
+   |
+LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
+   |                                                                              ^^ implementation of `Bar` is not general enough
+   |
+   = note: `()` must implement `Bar<'a>`
+   = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0`
+
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
   --> $DIR/nested-rpit-hrtb.rs:36:73
    |
 LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
@@ -77,15 +86,6 @@ note: lifetime declared here
 LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
    |                                            ^^
 
-error: implementation of `Bar` is not general enough
-  --> $DIR/nested-rpit-hrtb.rs:32:78
-   |
-LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
-   |                                                                              ^^ implementation of `Bar` is not general enough
-   |
-   = note: `()` must implement `Bar<'a>`
-   = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0`
-
 error[E0277]: the trait bound `for<'a> &'a (): Qux<'_>` is not satisfied
   --> $DIR/nested-rpit-hrtb.rs:36:64
    |
@@ -133,5 +133,5 @@ LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Si
 
 error: aborting due to 12 previous errors
 
-Some errors have detailed explanations: E0261, E0277.
+Some errors have detailed explanations: E0261, E0277, E0657.
 For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr
index e82f33ad6bc..bffe0447f8b 100644
--- a/tests/ui/impl-trait/where-allowed.stderr
+++ b/tests/ui/impl-trait/where-allowed.stderr
@@ -342,25 +342,6 @@ LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
-error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:239:7
-   |
-LL | impl <T = impl Debug> T {}
-   |       ^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
-   = note: `#[deny(invalid_type_param_default)]` on by default
-
-error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:246:36
-   |
-LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
-   |                                    ^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
-
 error[E0283]: type annotations needed
   --> $DIR/where-allowed.rs:46:57
    |
@@ -381,6 +362,16 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani
            - impl<Args, F, A> Fn<Args> for Box<F, A>
              where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
 
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+  --> $DIR/where-allowed.rs:239:7
+   |
+LL | impl <T = impl Debug> T {}
+   |       ^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
+   = note: `#[deny(invalid_type_param_default)]` on by default
+
 error[E0118]: no nominal type found for inherent implementation
   --> $DIR/where-allowed.rs:239:1
    |
@@ -428,6 +419,15 @@ LL |     type Out = impl Debug;
    |
    = note: `Out` must be used in combination with a concrete type within the same impl
 
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+  --> $DIR/where-allowed.rs:246:36
+   |
+LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
+   |                                    ^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
+
 error: aborting due to 50 previous errors
 
 Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0599, E0658, E0666.
diff --git a/tests/ui/infinite/infinite-trait-alias-recursion.stderr b/tests/ui/infinite/infinite-trait-alias-recursion.stderr
index 220d81031ac..b3980cb935e 100644
--- a/tests/ui/infinite/infinite-trait-alias-recursion.stderr
+++ b/tests/ui/infinite/infinite-trait-alias-recursion.stderr
@@ -16,7 +16,7 @@ LL | trait T3 = T1 + T3;
    |            ^^
    = note: ...which again requires computing the super predicates of `T1`, completing the cycle
    = note: trait aliases cannot be recursive
-note: cycle used when collecting item types in top-level module
+note: cycle used when checking that `T1` is well-formed
   --> $DIR/infinite-trait-alias-recursion.rs:3:1
    |
 LL | trait T1 = T2;
diff --git a/tests/ui/infinite/infinite-type-alias-mutual-recursion.gated.stderr b/tests/ui/infinite/infinite-type-alias-mutual-recursion.gated.stderr
index 57ca1b24d2a..ab1bcc44cb8 100644
--- a/tests/ui/infinite/infinite-type-alias-mutual-recursion.gated.stderr
+++ b/tests/ui/infinite/infinite-type-alias-mutual-recursion.gated.stderr
@@ -18,17 +18,11 @@ LL | type X3 = X1;
    = note: type aliases cannot be recursive
    = help: consider using a struct, enum, or union instead to break the cycle
    = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
-note: cycle used when collecting item types in top-level module
-  --> $DIR/infinite-type-alias-mutual-recursion.rs:3:1
+note: cycle used when checking that `X1` is well-formed
+  --> $DIR/infinite-type-alias-mutual-recursion.rs:6:1
    |
-LL | / #![cfg_attr(feature, feature(lazy_type_alias))]
-LL | | #![allow(incomplete_features)]
-LL | |
-LL | | type X1 = X2;
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
+LL | type X1 = X2;
+   | ^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/infinite/infinite-vec-type-recursion.gated.stderr b/tests/ui/infinite/infinite-vec-type-recursion.gated.stderr
index efafc9b75cd..43364892bb5 100644
--- a/tests/ui/infinite/infinite-vec-type-recursion.gated.stderr
+++ b/tests/ui/infinite/infinite-vec-type-recursion.gated.stderr
@@ -8,17 +8,11 @@ LL | type X = Vec<X>;
    = note: type aliases cannot be recursive
    = help: consider using a struct, enum, or union instead to break the cycle
    = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
-note: cycle used when collecting item types in top-level module
-  --> $DIR/infinite-vec-type-recursion.rs:3:1
+note: cycle used when checking that `X` is well-formed
+  --> $DIR/infinite-vec-type-recursion.rs:6:1
    |
-LL | / #![cfg_attr(feature, feature(lazy_type_alias))]
-LL | | #![allow(incomplete_features)]
-LL | |
-LL | | type X = Vec<X>;
-...  |
-LL | | #[rustfmt::skip]
-LL | | fn main() { let b: X = Vec::new(); }
-   | |____________________________________^
+LL | type X = Vec<X>;
+   | ^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/issues/issue-20831-debruijn.stderr b/tests/ui/issues/issue-20831-debruijn.stderr
index 7d1e19b7e47..60721f001b7 100644
--- a/tests/ui/issues/issue-20831-debruijn.stderr
+++ b/tests/ui/issues/issue-20831-debruijn.stderr
@@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
 LL |     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: first, the lifetime cannot outlive the anonymous lifetime defined here...
-  --> $DIR/issue-20831-debruijn.rs:28:58
+note: first, the lifetime cannot outlive the anonymous lifetime as defined here...
+  --> $DIR/issue-20831-debruijn.rs:28:18
    |
 LL |     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
-   |                                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^
 note: ...but the lifetime must also be valid for the lifetime `'a` as defined here...
   --> $DIR/issue-20831-debruijn.rs:26:6
    |
diff --git a/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-1.stderr b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-1.stderr
index 53131f9130d..234060ab5c8 100644
--- a/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-1.stderr
+++ b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-1.stderr
@@ -10,15 +10,11 @@ note: ...which requires const-evaluating + checking `X::A::{constant#0}`...
 LL |     A = X::A as isize,
    |         ^^^^^^^^^^^^^
    = note: ...which again requires simplifying constant for the type system `X::A::{constant#0}`, completing the cycle
-note: cycle used when collecting item types in top-level module
+note: cycle used when checking that `X` is well-formed
   --> $DIR/issue-23302-1.rs:3:1
    |
-LL | / enum X {
-LL | |     A = X::A as isize,
-LL | | }
-LL | |
-LL | | fn main() { }
-   | |_____________^
+LL | enum X {
+   | ^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-2.stderr b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-2.stderr
index d55d88762be..9bd95239c83 100644
--- a/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-2.stderr
+++ b/tests/ui/issues/issue-23302-enum-infinite-recursion/issue-23302-2.stderr
@@ -10,16 +10,11 @@ note: ...which requires const-evaluating + checking `Y::A::{constant#0}`...
 LL |     A = Y::B as isize,
    |         ^^^^^^^^^^^^^
    = note: ...which again requires simplifying constant for the type system `Y::A::{constant#0}`, completing the cycle
-note: cycle used when collecting item types in top-level module
+note: cycle used when checking that `Y` is well-formed
   --> $DIR/issue-23302-2.rs:3:1
    |
-LL | / enum Y {
-LL | |     A = Y::B as isize,
-LL | |     B,
-LL | | }
-LL | |
-LL | | fn main() { }
-   | |_____________^
+LL | enum Y {
+   | ^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/issues/issue-34373.stderr b/tests/ui/issues/issue-34373.stderr
index 13667cd920e..784fe935bf8 100644
--- a/tests/ui/issues/issue-34373.stderr
+++ b/tests/ui/issues/issue-34373.stderr
@@ -10,17 +10,11 @@ note: ...which requires expanding type alias `DefaultFoo`...
 LL | type DefaultFoo = Foo;
    |                   ^^^
    = note: ...which again requires computing type of `Foo::T`, completing the cycle
-note: cycle used when collecting item types in top-level module
-  --> $DIR/issue-34373.rs:1:1
-   |
-LL | / #![allow(warnings)]
-LL | |
-LL | | trait Trait<T> {
-LL | |     fn foo(_: T) {}
-...  |
-LL | | fn main() {
-LL | | }
-   | |_^
+note: cycle used when checking that `Foo` is well-formed
+  --> $DIR/issue-34373.rs:7:1
+   |
+LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error[E0038]: the trait `Trait` cannot be made into an object
diff --git a/tests/ui/layout/issue-84108.rs b/tests/ui/layout/issue-84108.rs
index 44d6ac8db72..425da65b990 100644
--- a/tests/ui/layout/issue-84108.rs
+++ b/tests/ui/layout/issue-84108.rs
@@ -11,4 +11,5 @@ const BAR: (&Path, [u8], usize) = ("hello", [], 42);
 
 static BAZ: ([u8], usize) = ([], 0);
 //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+//~| ERROR the size for values of type `[u8]` cannot be known at compilation time
 //~| ERROR mismatched types
diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr
index 58bddb069fc..6c168cc5fa8 100644
--- a/tests/ui/layout/issue-84108.stderr
+++ b/tests/ui/layout/issue-84108.stderr
@@ -29,6 +29,16 @@ LL | static BAZ: ([u8], usize) = ([], 0);
    = help: the trait `Sized` is not implemented for `[u8]`
    = note: only the last element of a tuple may have a dynamically sized type
 
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/issue-84108.rs:12:13
+   |
+LL | static BAZ: ([u8], usize) = ([], 0);
+   |             ^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+   = note: only the last element of a tuple may have a dynamically sized type
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0308]: mismatched types
   --> $DIR/issue-84108.rs:12:30
    |
@@ -38,7 +48,7 @@ LL | static BAZ: ([u8], usize) = ([], 0);
    = note: expected slice `[u8]`
               found array `[_; 0]`
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0277, E0308, E0412.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/lifetimes/issue-95023.stderr b/tests/ui/lifetimes/issue-95023.stderr
index 0c67d7328f2..c4285dbf4bd 100644
--- a/tests/ui/lifetimes/issue-95023.stderr
+++ b/tests/ui/lifetimes/issue-95023.stderr
@@ -32,12 +32,6 @@ help: parenthesized trait syntax expands to `Fn<(&isize,), Output=()>`
 LL | impl Fn(&isize) for Error {
    |      ^^^^^^^^^^
 
-error[E0220]: associated type `B` not found for `Self`
-  --> $DIR/issue-95023.rs:8:44
-   |
-LL |     fn foo<const N: usize>(&self) -> Self::B<{ N }>;
-   |                                            ^ help: `Self` has the following associated type: `Output`
-
 error[E0277]: expected a `FnMut(&isize)` closure, found `Error`
   --> $DIR/issue-95023.rs:3:21
    |
@@ -61,6 +55,12 @@ error[E0220]: associated type `B` not found for `Self`
    |
 LL |     fn foo<const N: usize>(&self) -> Self::B<{ N }>;
    |                                            ^ help: `Self` has the following associated type: `Output`
+
+error[E0220]: associated type `B` not found for `Self`
+  --> $DIR/issue-95023.rs:8:44
+   |
+LL |     fn foo<const N: usize>(&self) -> Self::B<{ N }>;
+   |                                            ^ help: `Self` has the following associated type: `Output`
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
diff --git a/tests/ui/lifetimes/missing-lifetime-in-alias.stderr b/tests/ui/lifetimes/missing-lifetime-in-alias.stderr
index 9183e6302ee..b868d4b15a1 100644
--- a/tests/ui/lifetimes/missing-lifetime-in-alias.stderr
+++ b/tests/ui/lifetimes/missing-lifetime-in-alias.stderr
@@ -25,22 +25,6 @@ help: consider using one of the available lifetimes here
 LL | type C<'a, 'b> = <A<'a> as Trait<'lifetime>>::Bar;
    |                                 +++++++++++
 
-error[E0107]: missing generics for associated type `Trait::Bar`
-  --> $DIR/missing-lifetime-in-alias.rs:27:36
-   |
-LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
-   |                                    ^^^ expected 1 lifetime argument
-   |
-note: associated type defined here, with 1 lifetime parameter: `'b`
-  --> $DIR/missing-lifetime-in-alias.rs:4:10
-   |
-LL |     type Bar<'b>
-   |          ^^^ --
-help: add missing lifetime argument
-   |
-LL | type C<'a, 'b> = <A<'a> as Trait>::Bar<'a>;
-   |                                       ++++
-
 error[E0477]: the type `Impl<'a>` does not fulfill the required lifetime
   --> $DIR/missing-lifetime-in-alias.rs:16:20
    |
@@ -60,6 +44,22 @@ help: copy the `where` clause predicates from the trait
 LL |     type Bar<'b> = &'b () where Self: 'b;
    |                           ++++++++++++++
 
+error[E0107]: missing generics for associated type `Trait::Bar`
+  --> $DIR/missing-lifetime-in-alias.rs:27:36
+   |
+LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
+   |                                    ^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'b`
+  --> $DIR/missing-lifetime-in-alias.rs:4:10
+   |
+LL |     type Bar<'b>
+   |          ^^^ --
+help: add missing lifetime argument
+   |
+LL | type C<'a, 'b> = <A<'a> as Trait>::Bar<'a>;
+   |                                       ++++
+
 error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0106, E0107, E0477.
diff --git a/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr b/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr
index e7fcdbd0c9c..6beb04e5b93 100644
--- a/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr
+++ b/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr
@@ -1,21 +1,3 @@
-error[E0038]: the trait `Baz` cannot be made into an object
-  --> $DIR/object-safety-supertrait-mentions-Self.rs:16:31
-   |
-LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
-   |                               ^^^^^^^ `Baz` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety-supertrait-mentions-Self.rs:8:13
-   |
-LL | trait Baz : Bar<Self> {
-   |       ---   ^^^^^^^^^ ...because it uses `Self` as a type parameter
-   |       |
-   |       this trait cannot be made into an object...
-help: consider using an opaque type instead
-   |
-LL | fn make_baz<T:Baz>(t: &T) -> &impl Baz {
-   |                               ~~~~
-
 error[E0277]: the size for values of type `Self` cannot be known at compilation time
   --> $DIR/object-safety-supertrait-mentions-Self.rs:8:13
    |
@@ -36,6 +18,24 @@ help: consider relaxing the implicit `Sized` restriction
 LL | trait Bar<T: ?Sized> {
    |            ++++++++
 
+error[E0038]: the trait `Baz` cannot be made into an object
+  --> $DIR/object-safety-supertrait-mentions-Self.rs:16:31
+   |
+LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
+   |                               ^^^^^^^ `Baz` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety-supertrait-mentions-Self.rs:8:13
+   |
+LL | trait Baz : Bar<Self> {
+   |       ---   ^^^^^^^^^ ...because it uses `Self` as a type parameter
+   |       |
+   |       this trait cannot be made into an object...
+help: consider using an opaque type instead
+   |
+LL | fn make_baz<T:Baz>(t: &T) -> &impl Baz {
+   |                               ~~~~
+
 error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0038, E0277.
diff --git a/tests/ui/resolve/auxiliary/proc_macro_generate_packed.rs b/tests/ui/resolve/auxiliary/proc_macro_generate_packed.rs
new file mode 100644
index 00000000000..c0b24706dcb
--- /dev/null
+++ b/tests/ui/resolve/auxiliary/proc_macro_generate_packed.rs
@@ -0,0 +1,27 @@
+//@ force-host
+//@ no-prefer-dynamic
+//@ compile-flags: --crate-type proc-macro
+
+extern crate proc_macro;
+
+use proc_macro::*;
+
+#[proc_macro_attribute]
+pub fn proc_macro_attribute_that_generates_repr_packed(
+    _attr: TokenStream,
+    item: TokenStream,
+) -> TokenStream {
+    let repr = vec![TokenTree::Ident(Ident::new("packed", Span::call_site()))].into_iter();
+    let attr = vec![
+        TokenTree::Ident(Ident::new("repr", Span::call_site())),
+        TokenTree::Group(Group::new(Delimiter::Parenthesis, repr.collect())),
+    ]
+    .into_iter();
+    vec![
+        TokenTree::Punct(Punct::new('#', Spacing::Alone)),
+        TokenTree::Group(Group::new(Delimiter::Bracket, attr.collect())),
+    ]
+    .into_iter()
+    .chain(item)
+    .collect()
+}
diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.rs b/tests/ui/resolve/multiple_definitions_attribute_merging.rs
new file mode 100644
index 00000000000..523717861e1
--- /dev/null
+++ b/tests/ui/resolve/multiple_definitions_attribute_merging.rs
@@ -0,0 +1,19 @@
+//! This test ICEs because the `repr(packed)` attributes
+//! end up on the `Dealigned` struct's attribute list, but the
+//! derive didn't see that.
+
+//@known-bug: #120873
+//@ failure-status: 101
+//@ normalize-stderr-test "note: .*\n\n" -> ""
+//@ normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
+//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
+//@ rustc-env:RUST_BACKTRACE=0
+
+#[repr(packed)]
+struct Dealigned<T>(u8, T);
+
+#[derive(PartialEq)]
+#[repr(C)]
+struct Dealigned<T>(u8, T);
+
+fn main() {}
diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.stderr b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr
new file mode 100644
index 00000000000..b2d20af883a
--- /dev/null
+++ b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr
@@ -0,0 +1,26 @@
+error[E0428]: the name `Dealigned` is defined multiple times
+  --> $DIR/multiple_definitions_attribute_merging.rs:17:1
+   |
+LL | struct Dealigned<T>(u8, T);
+   | --------------------------- previous definition of the type `Dealigned` here
+...
+LL | struct Dealigned<T>(u8, T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Dealigned` redefined here
+   |
+   = error: internal compiler error: compiler/rustc_mir_transform/src/check_packed_ref.rs:LL:CC: builtin derive created an unaligned reference
+  --> $DIR/multiple_definitions_attribute_merging.rs:17:25
+   |
+LL | #[derive(PartialEq)]
+   |          --------- in this derive macro expansion
+LL | #[repr(C)]
+LL | struct Dealigned<T>(u8, T);
+   |                         ^
+   |
+   = Box<dyn Any>
+query stack during panic:
+#0 [mir_const] preparing `<impl at $DIR/multiple_definitions_attribute_merging.rs:15:10: 15:19>::eq` for borrow checking
+#1 [mir_promoted] promoting constants in MIR for `<impl at $DIR/multiple_definitions_attribute_merging.rs:15:10: 15:19>::eq`
+end of query stack
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0428`.
diff --git a/tests/ui/resolve/proc_macro_generated_packed.rs b/tests/ui/resolve/proc_macro_generated_packed.rs
new file mode 100644
index 00000000000..34a7e4db603
--- /dev/null
+++ b/tests/ui/resolve/proc_macro_generated_packed.rs
@@ -0,0 +1,20 @@
+//! This test ICEs because the `repr(packed)` attribute
+//! was generated by a proc macro, so `#[derive]` didn't see it.
+
+//@aux-build: proc_macro_generate_packed.rs
+//@known-bug: #120873
+//@ failure-status: 101
+//@ normalize-stderr-test "note: .*\n\n" -> ""
+//@ normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
+//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
+//@ rustc-env:RUST_BACKTRACE=0
+
+extern crate proc_macro_generate_packed;
+use proc_macro_generate_packed::proc_macro_attribute_that_generates_repr_packed;
+
+#[derive(PartialEq)]
+#[repr(C)]
+#[proc_macro_attribute_that_generates_repr_packed]
+struct Dealigned<T>(u8, T);
+
+fn main() {}
diff --git a/tests/ui/resolve/proc_macro_generated_packed.stderr b/tests/ui/resolve/proc_macro_generated_packed.stderr
new file mode 100644
index 00000000000..507e5867c90
--- /dev/null
+++ b/tests/ui/resolve/proc_macro_generated_packed.stderr
@@ -0,0 +1,16 @@
+error: internal compiler error: compiler/rustc_mir_transform/src/check_packed_ref.rs:LL:CC: builtin derive created an unaligned reference
+  --> $DIR/proc_macro_generated_packed.rs:18:25
+   |
+LL | #[derive(PartialEq)]
+   |          --------- in this derive macro expansion
+...
+LL | struct Dealigned<T>(u8, T);
+   |                         ^
+   |
+   = Box<dyn Any>
+query stack during panic:
+#0 [mir_const] preparing `<impl at $DIR/proc_macro_generated_packed.rs:15:10: 15:19>::eq` for borrow checking
+#1 [mir_promoted] promoting constants in MIR for `<impl at $DIR/proc_macro_generated_packed.rs:15:10: 15:19>::eq`
+end of query stack
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/resolve/resolve-self-in-impl.stderr b/tests/ui/resolve/resolve-self-in-impl.stderr
index 183a17171f7..62cfdb4dc78 100644
--- a/tests/ui/resolve/resolve-self-in-impl.stderr
+++ b/tests/ui/resolve/resolve-self-in-impl.stderr
@@ -14,6 +14,20 @@ LL | impl Tr for S<Self> {}
    |
    = note: replace `Self` with a different type
 
+error[E0391]: cycle detected when computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:19:1: 19:23>`
+  --> $DIR/resolve-self-in-impl.rs:19:1
+   |
+LL | impl Tr<Self::A> for S {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: ...which immediately requires computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:19:1: 19:23>` again
+note: cycle used when building specialization graph of trait `Tr`
+  --> $DIR/resolve-self-in-impl.rs:4:1
+   |
+LL | trait Tr<T = u8> {
+   | ^^^^^^^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
 error: `Self` is not valid in the self type of an impl block
   --> $DIR/resolve-self-in-impl.rs:16:6
    |
@@ -38,26 +52,6 @@ LL | impl (Self, Self) {}
    |
    = note: replace `Self` with a different type
 
-error[E0391]: cycle detected when computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:19:1: 19:23>`
-  --> $DIR/resolve-self-in-impl.rs:19:1
-   |
-LL | impl Tr<Self::A> for S {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: ...which immediately requires computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:19:1: 19:23>` again
-note: cycle used when collecting item types in top-level module
-  --> $DIR/resolve-self-in-impl.rs:1:1
-   |
-LL | / #![feature(associated_type_defaults)]
-LL | |
-LL | | struct S<T = u8>(T);
-LL | | trait Tr<T = u8> {
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
 error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr
index eb0f18edd34..00efbb52f15 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr
@@ -1,5 +1,5 @@
 error: `#[target_feature(..)]` cannot be applied to safe trait method
-  --> $DIR/trait-impl.rs:22:5
+  --> $DIR/trait-impl.rs:13:5
    |
 LL |     #[target_feature(enable = "sse2")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method
@@ -8,7 +8,7 @@ LL |     fn foo(&self) {}
    |     ------------- not an `unsafe` function
 
 error: `#[target_feature(..)]` cannot be applied to safe trait method
-  --> $DIR/trait-impl.rs:13:5
+  --> $DIR/trait-impl.rs:22:5
    |
 LL |     #[target_feature(enable = "sse2")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
index 9ca7b574b13..e45c1a1f46f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
@@ -13,6 +13,15 @@ LL | impl const Default for A {
    = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
    = note: adding a non-const method body in the future would be a breaking change
 
+error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/derive-const-use.rs:7:6
+   |
+LL | impl const Default for A {
+   |      ^^^^^ unconstrained const parameter
+   |
+   = note: expressions using a const parameter must map each value to a distinct output value
+   = note: proving the result of expressions other than the parameter are unique is not supported
+
 error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
   --> $DIR/derive-const-use.rs:15:16
    |
@@ -24,15 +33,6 @@ LL | #[derive_const(Default, PartialEq)]
    = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/derive-const-use.rs:7:6
-   |
-LL | impl const Default for A {
-   |      ^^^^^ unconstrained const parameter
-   |
-   = note: expressions using a const parameter must map each value to a distinct output value
-   = note: proving the result of expressions other than the parameter are unique is not supported
-
-error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
    |
    = note: expressions using a const parameter must map each value to a distinct output value
    = note: proving the result of expressions other than the parameter are unique is not supported
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
index 2c63c0217ab..77aee6a8bb8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
@@ -25,12 +25,6 @@ LL | trait Bar: ~const Foo {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/super-traits-fail-3.rs:18:24
-   |
-LL | const fn foo<T: ~const Bar>(x: &T) {
-   |                        ^^^
-
-error: `~const` can only be applied to `#[const_trait]` traits
   --> $DIR/super-traits-fail-3.rs:12:19
    |
 LL | trait Bar: ~const Foo {}
@@ -38,5 +32,11 @@ LL | trait Bar: ~const Foo {}
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
+error: `~const` can only be applied to `#[const_trait]` traits
+  --> $DIR/super-traits-fail-3.rs:18:24
+   |
+LL | const fn foo<T: ~const Bar>(x: &T) {
+   |                        ^^^
+
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
index 92a9c347a07..8151b9aaa23 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
@@ -262,16 +262,6 @@ LL |     const CONSTANT<T: ~const Trait>: () = ();
    = help: add `#![feature(generic_const_items)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0658]: inherent associated types are unstable
-  --> $DIR/tilde-const-invalid-places.rs:44:5
-   |
-LL |     type Type<T: ~const Trait> = ();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
-   = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
 error[E0392]: type parameter `T` is never used
   --> $DIR/tilde-const-invalid-places.rs:11:19
    |
@@ -304,6 +294,16 @@ note: required by a bound in `NonConstTrait::Type`
 LL |     type Type<T: ~const Trait>: ~const Trait;
    |                                 ^^^^^^^^^^^^ required by this bound in `NonConstTrait::Type`
 
+error[E0658]: inherent associated types are unstable
+  --> $DIR/tilde-const-invalid-places.rs:44:5
+   |
+LL |     type Type<T: ~const Trait> = ();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
+   = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
 error: aborting due to 30 previous errors
 
 Some errors have detailed explanations: E0275, E0392, E0658, E0740.
diff --git a/tests/ui/span/issue-35987.rs b/tests/ui/span/issue-35987.rs
index 3a6e6ffe249..d52a3793af9 100644
--- a/tests/ui/span/issue-35987.rs
+++ b/tests/ui/span/issue-35987.rs
@@ -7,6 +7,7 @@ impl<T: Clone, Add> Add for Foo<T> {
     type Output = usize;
 
     fn add(self, rhs: Self) -> Self::Output {
+        //~^ ERROR ambiguous associated type
         unimplemented!();
     }
 }
diff --git a/tests/ui/span/issue-35987.stderr b/tests/ui/span/issue-35987.stderr
index d3014f276fd..36c59137b31 100644
--- a/tests/ui/span/issue-35987.stderr
+++ b/tests/ui/span/issue-35987.stderr
@@ -9,6 +9,20 @@ LL | impl<T: Clone, Add> Add for Foo<T> {
    |                |
    |                found this type parameter
 
-error: aborting due to 1 previous error
+error[E0223]: ambiguous associated type
+  --> $DIR/issue-35987.rs:9:32
+   |
+LL |     fn add(self, rhs: Self) -> Self::Output {
+   |                                ^^^^^^^^^^^^
+   |
+help: use fully-qualified syntax
+   |
+LL |     fn add(self, rhs: Self) -> <Foo<T> as BitOr>::Output {
+   |                                ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     fn add(self, rhs: Self) -> <Foo<T> as IntoFuture>::Output {
+   |                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0404`.
+Some errors have detailed explanations: E0223, E0404.
+For more information about an error, try `rustc --explain E0223`.
diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
index a7d636b63bd..61a2925f582 100644
--- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
+++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
@@ -150,6 +150,14 @@ help: consider introducing a named lifetime parameter
 LL |     fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&()> { x.next() }
    |         ++++                              ++
 
+error: lifetime may not live long enough
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:19:67
+   |
+LL |     async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
+   |     -----------------------------------------------------------   ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+   |     |
+   |     return type `impl Future<Output = Option<&'static ()>>` contains a lifetime `'1`
+
 error[E0658]: anonymous lifetimes in `impl Trait` are unstable
   --> $DIR/impl-trait-missing-lifetime-gated.rs:25:35
    |
@@ -176,6 +184,14 @@ help: consider introducing a named lifetime parameter
 LL |     fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'_ ()> { x.next() }
    |         ++++                              ~~
 
+error: lifetime may not live long enough
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:38:73
+   |
+LL |     async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
+   |     -----------------------------------------------------------------   ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+   |     |
+   |     return type `impl Future<Output = Option<&'static ()>>` contains a lifetime `'1`
+
 error[E0658]: anonymous lifetimes in `impl Trait` are unstable
   --> $DIR/impl-trait-missing-lifetime-gated.rs:46:18
    |
@@ -228,22 +244,6 @@ help: consider introducing a named lifetime parameter
 LL |     fn g<'a>(mut x: impl Foo<'a, ()>) -> Option<&()> { x.next() }
    |         ++++                 +++
 
-error: lifetime may not live long enough
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:19:67
-   |
-LL |     async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
-   |     -----------------------------------------------------------   ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
-   |     |
-   |     return type `impl Future<Output = Option<&'static ()>>` contains a lifetime `'1`
-
-error: lifetime may not live long enough
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:38:73
-   |
-LL |     async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
-   |     -----------------------------------------------------------------   ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
-   |     |
-   |     return type `impl Future<Output = Option<&'static ()>>` contains a lifetime `'1`
-
 error: aborting due to 16 previous errors
 
 Some errors have detailed explanations: E0106, E0658.
diff --git a/tests/ui/suggestions/suggest-blanket-impl-local-trait.stderr b/tests/ui/suggestions/suggest-blanket-impl-local-trait.stderr
index 398caa98b84..769f3bd64f3 100644
--- a/tests/ui/suggestions/suggest-blanket-impl-local-trait.stderr
+++ b/tests/ui/suggestions/suggest-blanket-impl-local-trait.stderr
@@ -1,41 +1,4 @@
 error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/suggest-blanket-impl-local-trait.rs:13:24
-   |
-LL | impl LocalTraitTwo for LocalTraitOne {}
-   |                        ^^^^^^^^^^^^^
-   |
-help: add `dyn` keyword before this trait
-   |
-LL | impl LocalTraitTwo for dyn LocalTraitOne {}
-   |                        +++
-help: alternatively use a blanket implementation to implement `LocalTraitTwo` for all types that also implement `LocalTraitOne`
-   |
-LL | impl<T: LocalTraitOne> LocalTraitTwo for T {}
-   |     ++++++++++++++++++                   ~
-
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/suggest-blanket-impl-local-trait.rs:18:23
-   |
-LL | impl fmt::Display for LocalTraitOne {
-   |                       ^^^^^^^^^^^^^
-   |
-help: add `dyn` keyword before this trait
-   |
-LL | impl fmt::Display for dyn LocalTraitOne {
-   |                       +++
-
-error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/suggest-blanket-impl-local-trait.rs:26:23
-   |
-LL | impl fmt::Display for LocalTraitTwo + Send {
-   |                       ^^^^^^^^^^^^^^^^^^^^
-   |
-help: add `dyn` keyword before this trait
-   |
-LL | impl fmt::Display for dyn LocalTraitTwo + Send {
-   |                       +++
-
-error[E0782]: trait objects must include the `dyn` keyword
   --> $DIR/suggest-blanket-impl-local-trait.rs:34:24
    |
 LL | impl LocalTraitOne for fmt::Display {}
@@ -66,6 +29,21 @@ LL | impl<T: fmt::Display + Send> LocalTraitOne for T {}
    |     ++++++++++++++++++++++++                   ~
 
 error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/suggest-blanket-impl-local-trait.rs:13:24
+   |
+LL | impl LocalTraitTwo for LocalTraitOne {}
+   |                        ^^^^^^^^^^^^^
+   |
+help: add `dyn` keyword before this trait
+   |
+LL | impl LocalTraitTwo for dyn LocalTraitOne {}
+   |                        +++
+help: alternatively use a blanket implementation to implement `LocalTraitTwo` for all types that also implement `LocalTraitOne`
+   |
+LL | impl<T: LocalTraitOne> LocalTraitTwo for T {}
+   |     ++++++++++++++++++                   ~
+
+error[E0782]: trait objects must include the `dyn` keyword
   --> $DIR/suggest-blanket-impl-local-trait.rs:46:29
    |
 LL | impl<E> GenericTrait<E> for LocalTraitOne {}
@@ -81,6 +59,28 @@ LL | impl<E, T: LocalTraitOne> GenericTrait<E> for T {}
    |       ++++++++++++++++++                      ~
 
 error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/suggest-blanket-impl-local-trait.rs:18:23
+   |
+LL | impl fmt::Display for LocalTraitOne {
+   |                       ^^^^^^^^^^^^^
+   |
+help: add `dyn` keyword before this trait
+   |
+LL | impl fmt::Display for dyn LocalTraitOne {
+   |                       +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/suggest-blanket-impl-local-trait.rs:26:23
+   |
+LL | impl fmt::Display for LocalTraitTwo + Send {
+   |                       ^^^^^^^^^^^^^^^^^^^^
+   |
+help: add `dyn` keyword before this trait
+   |
+LL | impl fmt::Display for dyn LocalTraitTwo + Send {
+   |                       +++
+
+error[E0782]: trait objects must include the `dyn` keyword
   --> $DIR/suggest-blanket-impl-local-trait.rs:53:35
    |
 LL | impl<T, E> GenericTraitTwo<E> for GenericTrait<T> {}
diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs
index c4384bce3a9..a5ab8be7f45 100644
--- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs
+++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs
@@ -3,9 +3,12 @@
 pub trait Trait<'a, T> {}
 
 pub struct Struct<T>;
+//~^ ERROR `T` is never used
 pub enum Enum<T> {}
+//~^ ERROR `T` is never used
 
 pub union Union<T> {
+    //~^ ERROR `T` is never used
     f1: usize,
 }
 
@@ -15,8 +18,10 @@ impl<'a, T> Struct<T> for Trait<'a, T> {}
 
 impl<'a, T> Enum<T> for Trait<'a, T> {}
 //~^ ERROR expected trait, found enum `Enum`
+//~| ERROR trait objects must include the `dyn` keyword
 
 impl<'a, T> Union<T> for Trait<'a, T> {}
 //~^ ERROR expected trait, found union `Union`
+//~| ERROR trait objects must include the `dyn` keyword
 
 fn main() {}
diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
index 87e71643620..2893370570d 100644
--- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
+++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
@@ -1,5 +1,5 @@
 error[E0404]: expected trait, found struct `Struct`
-  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:12:13
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:15:13
    |
 LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
    |             ^^^^^^^^^ not a trait
@@ -10,7 +10,7 @@ LL | impl<'a, T> Trait<'a, T> for Struct<T> {}
    |             ~~~~~~~~~~~~     ~~~~~~~~~
 
 error[E0404]: expected trait, found enum `Enum`
-  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:16:13
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:19:13
    |
 LL | impl<'a, T> Enum<T> for Trait<'a, T> {}
    |             ^^^^^^^ not a trait
@@ -21,7 +21,7 @@ LL | impl<'a, T> Trait<'a, T> for Enum<T> {}
    |             ~~~~~~~~~~~~     ~~~~~~~
 
 error[E0404]: expected trait, found union `Union`
-  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:19:13
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:23:13
    |
 LL | impl<'a, T> Union<T> for Trait<'a, T> {}
    |             ^^^^^^^^ not a trait
@@ -31,8 +31,35 @@ help: `impl` items mention the trait being implemented first and the type it is
 LL | impl<'a, T> Trait<'a, T> for Union<T> {}
    |             ~~~~~~~~~~~~     ~~~~~~~~
 
+error[E0392]: type parameter `T` is never used
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:5:19
+   |
+LL | pub struct Struct<T>;
+   |                   ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error[E0392]: type parameter `T` is never used
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:7:15
+   |
+LL | pub enum Enum<T> {}
+   |               ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error[E0392]: type parameter `T` is never used
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:10:17
+   |
+LL | pub union Union<T> {
+   |                 ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
 error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:12:27
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:15:27
    |
 LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
    |                           ^^^^^^^^^^^^
@@ -42,7 +69,29 @@ help: add `dyn` keyword before this trait
 LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
    |                           +++
 
-error: aborting due to 4 previous errors
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:19:25
+   |
+LL | impl<'a, T> Enum<T> for Trait<'a, T> {}
+   |                         ^^^^^^^^^^^^
+   |
+help: add `dyn` keyword before this trait
+   |
+LL | impl<'a, T> Enum<T> for dyn Trait<'a, T> {}
+   |                         +++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:23:26
+   |
+LL | impl<'a, T> Union<T> for Trait<'a, T> {}
+   |                          ^^^^^^^^^^^^
+   |
+help: add `dyn` keyword before this trait
+   |
+LL | impl<'a, T> Union<T> for dyn Trait<'a, T> {}
+   |                          +++
+
+error: aborting due to 9 previous errors
 
-Some errors have detailed explanations: E0404, E0782.
-For more information about an error, try `rustc --explain E0404`.
+Some errors have detailed explanations: E0392, E0404, E0782.
+For more information about an error, try `rustc --explain E0392`.
diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.rs b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.rs
index 947bc2c7965..951e7313f0a 100644
--- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.rs
+++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.rs
@@ -1,9 +1,12 @@
 pub trait Trait<'a, T> {}
 
 pub struct Struct<T>;
+//~^ ERROR `T` is never used
 pub enum Enum<T> {}
+//~^ ERROR `T` is never used
 
 pub union Union<T> {
+    //~^ ERROR `T` is never used
     f1: usize,
 }
 
@@ -14,8 +17,12 @@ impl<'a, T> Struct<T> for Trait<'a, T> {}
 
 impl<'a, T> Enum<T> for Trait<'a, T> {}
 //~^ ERROR expected trait, found enum `Enum`
+//~| WARNING trait objects without an explicit `dyn` are deprecated
+//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
 
 impl<'a, T> Union<T> for Trait<'a, T> {}
 //~^ ERROR expected trait, found union `Union`
+//~| WARNING trait objects without an explicit `dyn` are deprecated
+//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
 
 fn main() {}
diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
index 0098814f81e..5d805d97a43 100644
--- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
+++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
@@ -1,5 +1,5 @@
 error[E0404]: expected trait, found struct `Struct`
-  --> $DIR/suggest-swapping-self-ty-and-trait.rs:10:13
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:13:13
    |
 LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
    |             ^^^^^^^^^ not a trait
@@ -10,7 +10,7 @@ LL | impl<'a, T> Trait<'a, T> for Struct<T> {}
    |             ~~~~~~~~~~~~     ~~~~~~~~~
 
 error[E0404]: expected trait, found enum `Enum`
-  --> $DIR/suggest-swapping-self-ty-and-trait.rs:15:13
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:18:13
    |
 LL | impl<'a, T> Enum<T> for Trait<'a, T> {}
    |             ^^^^^^^ not a trait
@@ -21,7 +21,7 @@ LL | impl<'a, T> Trait<'a, T> for Enum<T> {}
    |             ~~~~~~~~~~~~     ~~~~~~~
 
 error[E0404]: expected trait, found union `Union`
-  --> $DIR/suggest-swapping-self-ty-and-trait.rs:18:13
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:23:13
    |
 LL | impl<'a, T> Union<T> for Trait<'a, T> {}
    |             ^^^^^^^^ not a trait
@@ -31,8 +31,35 @@ help: `impl` items mention the trait being implemented first and the type it is
 LL | impl<'a, T> Trait<'a, T> for Union<T> {}
    |             ~~~~~~~~~~~~     ~~~~~~~~
 
+error[E0392]: type parameter `T` is never used
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:3:19
+   |
+LL | pub struct Struct<T>;
+   |                   ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error[E0392]: type parameter `T` is never used
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:5:15
+   |
+LL | pub enum Enum<T> {}
+   |               ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error[E0392]: type parameter `T` is never used
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:8:17
+   |
+LL | pub union Union<T> {
+   |                 ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/suggest-swapping-self-ty-and-trait.rs:10:27
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:13:27
    |
 LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
    |                           ^^^^^^^^^^^^
@@ -45,6 +72,33 @@ help: if this is an object-safe trait, use `dyn`
 LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
    |                           +++
 
-error: aborting due to 3 previous errors; 1 warning emitted
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:18:25
+   |
+LL | impl<'a, T> Enum<T> for Trait<'a, T> {}
+   |                         ^^^^^^^^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: if this is an object-safe trait, use `dyn`
+   |
+LL | impl<'a, T> Enum<T> for dyn Trait<'a, T> {}
+   |                         +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:23:26
+   |
+LL | impl<'a, T> Union<T> for Trait<'a, T> {}
+   |                          ^^^^^^^^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: if this is an object-safe trait, use `dyn`
+   |
+LL | impl<'a, T> Union<T> for dyn Trait<'a, T> {}
+   |                          +++
+
+error: aborting due to 6 previous errors; 3 warnings emitted
 
-For more information about this error, try `rustc --explain E0404`.
+Some errors have detailed explanations: E0392, E0404.
+For more information about an error, try `rustc --explain E0392`.
diff --git a/tests/ui/tag-type-args.stderr b/tests/ui/tag-type-args.stderr
index a1136f61cc5..def13832e1a 100644
--- a/tests/ui/tag-type-args.stderr
+++ b/tests/ui/tag-type-args.stderr
@@ -1,3 +1,12 @@
+error[E0392]: type parameter `T` is never used
+  --> $DIR/tag-type-args.rs:1:11
+   |
+LL | enum Quux<T> { Bar }
+   |           ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
 error[E0107]: missing generics for enum `Quux`
   --> $DIR/tag-type-args.rs:4:11
    |
@@ -14,15 +23,6 @@ help: add missing generic argument
 LL | fn foo(c: Quux<T>) { assert!((false)); }
    |               +++
 
-error[E0392]: type parameter `T` is never used
-  --> $DIR/tag-type-args.rs:1:11
-   |
-LL | enum Quux<T> { Bar }
-   |           ^ unused type parameter
-   |
-   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
-   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
-
 error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0107, E0392.
diff --git a/tests/ui/target-feature/invalid-attribute.stderr b/tests/ui/target-feature/invalid-attribute.stderr
index 278b9ad5003..bf48911edec 100644
--- a/tests/ui/target-feature/invalid-attribute.stderr
+++ b/tests/ui/target-feature/invalid-attribute.stderr
@@ -183,6 +183,15 @@ error: cannot use `#[inline(always)]` with `#[target_feature]`
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^
 
+error[E0046]: not all trait items implemented, missing: `foo`
+  --> $DIR/invalid-attribute.rs:88:1
+   |
+LL | impl Quux for u8 {}
+   | ^^^^^^^^^^^^^^^^ missing `foo` in implementation
+...
+LL |     fn foo();
+   |     --------- `foo` from trait
+
 error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
   --> $DIR/invalid-attribute.rs:103:5
    |
@@ -196,15 +205,6 @@ LL |     fn foo() {}
    = help: add `#![feature(target_feature_11)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0046]: not all trait items implemented, missing: `foo`
-  --> $DIR/invalid-attribute.rs:88:1
-   |
-LL | impl Quux for u8 {}
-   | ^^^^^^^^^^^^^^^^ missing `foo` in implementation
-...
-LL |     fn foo();
-   |     --------- `foo` from trait
-
 error: aborting due to 23 previous errors
 
 Some errors have detailed explanations: E0046, E0658.
diff --git a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs
new file mode 100644
index 00000000000..c3a2ab82adc
--- /dev/null
+++ b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs
@@ -0,0 +1,16 @@
+// Regression test for #121443
+// Checks that no ICE occurs upon encountering
+// a tuple with unsized element that is not
+// the last element
+
+type Fn = dyn FnOnce() -> u8;
+
+const TEST: Fn = some_fn;
+//~^ ERROR cannot find value `some_fn` in this scope
+//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
+//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
+const TEST2: (Fn, u8) = (TEST, 0);
+//~^ ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
+//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr
new file mode 100644
index 00000000000..0e92979ccd5
--- /dev/null
+++ b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr
@@ -0,0 +1,45 @@
+error[E0425]: cannot find value `some_fn` in this scope
+  --> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:18
+   |
+LL | const TEST: Fn = some_fn;
+   |                  ^^^^^^^ not found in this scope
+
+error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
+  --> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:13
+   |
+LL | const TEST: Fn = some_fn;
+   |             ^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
+
+error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
+  --> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:18
+   |
+LL | const TEST: Fn = some_fn;
+   |                  ^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
+   = note: constant expressions must have a statically known size
+
+error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
+  --> $DIR/ice-unsized-tuple-const-issue-121443.rs:12:14
+   |
+LL | const TEST2: (Fn, u8) = (TEST, 0);
+   |              ^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
+   = note: only the last element of a tuple may have a dynamically sized type
+
+error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
+  --> $DIR/ice-unsized-tuple-const-issue-121443.rs:12:25
+   |
+LL | const TEST2: (Fn, u8) = (TEST, 0);
+   |                         ^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
+   = note: only the last element of a tuple may have a dynamically sized type
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0277, E0425.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr
index 5062d17033e..f4ede4190fc 100644
--- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr
+++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr
@@ -1,3 +1,9 @@
+error[E0207]: the type parameter `S` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:9:9
+   |
+LL | impl<T, S> Trait<T> for i32 {
+   |         ^ unconstrained type parameter
+
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:15:12
    |
@@ -10,6 +16,12 @@ note: trait defined here, with 1 generic parameter: `T`
 LL | pub trait Trait<T> {
    |           ^^^^^ -
 
+error[E0207]: the type parameter `S` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:15:9
+   |
+LL | impl<T, S> Trait<T, S> for () {}
+   |         ^ unconstrained type parameter
+
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:12
    |
@@ -42,6 +54,12 @@ help: replace the generic bound with the associated type
 LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), Assoc = i32> {
    |                                                        +++++++
 
+error[E0282]: type annotations needed
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:41
+   |
+LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
+   |                                         ^^^^^^^^^^^^^^^^^^^ cannot infer type
+
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:27:18
    |
@@ -104,24 +122,6 @@ note: struct defined here, with 1 generic parameter: `T`
 LL | struct Struct<T: Trait<u32, String>> {
    |        ^^^^^^ -
 
-error[E0207]: the type parameter `S` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:9:9
-   |
-LL | impl<T, S> Trait<T> for i32 {
-   |         ^ unconstrained type parameter
-
-error[E0207]: the type parameter `S` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:15:9
-   |
-LL | impl<T, S> Trait<T, S> for () {}
-   |         ^ unconstrained type parameter
-
-error[E0282]: type annotations needed
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:41
-   |
-LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
-   |                                         ^^^^^^^^^^^^^^^^^^^ cannot infer type
-
 error: aborting due to 10 previous errors
 
 Some errors have detailed explanations: E0107, E0207, E0282.
diff --git a/tests/ui/traits/bound/on-structs-and-enums-static.rs b/tests/ui/traits/bound/on-structs-and-enums-static.rs
index 066416cb362..d734893dd7c 100644
--- a/tests/ui/traits/bound/on-structs-and-enums-static.rs
+++ b/tests/ui/traits/bound/on-structs-and-enums-static.rs
@@ -8,6 +8,7 @@ struct Foo<T:Trait> {
 
 static X: Foo<usize> = Foo {
 //~^ ERROR E0277
+//~| ERROR E0277
     x: 1, //~ ERROR: E0277
 };
 
diff --git a/tests/ui/traits/bound/on-structs-and-enums-static.stderr b/tests/ui/traits/bound/on-structs-and-enums-static.stderr
index 28bbe00c582..42ebcc07571 100644
--- a/tests/ui/traits/bound/on-structs-and-enums-static.stderr
+++ b/tests/ui/traits/bound/on-structs-and-enums-static.stderr
@@ -16,7 +16,25 @@ LL | struct Foo<T:Trait> {
    |              ^^^^^ required by this bound in `Foo`
 
 error[E0277]: the trait bound `usize: Trait` is not satisfied
-  --> $DIR/on-structs-and-enums-static.rs:11:8
+  --> $DIR/on-structs-and-enums-static.rs:9:11
+   |
+LL | static X: Foo<usize> = Foo {
+   |           ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/on-structs-and-enums-static.rs:1:1
+   |
+LL | trait Trait {
+   | ^^^^^^^^^^^
+note: required by a bound in `Foo`
+  --> $DIR/on-structs-and-enums-static.rs:5:14
+   |
+LL | struct Foo<T:Trait> {
+   |              ^^^^^ required by this bound in `Foo`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0277]: the trait bound `usize: Trait` is not satisfied
+  --> $DIR/on-structs-and-enums-static.rs:12:8
    |
 LL |     x: 1,
    |        ^ the trait `Trait` is not implemented for `usize`
@@ -32,6 +50,6 @@ note: required by a bound in `Foo`
 LL | struct Foo<T:Trait> {
    |              ^^^^^ required by this bound in `Foo`
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/issue-28576.stderr b/tests/ui/traits/issue-28576.stderr
index 653ce05d285..7e0f52bc4fe 100644
--- a/tests/ui/traits/issue-28576.stderr
+++ b/tests/ui/traits/issue-28576.stderr
@@ -1,3 +1,23 @@
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+  --> $DIR/issue-28576.rs:5:16
+   |
+LL | pub trait Bar: Foo<Assoc=()> {
+   |                ^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+note: required by an implicit `Sized` bound in `Foo`
+  --> $DIR/issue-28576.rs:1:15
+   |
+LL | pub trait Foo<RHS=Self> {
+   |               ^^^^^^^^ required by the implicit `Sized` requirement on this type parameter in `Foo`
+help: consider further restricting `Self`
+   |
+LL | pub trait Bar: Foo<Assoc=()> + Sized {
+   |                              +++++++
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | pub trait Foo<RHS: ?Sized=Self> {
+   |                  ++++++++
+
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-28576.rs:9:12
    |
@@ -32,26 +52,6 @@ LL | pub trait Foo<RHS=Self> {
    |               ^^^^^^^^ required by the implicit `Sized` requirement on this type parameter in `Foo`
 help: consider further restricting `Self`
    |
-LL | pub trait Bar: Foo<Assoc=()> + Sized {
-   |                              +++++++
-help: consider relaxing the implicit `Sized` restriction
-   |
-LL | pub trait Foo<RHS: ?Sized=Self> {
-   |                  ++++++++
-
-error[E0277]: the size for values of type `Self` cannot be known at compilation time
-  --> $DIR/issue-28576.rs:5:16
-   |
-LL | pub trait Bar: Foo<Assoc=()> {
-   |                ^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-note: required by an implicit `Sized` bound in `Foo`
-  --> $DIR/issue-28576.rs:1:15
-   |
-LL | pub trait Foo<RHS=Self> {
-   |               ^^^^^^^^ required by the implicit `Sized` requirement on this type parameter in `Foo`
-help: consider further restricting `Self`
-   |
 LL |     ) where Self: Sized;
    |       +++++++++++++++++
 help: consider relaxing the implicit `Sized` restriction
diff --git a/tests/ui/traits/next-solver/assembly/param-env-alias-bound-conflict.rs b/tests/ui/traits/next-solver/assembly/param-env-alias-bound-conflict.rs
new file mode 100644
index 00000000000..ddda1a71d7e
--- /dev/null
+++ b/tests/ui/traits/next-solver/assembly/param-env-alias-bound-conflict.rs
@@ -0,0 +1,26 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// Regression test for #119607.
+
+pub trait IntoFoo {
+    type Item;
+    type IntoIter: Foo<Item = Self::Item>;
+
+    fn into_iter(self) -> Self::IntoIter;
+}
+
+pub trait Foo {
+    type Item;
+
+    fn next(self) -> Option<Self::Item>;
+}
+
+pub fn foo<'a, Iter1, Elem1>(a: &'a Iter1)
+where
+    &'a Iter1: IntoFoo<Item = Elem1>,
+{
+    a.into_iter().next();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-env-impl-conflict.rs b/tests/ui/traits/next-solver/env-shadows-impls/param-env-impl-conflict.rs
new file mode 100644
index 00000000000..1b9e9866cd6
--- /dev/null
+++ b/tests/ui/traits/next-solver/env-shadows-impls/param-env-impl-conflict.rs
@@ -0,0 +1,23 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// Regression test for #119608.
+
+pub trait Foo {}
+
+pub trait Bar {
+    type Assoc;
+}
+
+impl<T: Foo> Bar for T {
+    type Assoc = T;
+}
+
+pub fn foo<I>(_input: <I as Bar>::Assoc)
+where
+    I: Bar,
+    <I as Bar>::Assoc: Foo,
+{
+}
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.rs b/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.rs
index 511e41562b2..6211c7fac41 100644
--- a/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.rs
+++ b/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.rs
@@ -1,5 +1,6 @@
 trait A: B + A {}
 //~^ ERROR cycle detected when computing the super predicates of `A` [E0391]
+//~| ERROR cycle detected when computing the implied predicates of `A` [E0391]
 
 trait B {}
 
diff --git a/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr b/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr
index 85c05bd05db..b9988e2e6d3 100644
--- a/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr
+++ b/tests/ui/traits/trait-upcasting/cyclic-trait-resolution.stderr
@@ -5,13 +5,27 @@ LL | trait A: B + A {}
    |              ^
    |
    = note: ...which immediately requires computing the super predicates of `A` again
-note: cycle used when collecting item types in top-level module
+note: cycle used when checking that `A` is well-formed
   --> $DIR/cyclic-trait-resolution.rs:1:1
    |
 LL | trait A: B + A {}
    | ^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error: aborting due to 1 previous error
+error[E0391]: cycle detected when computing the implied predicates of `A`
+  --> $DIR/cyclic-trait-resolution.rs:1:14
+   |
+LL | trait A: B + A {}
+   |              ^
+   |
+   = note: ...which immediately requires computing the implied predicates of `A` again
+note: cycle used when checking that `<impl at $DIR/cyclic-trait-resolution.rs:7:1: 7:14>` is well-formed
+  --> $DIR/cyclic-trait-resolution.rs:7:1
+   |
+LL | impl A for () {}
+   | ^^^^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
index 7f80c3cfaba..df466609a12 100644
--- a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
+++ b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
@@ -46,17 +46,11 @@ LL |     V3 = Self::V1 {} as u8 + 2,
    |          ^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires computing layout of `Alpha`...
    = note: ...which again requires simplifying constant for the type system `Alpha::V3::{constant#0}`, completing the cycle
-note: cycle used when collecting item types in top-level module
-  --> $DIR/self-in-enum-definition.rs:1:1
+note: cycle used when checking that `Alpha` is well-formed
+  --> $DIR/self-in-enum-definition.rs:2:1
    |
-LL | / #[repr(u8)]
-LL | | enum Alpha {
-LL | |     V1 = 41,
-LL | |     V2 = Self::V1 as u8 + 1,    // OK; See #50072.
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
+LL | enum Alpha {
+   | ^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs
index bf27e76db2b..1ff200680be 100644
--- a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs
+++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs
@@ -7,7 +7,7 @@ pub trait Trait<'a> {
 trait Test<'a> {}
 
 pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
-//~^ ERROR cannot capture late-bound lifetime in type alias impl trait
+//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
 
 impl Trait<'_> for () {
     type Assoc = ();
diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr
index 7dce067d39c..09f6fba79cf 100644
--- a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr
+++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr
@@ -1,8 +1,15 @@
-error: cannot capture late-bound lifetime in type alias impl trait
-  --> $DIR/escaping-bound-var.rs:9:57
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
+  --> $DIR/escaping-bound-var.rs:9:47
    |
 LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
-   |                         -- lifetime defined here        ^^
+   |                                               ^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
+   |
+note: lifetime declared here
+  --> $DIR/escaping-bound-var.rs:9:25
+   |
+LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
+   |                         ^^
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0657`.
diff --git a/tests/ui/type-alias-impl-trait/self-referential.rs b/tests/ui/type-alias-impl-trait/self-referential.rs
index 3090f7733d2..2bd450e6c86 100644
--- a/tests/ui/type-alias-impl-trait/self-referential.rs
+++ b/tests/ui/type-alias-impl-trait/self-referential.rs
@@ -12,14 +12,14 @@ fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
 type Foo<'a, 'b> = (i32, impl PartialEq<Foo<'a, 'b>> + std::fmt::Debug);
 
 fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
-    //~^ ERROR can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0})`
+    //~^ ERROR can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)`
     (42, i)
 }
 
 type Moo<'a, 'b> = (i32, impl PartialEq<Moo<'b, 'a>> + std::fmt::Debug);
 
 fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
-    //~^ ERROR can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})`
+    //~^ ERROR can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)`
     (42, i)
 }
 
diff --git a/tests/ui/type-alias-impl-trait/self-referential.stderr b/tests/ui/type-alias-impl-trait/self-referential.stderr
index 27506b8d06f..396237c7898 100644
--- a/tests/ui/type-alias-impl-trait/self-referential.stderr
+++ b/tests/ui/type-alias-impl-trait/self-referential.stderr
@@ -10,28 +10,28 @@ LL |     i
    = help: the trait `PartialEq<Bar<'b, 'a>>` is not implemented for `&i32`
    = help: the trait `PartialEq` is implemented for `i32`
 
-error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0})`
+error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)`
   --> $DIR/self-referential.rs:14:31
    |
 LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
-   |                               ^^^^^^^^^^^ no implementation for `&i32 == (i32, Foo<'a, 'b>::{opaque#0})`
+   |                               ^^^^^^^^^^^ no implementation for `&i32 == (i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)`
 LL |
 LL |     (42, i)
    |     ------- return type was inferred to be `(i32, &i32)` here
    |
-   = help: the trait `PartialEq<(i32, Foo<'a, 'b>::{opaque#0})>` is not implemented for `&i32`
+   = help: the trait `PartialEq<(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)>` is not implemented for `&i32`
    = help: the trait `PartialEq` is implemented for `i32`
 
-error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})`
+error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)`
   --> $DIR/self-referential.rs:21:31
    |
 LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
-   |                               ^^^^^^^^^^^ no implementation for `&i32 == (i32, Moo<'b, 'a>::{opaque#0})`
+   |                               ^^^^^^^^^^^ no implementation for `&i32 == (i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)`
 LL |
 LL |     (42, i)
    |     ------- return type was inferred to be `(i32, &i32)` here
    |
-   = help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0})>` is not implemented for `&i32`
+   = help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)>` is not implemented for `&i32`
    = help: the trait `PartialEq` is implemented for `i32`
 
 error: aborting due to 3 previous errors
diff --git a/tests/ui/type-alias-impl-trait/variance.rs b/tests/ui/type-alias-impl-trait/variance.rs
index eae5e5fdde2..4b9fa67fd64 100644
--- a/tests/ui/type-alias-impl-trait/variance.rs
+++ b/tests/ui/type-alias-impl-trait/variance.rs
@@ -5,21 +5,21 @@
 trait Captures<'a> {}
 impl<T> Captures<'_> for T {}
 
-type NotCapturedEarly<'a> = impl Sized; //~ [o]
+type NotCapturedEarly<'a> = impl Sized; //~ [*, o]
 //~^ ERROR: unconstrained opaque type
 
-type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o]
+type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [*, o]
 //~^ ERROR: unconstrained opaque type
 
-// TAIT does *not* capture `'b`
-type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [o]
-//~^ ERROR: unconstrained opaque type
+type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [*, o, o]
+//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
+//~| ERROR: unconstrained opaque type
 
-// TAIT does *not* capture `'b`
-type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [o]
-//~^ ERROR: unconstrained opaque type
+type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [*, o, o]
+//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
+//~| ERROR: unconstrained opaque type
 
-type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [o, o, o]
+type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [*, *, o, o, o]
 //~^ ERROR: unconstrained opaque type
 
 trait Foo<'i> {
@@ -31,24 +31,24 @@ trait Foo<'i> {
 }
 
 impl<'i> Foo<'i> for &'i () {
-    type ImplicitCapture<'a> = impl Sized; //~ [o, o]
+    type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o]
     //~^ ERROR: unconstrained opaque type
 
-    type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o]
+    type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [*, *, o, o]
     //~^ ERROR: unconstrained opaque type
 
-    type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o]
+    type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [*, *, o, o]
     //~^ ERROR: unconstrained opaque type
 }
 
 impl<'i> Foo<'i> for () {
-    type ImplicitCapture<'a> = impl Sized; //~ [o, o]
+    type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o]
     //~^ ERROR: unconstrained opaque type
 
-    type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o]
+    type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [*, *, o, o]
     //~^ ERROR: unconstrained opaque type
 
-    type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o]
+    type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [*, *, o, o]
     //~^ ERROR: unconstrained opaque type
 }
 
diff --git a/tests/ui/type-alias-impl-trait/variance.stderr b/tests/ui/type-alias-impl-trait/variance.stderr
index 914541fcf66..1aaf36223b7 100644
--- a/tests/ui/type-alias-impl-trait/variance.stderr
+++ b/tests/ui/type-alias-impl-trait/variance.stderr
@@ -1,3 +1,27 @@
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
+  --> $DIR/variance.rs:14:56
+   |
+LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
+   |                                                        ^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
+   |
+note: lifetime declared here
+  --> $DIR/variance.rs:14:36
+   |
+LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
+   |                                    ^^
+
+error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
+  --> $DIR/variance.rs:18:49
+   |
+LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
+   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
+   |
+note: lifetime declared here
+  --> $DIR/variance.rs:18:29
+   |
+LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
+   |                             ^^
+
 error: unconstrained opaque type
   --> $DIR/variance.rs:8:29
    |
@@ -15,7 +39,7 @@ LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
    = note: `CapturedEarly` must be used in combination with a concrete type within the same module
 
 error: unconstrained opaque type
-  --> $DIR/variance.rs:15:56
+  --> $DIR/variance.rs:14:56
    |
 LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
    |                                                        ^^^^^^^^^^
@@ -23,7 +47,7 @@ LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
    = note: `NotCapturedLate` must be used in combination with a concrete type within the same module
 
 error: unconstrained opaque type
-  --> $DIR/variance.rs:19:49
+  --> $DIR/variance.rs:18:49
    |
 LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -86,71 +110,72 @@ LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
    |
    = note: `ExplicitCaptureFromGat` must be used in combination with a concrete type within the same impl
 
-error: [o]
+error: [*, o]
   --> $DIR/variance.rs:8:29
    |
 LL | type NotCapturedEarly<'a> = impl Sized;
    |                             ^^^^^^^^^^
 
-error: [o]
+error: [*, o]
   --> $DIR/variance.rs:11:26
    |
 LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o]
-  --> $DIR/variance.rs:15:56
+error: [*, o, o]
+  --> $DIR/variance.rs:14:56
    |
 LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
    |                                                        ^^^^^^^^^^
 
-error: [o]
-  --> $DIR/variance.rs:19:49
+error: [*, o, o]
+  --> $DIR/variance.rs:18:49
    |
 LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, o, o]
+error: [*, *, o, o, o]
   --> $DIR/variance.rs:22:27
    |
 LL | type Bar<'a, 'b: 'b, T> = impl Sized;
    |                           ^^^^^^^^^^
 
-error: [o, o]
+error: [*, *, o, o]
   --> $DIR/variance.rs:34:32
    |
 LL |     type ImplicitCapture<'a> = impl Sized;
    |                                ^^^^^^^^^^
 
-error: [o, o]
+error: [*, *, o, o]
   --> $DIR/variance.rs:37:42
    |
 LL |     type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, o]
+error: [*, *, o, o]
   --> $DIR/variance.rs:40:39
    |
 LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, o]
+error: [*, *, o, o]
   --> $DIR/variance.rs:45:32
    |
 LL |     type ImplicitCapture<'a> = impl Sized;
    |                                ^^^^^^^^^^
 
-error: [o, o]
+error: [*, *, o, o]
   --> $DIR/variance.rs:48:42
    |
 LL |     type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, o]
+error: [*, *, o, o]
   --> $DIR/variance.rs:51:39
    |
 LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 22 previous errors
+error: aborting due to 24 previous errors
 
+For more information about this error, try `rustc --explain E0657`.
diff --git a/tests/ui/typeck/type-placeholder-fn-in-const.stderr b/tests/ui/typeck/type-placeholder-fn-in-const.stderr
index 302359d2500..92b47bd4781 100644
--- a/tests/ui/typeck/type-placeholder-fn-in-const.stderr
+++ b/tests/ui/typeck/type-placeholder-fn-in-const.stderr
@@ -1,25 +1,25 @@
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/type-placeholder-fn-in-const.rs:4:25
+  --> $DIR/type-placeholder-fn-in-const.rs:10:25
    |
-LL |     const TEST: fn() -> _;
+LL |     const TEST: fn() -> _ = 42;
    |                         ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
   --> $DIR/type-placeholder-fn-in-const.rs:4:25
    |
 LL |     const TEST: fn() -> _;
    |                         ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/type-placeholder-fn-in-const.rs:10:25
    |
 LL |     const TEST: fn() -> _ = 42;
    |                         ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/type-placeholder-fn-in-const.rs:10:25
+  --> $DIR/type-placeholder-fn-in-const.rs:4:25
    |
-LL |     const TEST: fn() -> _ = 42;
+LL |     const TEST: fn() -> _;
    |                         ^ not allowed in type signatures
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr
index 1dc1d46aa71..9a9b2a68dbe 100644
--- a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr
+++ b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr
@@ -25,6 +25,16 @@ LL | trait Trait: Copy<dyn Send> {}
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/typeck-builtin-bound-type-parameters.rs:4:14
+   |
+LL | trait Trait: Copy<dyn Send> {}
+   |              ^^^^---------- help: remove these generics
+   |              |
+   |              expected 0 generic arguments
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:9:21
    |
 LL | struct MyStruct1<T: Copy<T>>(T);
@@ -56,16 +66,6 @@ LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
    |               |
    |               expected 0 generic arguments
 
-error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
-  --> $DIR/typeck-builtin-bound-type-parameters.rs:4:14
-   |
-LL | trait Trait: Copy<dyn Send> {}
-   |              ^^^^---------- help: remove these generics
-   |              |
-   |              expected 0 generic arguments
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index c102926fcf5..e8f1de1ad04 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -169,6 +169,28 @@ LL | unsafe fn test12(x: *const usize) -> *const *const _ {
    |                                      |             not allowed in type signatures
    |                                      help: replace with the correct return type: `*const *const usize`
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:59:24
+   |
+LL |     fn clone(&self) -> _ { Test9 }
+   |                        ^ not allowed in type signatures
+   |
+help: try replacing `_` with the type in the corresponding trait method signature
+   |
+LL |     fn clone(&self) -> Test9 { Test9 }
+   |                        ~~~~~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:62:37
+   |
+LL |     fn clone_from(&mut self, other: _) { *self = Test9; }
+   |                                     ^ not allowed in type signatures
+   |
+help: try replacing `_` with the type in the corresponding trait method signature
+   |
+LL |     fn clone_from(&mut self, other: &Test9) { *self = Test9; }
+   |                                     ~~~~~~
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs
   --> $DIR/typeck_type_placeholder_item.rs:67:8
    |
@@ -294,6 +316,28 @@ help: use type parameters instead
 LL |     fn fn_test8<T>(_f: fn() -> T) { }
    |                +++             ~
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:115:28
+   |
+LL |         fn clone(&self) -> _ { FnTest9 }
+   |                            ^ not allowed in type signatures
+   |
+help: try replacing `_` with the type in the corresponding trait method signature
+   |
+LL |         fn clone(&self) -> FnTest9 { FnTest9 }
+   |                            ~~~~~~~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:118:41
+   |
+LL |         fn clone_from(&mut self, other: _) { *self = FnTest9; }
+   |                                         ^ not allowed in type signatures
+   |
+help: try replacing `_` with the type in the corresponding trait method signature
+   |
+LL |         fn clone_from(&mut self, other: &FnTest9) { *self = FnTest9; }
+   |                                         ~~~~~~~~
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs
   --> $DIR/typeck_type_placeholder_item.rs:123:12
    |
@@ -346,6 +390,76 @@ LL |     fn fn_test13(x: _) -> (i32, _) { (x, x) }
    |                           |     not allowed in type signatures
    |                           help: replace with the correct return type: `(i32, i32)`
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:140:31
+   |
+LL |     fn method_test1(&self, x: _);
+   |                               ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     fn method_test1<T>(&self, x: T);
+   |                    +++           ~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:142:31
+   |
+LL |     fn method_test2(&self, x: _) -> _;
+   |                               ^     ^ not allowed in type signatures
+   |                               |
+   |                               not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     fn method_test2<T>(&self, x: T) -> T;
+   |                    +++           ~     ~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:144:31
+   |
+LL |     fn method_test3(&self) -> _;
+   |                               ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     fn method_test3<T>(&self) -> T;
+   |                    +++           ~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:146:26
+   |
+LL |     fn assoc_fn_test1(x: _);
+   |                          ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     fn assoc_fn_test1<T>(x: T);
+   |                      +++    ~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:148:26
+   |
+LL |     fn assoc_fn_test2(x: _) -> _;
+   |                          ^     ^ not allowed in type signatures
+   |                          |
+   |                          not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     fn assoc_fn_test2<T>(x: T) -> T;
+   |                      +++    ~     ~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:150:28
+   |
+LL |     fn assoc_fn_test3() -> _;
+   |                            ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     fn assoc_fn_test3<T>() -> T;
+   |                      +++      ~
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs
   --> $DIR/typeck_type_placeholder_item.rs:154:21
    |
@@ -410,6 +524,28 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL | type Y = impl Trait<_>;
    |                     ^ not allowed in type signatures
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:44:27
+   |
+LL |     fn test10(&self, _x : _) { }
+   |                           ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     fn test10<T>(&self, _x : T) { }
+   |              +++             ~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
+  --> $DIR/typeck_type_placeholder_item.rs:110:34
+   |
+LL |         fn fn_test10(&self, _x : _) { }
+   |                                  ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |         fn fn_test10<T>(&self, _x : T) { }
+   |                     +++             ~
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:217:31
    |
@@ -428,6 +564,39 @@ LL | const _: Option<_> = map(value);
    |          not allowed in type signatures
    |          help: replace with the correct type: `Option<u8>`
 
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
+  --> $DIR/typeck_type_placeholder_item.rs:206:14
+   |
+LL |     const C: _;
+   |              ^ not allowed in type signatures
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
+  --> $DIR/typeck_type_placeholder_item.rs:209:14
+   |
+LL |     const D: _ = 42;
+   |              ^
+   |              |
+   |              not allowed in type signatures
+   |              help: replace with the correct type: `i32`
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
+  --> $DIR/typeck_type_placeholder_item.rs:194:14
+   |
+LL |     const D: _ = 42;
+   |              ^
+   |              |
+   |              not allowed in type signatures
+   |              help: replace with the correct type: `i32`
+
+error[E0046]: not all trait items implemented, missing: `F`
+  --> $DIR/typeck_type_placeholder_item.rs:200:1
+   |
+LL |     type F: std::ops::Fn(_);
+   |     ----------------------- `F` from trait
+...
+LL | impl Qux for Struct {
+   | ^^^^^^^^^^^^^^^^^^^ missing `F` in implementation
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:225:31
    |
@@ -449,103 +618,6 @@ note: however, the inferred type `Map<Filter<Range<i32>, {closure@typeck_type_pl
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:140:31
-   |
-LL |     fn method_test1(&self, x: _);
-   |                               ^ not allowed in type signatures
-   |
-help: use type parameters instead
-   |
-LL |     fn method_test1<T>(&self, x: T);
-   |                    +++           ~
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:142:31
-   |
-LL |     fn method_test2(&self, x: _) -> _;
-   |                               ^     ^ not allowed in type signatures
-   |                               |
-   |                               not allowed in type signatures
-   |
-help: use type parameters instead
-   |
-LL |     fn method_test2<T>(&self, x: T) -> T;
-   |                    +++           ~     ~
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:144:31
-   |
-LL |     fn method_test3(&self) -> _;
-   |                               ^ not allowed in type signatures
-   |
-help: use type parameters instead
-   |
-LL |     fn method_test3<T>(&self) -> T;
-   |                    +++           ~
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:146:26
-   |
-LL |     fn assoc_fn_test1(x: _);
-   |                          ^ not allowed in type signatures
-   |
-help: use type parameters instead
-   |
-LL |     fn assoc_fn_test1<T>(x: T);
-   |                      +++    ~
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:148:26
-   |
-LL |     fn assoc_fn_test2(x: _) -> _;
-   |                          ^     ^ not allowed in type signatures
-   |                          |
-   |                          not allowed in type signatures
-   |
-help: use type parameters instead
-   |
-LL |     fn assoc_fn_test2<T>(x: T) -> T;
-   |                      +++    ~     ~
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:150:28
-   |
-LL |     fn assoc_fn_test3() -> _;
-   |                            ^ not allowed in type signatures
-   |
-help: use type parameters instead
-   |
-LL |     fn assoc_fn_test3<T>() -> T;
-   |                      +++      ~
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
-  --> $DIR/typeck_type_placeholder_item.rs:190:14
-   |
-LL |     type B = _;
-   |              ^ not allowed in type signatures
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item.rs:192:14
-   |
-LL |     const C: _;
-   |              ^ not allowed in type signatures
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item.rs:194:14
-   |
-LL |     const D: _ = 42;
-   |              ^
-   |              |
-   |              not allowed in type signatures
-   |              help: replace with the correct type: `i32`
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
-  --> $DIR/typeck_type_placeholder_item.rs:197:26
-   |
-LL |     type F: std::ops::Fn(_);
-   |                          ^ not allowed in type signatures
-
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:41:24
    |
@@ -555,39 +627,6 @@ LL |     fn test9(&self) -> _ { () }
    |                        not allowed in type signatures
    |                        help: replace with the correct return type: `()`
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:44:27
-   |
-LL |     fn test10(&self, _x : _) { }
-   |                           ^ not allowed in type signatures
-   |
-help: use type parameters instead
-   |
-LL |     fn test10<T>(&self, _x : T) { }
-   |              +++             ~
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:59:24
-   |
-LL |     fn clone(&self) -> _ { Test9 }
-   |                        ^ not allowed in type signatures
-   |
-help: try replacing `_` with the type in the corresponding trait method signature
-   |
-LL |     fn clone(&self) -> Test9 { Test9 }
-   |                        ~~~~~
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:62:37
-   |
-LL |     fn clone_from(&mut self, other: _) { *self = Test9; }
-   |                                     ^ not allowed in type signatures
-   |
-help: try replacing `_` with the type in the corresponding trait method signature
-   |
-LL |     fn clone_from(&mut self, other: &Test9) { *self = Test9; }
-   |                                     ~~~~~~
-
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:107:31
    |
@@ -597,39 +636,6 @@ LL |         fn fn_test9(&self) -> _ { () }
    |                               not allowed in type signatures
    |                               help: replace with the correct return type: `()`
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:110:34
-   |
-LL |         fn fn_test10(&self, _x : _) { }
-   |                                  ^ not allowed in type signatures
-   |
-help: use type parameters instead
-   |
-LL |         fn fn_test10<T>(&self, _x : T) { }
-   |                     +++             ~
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:115:28
-   |
-LL |         fn clone(&self) -> _ { FnTest9 }
-   |                            ^ not allowed in type signatures
-   |
-help: try replacing `_` with the type in the corresponding trait method signature
-   |
-LL |         fn clone(&self) -> FnTest9 { FnTest9 }
-   |                            ~~~~~~~
-
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/typeck_type_placeholder_item.rs:118:41
-   |
-LL |         fn clone_from(&mut self, other: _) { *self = FnTest9; }
-   |                                         ^ not allowed in type signatures
-   |
-help: try replacing `_` with the type in the corresponding trait method signature
-   |
-LL |         fn clone_from(&mut self, other: &FnTest9) { *self = FnTest9; }
-   |                                         ~~~~~~~~
-
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
   --> $DIR/typeck_type_placeholder_item.rs:202:14
    |
@@ -642,29 +648,23 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
 LL |     type B = _;
    |              ^ not allowed in type signatures
 
-error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item.rs:206:14
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
+  --> $DIR/typeck_type_placeholder_item.rs:190:14
    |
-LL |     const C: _;
+LL |     type B = _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item.rs:209:14
+  --> $DIR/typeck_type_placeholder_item.rs:192:14
    |
-LL |     const D: _ = 42;
-   |              ^
-   |              |
-   |              not allowed in type signatures
-   |              help: replace with the correct type: `i32`
+LL |     const C: _;
+   |              ^ not allowed in type signatures
 
-error[E0046]: not all trait items implemented, missing: `F`
-  --> $DIR/typeck_type_placeholder_item.rs:200:1
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
+  --> $DIR/typeck_type_placeholder_item.rs:197:26
    |
 LL |     type F: std::ops::Fn(_);
-   |     ----------------------- `F` from trait
-...
-LL | impl Qux for Struct {
-   | ^^^^^^^^^^^^^^^^^^^ missing `F` in implementation
+   |                          ^ not allowed in type signatures
 
 error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::filter::<{closure@$DIR/typeck_type_placeholder_item.rs:230:29: 230:32}>` in constants
   --> $DIR/typeck_type_placeholder_item.rs:230:22
diff --git a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr
index b0d4ed8272b..32585e2937b 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr
@@ -38,18 +38,18 @@ LL | const TEST4: fn() -> _ = 42;
    |                      ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item_help.rs:18:18
+  --> $DIR/typeck_type_placeholder_item_help.rs:25:18
    |
-LL |     const TEST5: _ = 42;
+LL |     const TEST6: _ = 13;
    |                  ^
    |                  |
    |                  not allowed in type signatures
    |                  help: replace with the correct type: `i32`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item_help.rs:25:18
+  --> $DIR/typeck_type_placeholder_item_help.rs:18:18
    |
-LL |     const TEST6: _ = 13;
+LL |     const TEST5: _ = 42;
    |                  ^
    |                  |
    |                  not allowed in type signatures
diff --git a/tests/ui/wf/wf-const-type.rs b/tests/ui/wf/wf-const-type.rs
index 64b0d9c8de7..3b770b4b916 100644
--- a/tests/ui/wf/wf-const-type.rs
+++ b/tests/ui/wf/wf-const-type.rs
@@ -10,6 +10,7 @@ struct NotCopy;
 const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
 //~^ ERROR E0277
 //~| ERROR E0277
+//~| ERROR E0277
 
 
 fn main() { }
diff --git a/tests/ui/wf/wf-const-type.stderr b/tests/ui/wf/wf-const-type.stderr
index d5e0f7672a6..d73642729ea 100644
--- a/tests/ui/wf/wf-const-type.stderr
+++ b/tests/ui/wf/wf-const-type.stderr
@@ -17,6 +17,25 @@ LL | struct NotCopy;
    |
 
 error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
+  --> $DIR/wf-const-type.rs:10:12
+   |
+LL | const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
+   |            ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`, which is required by `Option<NotCopy>: Copy`
+   |
+   = note: required for `Option<NotCopy>` to implement `Copy`
+note: required by a bound in `IsCopy`
+  --> $DIR/wf-const-type.rs:7:17
+   |
+LL | struct IsCopy<T:Copy> { t: T }
+   |                 ^^^^ required by this bound in `IsCopy`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: consider annotating `NotCopy` with `#[derive(Copy)]`
+   |
+LL + #[derive(Copy)]
+LL | struct NotCopy;
+   |
+
+error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
   --> $DIR/wf-const-type.rs:10:50
    |
 LL | const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
@@ -34,6 +53,6 @@ LL + #[derive(Copy)]
 LL | struct NotCopy;
    |
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/wf/wf-static-type.rs b/tests/ui/wf/wf-static-type.rs
index f454fe30e77..1980c5de40c 100644
--- a/tests/ui/wf/wf-static-type.rs
+++ b/tests/ui/wf/wf-static-type.rs
@@ -10,6 +10,7 @@ struct NotCopy;
 static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
 //~^ ERROR E0277
 //~| ERROR E0277
+//~| ERROR E0277
 
 
 fn main() { }
diff --git a/tests/ui/wf/wf-static-type.stderr b/tests/ui/wf/wf-static-type.stderr
index 481173b8a26..36234f3fd17 100644
--- a/tests/ui/wf/wf-static-type.stderr
+++ b/tests/ui/wf/wf-static-type.stderr
@@ -17,6 +17,25 @@ LL | struct NotCopy;
    |
 
 error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
+  --> $DIR/wf-static-type.rs:10:13
+   |
+LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`, which is required by `Option<NotCopy>: Copy`
+   |
+   = note: required for `Option<NotCopy>` to implement `Copy`
+note: required by a bound in `IsCopy`
+  --> $DIR/wf-static-type.rs:7:17
+   |
+LL | struct IsCopy<T:Copy> { t: T }
+   |                 ^^^^ required by this bound in `IsCopy`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: consider annotating `NotCopy` with `#[derive(Copy)]`
+   |
+LL + #[derive(Copy)]
+LL | struct NotCopy;
+   |
+
+error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
   --> $DIR/wf-static-type.rs:10:51
    |
 LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
@@ -34,6 +53,6 @@ LL + #[derive(Copy)]
 LL | struct NotCopy;
    |
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.