about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs152
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs93
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs28
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs24
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs92
-rw-r--r--compiler/rustc_codegen_cranelift/src/archive.rs43
-rw-r--r--compiler/rustc_codegen_gcc/src/archive.rs47
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs120
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs39
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs24
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs13
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs18
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs5
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs12
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs114
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/mod.rs155
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/tests.rs15
-rw-r--r--compiler/rustc_error_messages/src/lib.rs1
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs60
-rw-r--r--compiler/rustc_expand/src/tokenstream/tests.rs6
-rw-r--r--compiler/rustc_index/src/bit_set.rs12
-rw-r--r--compiler/rustc_infer/src/infer/glb.rs20
-rw-r--r--compiler/rustc_infer/src/infer/lub.rs20
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs6
-rw-r--r--compiler/rustc_lint/src/builtin.rs6
-rw-r--r--compiler/rustc_lint/src/lib.rs27
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs18
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs12
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs35
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs1
-rw-r--r--compiler/rustc_middle/src/mir/spanview.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs6
-rw-r--r--compiler/rustc_middle/src/ty/context.rs12
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs7
-rw-r--r--compiler/rustc_middle/src/ty/impls_ty.rs42
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs81
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs22
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs24
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs162
-rw-r--r--compiler/rustc_middle/src/ty/subst.rs4
-rw-r--r--compiler/rustc_middle/src/ty/util.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs24
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs39
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs34
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs13
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs2
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_box_derefs.rs184
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs102
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs2
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs5
-rw-r--r--compiler/rustc_passes/src/check_attr.rs76
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs2
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs23
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs3
-rw-r--r--compiler/rustc_session/src/config.rs123
-rw-r--r--compiler/rustc_session/src/lib.rs1
-rw-r--r--compiler/rustc_span/src/lib.rs3
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs10
-rw-r--r--compiler/rustc_target/src/spec/mod.rs124
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs28
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs66
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs98
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs3
-rw-r--r--compiler/rustc_type_ir/src/lib.rs88
-rw-r--r--compiler/rustc_type_ir/src/sty.rs500
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs4
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/checks.rs4
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs21
-rw-r--r--compiler/rustc_typeck/src/hir_wf_check.rs5
-rw-r--r--library/alloc/src/collections/btree/map.rs10
-rw-r--r--library/alloc/src/collections/btree/set.rs2
-rw-r--r--library/alloc/src/rc.rs40
-rw-r--r--library/alloc/src/sync.rs45
-rw-r--r--library/core/src/fmt/mod.rs1
-rw-r--r--library/core/src/future/into_future.rs4
-rw-r--r--library/core/src/intrinsics.rs2
-rw-r--r--library/core/src/mem/mod.rs22
-rw-r--r--library/core/src/ops/generator.rs3
-rw-r--r--library/core/src/pin.rs7
-rw-r--r--library/core/src/slice/iter.rs48
-rw-r--r--library/core/src/slice/sort.rs19
-rw-r--r--library/proc_macro/src/bridge/client.rs3
-rw-r--r--library/std/src/alloc.rs8
-rw-r--r--library/std/src/collections/hash/map.rs2
-rw-r--r--library/std/src/fs.rs8
-rw-r--r--library/std/src/io/mod.rs62
-rw-r--r--library/std/src/io/tests.rs8
-rw-r--r--library/std/src/os/unix/io/mod.rs19
-rw-r--r--library/std/src/os/unix/net/ancillary.rs4
-rw-r--r--library/std/src/os/windows/process.rs40
-rw-r--r--library/std/src/path.rs17
-rw-r--r--library/std/src/process.rs16
-rw-r--r--library/std/src/sync/condvar.rs4
-rw-r--r--library/std/src/sync/mutex.rs4
-rw-r--r--library/std/src/sync/poison.rs1
-rw-r--r--library/std/src/sync/rwlock.rs4
-rw-r--r--library/std/src/sys/itron/mutex.rs1
-rw-r--r--library/std/src/sys/solid/rwlock.rs1
-rw-r--r--library/std/src/sys/unsupported/locks/condvar.rs1
-rw-r--r--library/std/src/sys/unsupported/locks/mutex.rs1
-rw-r--r--library/std/src/sys/unsupported/locks/rwlock.rs1
-rw-r--r--library/std/src/sys/windows/locks/condvar.rs1
-rw-r--r--library/std/src/sys/windows/locks/mutex.rs1
-rw-r--r--library/std/src/sys/windows/locks/rwlock.rs1
-rw-r--r--library/std/src/sys_common/condvar.rs3
-rw-r--r--library/std/src/sys_common/mutex.rs11
-rw-r--r--library/std/src/sys_common/rwlock.rs10
-rw-r--r--library/std/src/thread/mod.rs7
-rw-r--r--library/std/src/thread/scoped.rs7
-rw-r--r--src/bootstrap/Cargo.toml1
-rw-r--r--src/bootstrap/dist.rs10
-rw-r--r--src/bootstrap/lib.rs35
-rw-r--r--src/bootstrap/tarball.rs20
-rw-r--r--src/doc/unstable-book/src/language-features/lang-items.md4
-rw-r--r--src/etc/htmldocck.py4
-rw-r--r--src/librustdoc/doctest.rs4
-rw-r--r--src/librustdoc/html/format.rs44
-rw-r--r--src/librustdoc/html/layout.rs2
-rw-r--r--src/librustdoc/html/render/context.rs6
-rw-r--r--src/librustdoc/html/render/mod.rs19
-rw-r--r--src/librustdoc/html/render/write_shared.rs2
-rw-r--r--src/librustdoc/html/sources.rs2
-rw-r--r--src/librustdoc/html/static/js/main.js130
-rw-r--r--src/librustdoc/html/static/js/search.js5
-rw-r--r--src/librustdoc/html/static/js/source-script.js41
-rw-r--r--src/librustdoc/html/templates/page.html15
-rw-r--r--src/test/codegen/loads.rs40
-rw-r--r--src/test/debuginfo/lexical-scope-in-if-let.rs100
-rw-r--r--src/test/mir-opt/const_prop/boxes.main.ConstProp.diff14
-rw-r--r--src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff22
-rw-r--r--src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff22
-rw-r--r--src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff18
-rw-r--r--src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff64
-rw-r--r--src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff44
-rw-r--r--src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff44
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir6
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir6
-rw-r--r--src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir14
-rw-r--r--src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff34
-rw-r--r--src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff50
-rw-r--r--src/test/mir-opt/unreachable.main.UnreachablePropagation.diff26
-rw-r--r--src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff42
-rw-r--r--src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff24
-rw-r--r--src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff24
-rw-r--r--src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir2
-rw-r--r--src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir2
-rw-r--r--src/test/pretty/where-clauses.rs3
-rw-r--r--src/test/rustdoc-gui/duplicate-macro-reexport.goml6
-rw-r--r--src/test/rustdoc-gui/headings.goml4
-rw-r--r--src/test/rustdoc/tuples.link1_i32.html1
-rw-r--r--src/test/rustdoc/tuples.link1_t.html1
-rw-r--r--src/test/rustdoc/tuples.link2_i32.html1
-rw-r--r--src/test/rustdoc/tuples.link2_t.html1
-rw-r--r--src/test/rustdoc/tuples.link2_tu.html1
-rw-r--r--src/test/rustdoc/tuples.link_unit.html1
-rw-r--r--src/test/rustdoc/tuples.rs12
-rw-r--r--src/test/ui/argument-suggestions/basic.stderr8
-rw-r--r--src/test/ui/argument-suggestions/complex.stderr4
-rw-r--r--src/test/ui/argument-suggestions/issue-96638.stderr4
-rw-r--r--src/test/ui/argument-suggestions/issue-97197.stderr4
-rw-r--r--src/test/ui/argument-suggestions/issue-97484.stderr4
-rw-r--r--src/test/ui/argument-suggestions/missing_arguments.stderr76
-rw-r--r--src/test/ui/argument-suggestions/mixed_cases.stderr24
-rw-r--r--src/test/ui/associated-types/issue-47139-2.rs (renamed from src/test/ui/issues/issue-47139-2.rs)0
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-1.stderr8
-rw-r--r--src/test/ui/cast/issue-10991.rs (renamed from src/test/ui/issues/issue-10991.rs)0
-rw-r--r--src/test/ui/cast/issue-10991.stderr (renamed from src/test/ui/issues/issue-10991.stderr)0
-rw-r--r--src/test/ui/codegen/issue-28950.rs (renamed from src/test/ui/issues/issue-28950.rs)0
-rw-r--r--src/test/ui/codegen/issue-63787.rs (renamed from src/test/ui/issues/issue-63787.rs)0
-rw-r--r--src/test/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr (renamed from src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.stderr)2
-rw-r--r--src/test/ui/const-generics/issues/issue-73727-static-reference-array-const-param.rs14
-rw-r--r--src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs6
-rw-r--r--src/test/ui/consts/const-eval/format.rs21
-rw-r--r--src/test/ui/consts/const-eval/format.stderr78
-rw-r--r--src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr24
-rw-r--r--src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr24
-rw-r--r--src/test/ui/consts/recursive-zst-static.default.stderr10
-rw-r--r--src/test/ui/consts/recursive-zst-static.unleash.stderr10
-rw-r--r--src/test/ui/consts/write-to-static-mut-in-static.stderr12
-rw-r--r--src/test/ui/derives/issue-97343.stderr2
-rw-r--r--src/test/ui/deriving/issue-6341.rs (renamed from src/test/ui/issues/issue-6341.rs)0
-rw-r--r--src/test/ui/error-codes/E0057.stderr4
-rw-r--r--src/test/ui/error-codes/E0060.stderr4
-rw-r--r--src/test/ui/error-codes/E0061.stderr8
-rw-r--r--src/test/ui/error-codes/E0109.stderr2
-rw-r--r--src/test/ui/error-codes/E0110.stderr2
-rw-r--r--src/test/ui/error-codes/E0411.stderr2
-rw-r--r--src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr340
-rw-r--r--src/test/ui/hrtb/hrtb-just-for-static.stderr2
-rw-r--r--src/test/ui/hrtb/issue-58451.stderr4
-rw-r--r--src/test/ui/imports/issue-24883.rs (renamed from src/test/ui/issues/issue-24883.rs)0
-rw-r--r--src/test/ui/imports/issue-68103.rs (renamed from src/test/ui/issues/issue-68103.rs)0
-rw-r--r--src/test/ui/inference/issue-72690.rs (renamed from src/test/ui/issues/issue-72690.rs)0
-rw-r--r--src/test/ui/inference/issue-72690.stderr (renamed from src/test/ui/issues/issue-72690.stderr)0
-rw-r--r--src/test/ui/issue-94866.rs14
-rw-r--r--src/test/ui/issue-94866.stderr21
-rw-r--r--src/test/ui/issues/issue-18819.stderr4
-rw-r--r--src/test/ui/issues/issue-22706.stderr2
-rw-r--r--src/test/ui/issues/issue-3044.stderr2
-rw-r--r--src/test/ui/issues/issue-57924.stderr2
-rw-r--r--src/test/ui/issues/issue-60989.stderr4
-rw-r--r--src/test/ui/issues/issue-98299.rs18
-rw-r--r--src/test/ui/issues/issue-98299.stderr9
-rw-r--r--src/test/ui/lifetimes/issue-97194.rs2
-rw-r--r--src/test/ui/lifetimes/issue-97194.stderr4
-rw-r--r--src/test/ui/lint/issue-35075.rs (renamed from src/test/ui/issues/issue-35075.rs)0
-rw-r--r--src/test/ui/lint/issue-35075.stderr (renamed from src/test/ui/issues/issue-35075.stderr)0
-rw-r--r--src/test/ui/lint/unused/unused-attr-doc-hidden.fixed55
-rw-r--r--src/test/ui/lint/unused/unused-attr-doc-hidden.rs55
-rw-r--r--src/test/ui/lint/unused/unused-attr-doc-hidden.stderr67
-rw-r--r--src/test/ui/lub-glb/empty-binder-future-compat.rs22
-rw-r--r--src/test/ui/lub-glb/empty-binders-err.rs55
-rw-r--r--src/test/ui/lub-glb/empty-binders-err.stderr59
-rw-r--r--src/test/ui/lub-glb/empty-binders.rs45
-rw-r--r--src/test/ui/macros/issue-8851.rs (renamed from src/test/ui/issues/issue-8851.rs)0
-rw-r--r--src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs42
-rw-r--r--src/test/ui/match/issue-46920-byte-array-patterns.rs (renamed from src/test/ui/issues/issue-46920-byte-array-patterns.rs)0
-rw-r--r--src/test/ui/methods/method-call-err-msg.stderr12
-rw-r--r--src/test/ui/mir/ssa-analysis-regression-50041.rs18
-rw-r--r--src/test/ui/mismatched_types/overloaded-calls-bad.stderr8
-rw-r--r--src/test/ui/mod-subitem-as-enum-variant.stderr2
-rw-r--r--src/test/ui/nll/issue-27282-move-match-input-into-guard.rs (renamed from src/test/ui/borrowck/issue-27282-move-match-input-into-guard.rs)0
-rw-r--r--src/test/ui/nll/issue-27282-move-match-input-into-guard.stderr (renamed from src/test/ui/borrowck/issue-27282-move-match-input-into-guard.stderr)0
-rw-r--r--src/test/ui/nll/issue-27282-move-ref-mut-into-guard.rs (renamed from src/test/ui/issues/issue-27282-move-ref-mut-into-guard.rs)0
-rw-r--r--src/test/ui/nll/issue-27282-move-ref-mut-into-guard.stderr (renamed from src/test/ui/issues/issue-27282-move-ref-mut-into-guard.stderr)0
-rw-r--r--src/test/ui/nll/issue-27282-mutate-before-diverging-arm-1.rs (renamed from src/test/ui/issues/issue-27282-mutate-before-diverging-arm-1.rs)0
-rw-r--r--src/test/ui/nll/issue-27282-mutate-before-diverging-arm-1.stderr (renamed from src/test/ui/issues/issue-27282-mutate-before-diverging-arm-1.stderr)0
-rw-r--r--src/test/ui/nll/issue-27282-mutate-before-diverging-arm-2.rs (renamed from src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.rs)0
-rw-r--r--src/test/ui/nll/issue-27282-mutate-before-diverging-arm-2.stderr (renamed from src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.stderr)0
-rw-r--r--src/test/ui/nll/issue-27282-mutate-before-diverging-arm-3.rs (renamed from src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.rs)0
-rw-r--r--src/test/ui/nll/issue-27282-mutate-before-diverging-arm-3.stderr (renamed from src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.stderr)0
-rw-r--r--src/test/ui/nll/issue-27282-mutation-in-guard.rs (renamed from src/test/ui/borrowck/issue-27282-mutation-in-guard.rs)0
-rw-r--r--src/test/ui/nll/issue-27282-mutation-in-guard.stderr (renamed from src/test/ui/borrowck/issue-27282-mutation-in-guard.stderr)0
-rw-r--r--src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.rs (renamed from src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.rs)0
-rw-r--r--src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.stderr (renamed from src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr)0
-rw-r--r--src/test/ui/nll/issue-52057.rs (renamed from src/test/ui/issues/issue-52057.rs)0
-rw-r--r--src/test/ui/nll/issue-97997.rs16
-rw-r--r--src/test/ui/nll/issue-97997.stderr20
-rw-r--r--src/test/ui/not-enough-arguments.stderr8
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr50
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr40
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match.stderr4
-rw-r--r--src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr2
-rw-r--r--src/test/ui/recursion/recursive-static-definition.stderr9
-rw-r--r--src/test/ui/resolve/issue-24968.rs25
-rw-r--r--src/test/ui/resolve/issue-24968.stderr56
-rw-r--r--src/test/ui/statics/uninhabited-static.stderr12
-rw-r--r--src/test/ui/structs/struct-path-associated-type.stderr4
-rw-r--r--src/test/ui/structs/struct-path-self.stderr6
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple-errors.stderr12
-rw-r--r--src/test/ui/test-attrs/issue-16597-empty.rs (renamed from src/test/ui/issues/issue-16597-empty.rs)0
-rw-r--r--src/test/ui/test-attrs/issue-16597.rs (renamed from src/test/ui/issues/issue-16597.rs)0
-rw-r--r--src/test/ui/traits/issue-38033.rs (renamed from src/test/ui/issues/issue-38033.rs)0
-rw-r--r--src/test/ui/tuple/wrong_argument_ice-3.stderr4
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr54
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr4
-rw-r--r--src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr2
-rw-r--r--src/test/ui/type-alias/issue-62263-self-in-atb.rs2
-rw-r--r--src/test/ui/type-alias/issue-62263-self-in-atb.stderr4
-rw-r--r--src/test/ui/type-alias/issue-62305-self-assoc-ty.rs2
-rw-r--r--src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr4
-rw-r--r--src/test/ui/type-alias/issue-62364-self-ty-arg.stderr6
-rw-r--r--src/test/ui/type/issue-91268.stderr2
-rw-r--r--src/test/ui/typeck/issue-10401.rs (renamed from src/test/ui/issues/issue-10401.rs)0
-rw-r--r--src/test/ui/typeck/issue-10401.stderr (renamed from src/test/ui/issues/issue-10401.stderr)0
-rw-r--r--src/test/ui/typeck/prim-with-args.stderr44
-rw-r--r--src/test/ui/typeck/struct-enum-wrong-args.stderr16
-rw-r--r--src/test/ui/unsafe/issue-3080.mir.stderr (renamed from src/test/ui/issues/issue-3080.mir.stderr)0
-rw-r--r--src/test/ui/unsafe/issue-3080.rs (renamed from src/test/ui/issues/issue-3080.rs)0
-rw-r--r--src/test/ui/unsafe/issue-3080.thir.stderr (renamed from src/test/ui/issues/issue-3080.thir.stderr)0
-rw-r--r--src/test/ui/unsafe/issue-47412.mir.stderr (renamed from src/test/ui/issues/issue-47412.mir.stderr)0
-rw-r--r--src/test/ui/unsafe/issue-47412.rs (renamed from src/test/ui/issues/issue-47412.rs)0
-rw-r--r--src/test/ui/unsafe/issue-47412.thir.stderr (renamed from src/test/ui/issues/issue-47412.thir.stderr)0
-rw-r--r--src/test/ui/use/use-self-type.rs2
-rw-r--r--src/test/ui/use/use-self-type.stderr6
-rw-r--r--src/test/ui/usize-generic-argument-parent.stderr2
-rw-r--r--src/test/ui/wf/issue-95665.rs18
-rw-r--r--src/test/ui/wf/issue-95665.stderr15
m---------src/tools/rust-analyzer16
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
294 files changed, 3878 insertions, 2461 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5a0c94d3b68..6857451116d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -236,6 +236,7 @@ dependencies = [
  "sysinfo",
  "tar",
  "toml",
+ "walkdir",
  "winapi",
  "xz2",
 ]
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 84d8829c398..37de90d64c7 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -25,7 +25,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_span::{Span, DUMMY_SP};
 use smallvec::{smallvec, SmallVec};
 
-use std::{fmt, iter, mem};
+use std::{fmt, iter};
 
 /// When the main Rust parser encounters a syntax-extension invocation, it
 /// parses the arguments to the invocation as a token tree. This is a very
@@ -399,45 +399,6 @@ impl TokenStream {
         self.0.len()
     }
 
-    pub fn from_streams(mut streams: SmallVec<[TokenStream; 2]>) -> TokenStream {
-        match streams.len() {
-            0 => TokenStream::default(),
-            1 => streams.pop().unwrap(),
-            _ => {
-                // We are going to extend the first stream in `streams` with
-                // the elements from the subsequent streams. This requires
-                // using `make_mut()` on the first stream, and in practice this
-                // doesn't cause cloning 99.9% of the time.
-                //
-                // One very common use case is when `streams` has two elements,
-                // where the first stream has any number of elements within
-                // (often 1, but sometimes many more) and the second stream has
-                // a single element within.
-
-                // Determine how much the first stream will be extended.
-                // Needed to avoid quadratic blow up from on-the-fly
-                // reallocations (#57735).
-                let num_appends = streams.iter().skip(1).map(|ts| ts.len()).sum();
-
-                // Get the first stream. If it's `None`, create an empty
-                // stream.
-                let mut iter = streams.drain(..);
-                let mut first_stream_lrc = iter.next().unwrap().0;
-
-                // Append the elements to the first stream, after reserving
-                // space for them.
-                let first_vec_mut = Lrc::make_mut(&mut first_stream_lrc);
-                first_vec_mut.reserve(num_appends);
-                for stream in iter {
-                    first_vec_mut.extend(stream.0.iter().cloned());
-                }
-
-                // Create the final `TokenStream`.
-                TokenStream(first_stream_lrc)
-            }
-        }
-    }
-
     pub fn trees(&self) -> CursorRef<'_> {
         CursorRef::new(self)
     }
@@ -562,50 +523,65 @@ impl TokenStreamBuilder {
     }
 
     pub fn push<T: Into<TokenStream>>(&mut self, stream: T) {
-        let mut stream = stream.into();
-
-        // If `self` is not empty and the last tree within the last stream is a
-        // token tree marked with `Joint`...
-        if let Some(TokenStream(ref mut last_stream_lrc)) = self.0.last_mut()
-            && let Some((TokenTree::Token(last_token), Spacing::Joint)) = last_stream_lrc.last()
-            // ...and `stream` is not empty and the first tree within it is
-            // a token tree...
-            && let TokenStream(ref mut stream_lrc) = stream
-            && let Some((TokenTree::Token(token), spacing)) = stream_lrc.first()
-            // ...and the two tokens can be glued together...
-            && let Some(glued_tok) = last_token.glue(&token)
-        {
-            // ...then do so, by overwriting the last token
-            // tree in `self` and removing the first token tree
-            // from `stream`. This requires using `make_mut()`
-            // on the last stream in `self` and on `stream`,
-            // and in practice this doesn't cause cloning 99.9%
-            // of the time.
-
-            // Overwrite the last token tree with the merged
-            // token.
-            let last_vec_mut = Lrc::make_mut(last_stream_lrc);
-            *last_vec_mut.last_mut().unwrap() = (TokenTree::Token(glued_tok), *spacing);
-
-            // Remove the first token tree from `stream`. (This
-            // is almost always the only tree in `stream`.)
-            let stream_vec_mut = Lrc::make_mut(stream_lrc);
-            stream_vec_mut.remove(0);
-
-            // Don't push `stream` if it's empty -- that could
-            // block subsequent token gluing, by getting
-            // between two token trees that should be glued
-            // together.
-            if !stream.is_empty() {
-                self.0.push(stream);
-            }
-            return;
-        }
-        self.0.push(stream);
+        self.0.push(stream.into());
     }
 
     pub fn build(self) -> TokenStream {
-        TokenStream::from_streams(self.0)
+        let mut streams = self.0;
+        match streams.len() {
+            0 => TokenStream::default(),
+            1 => streams.pop().unwrap(),
+            _ => {
+                // We will extend the first stream in `streams` with the
+                // elements from the subsequent streams. This requires using
+                // `make_mut()` on the first stream, and in practice this
+                // doesn't cause cloning 99.9% of the time.
+                //
+                // One very common use case is when `streams` has two elements,
+                // where the first stream has any number of elements within
+                // (often 1, but sometimes many more) and the second stream has
+                // a single element within.
+
+                // Determine how much the first stream will be extended.
+                // Needed to avoid quadratic blow up from on-the-fly
+                // reallocations (#57735).
+                let num_appends = streams.iter().skip(1).map(|ts| ts.len()).sum();
+
+                // Get the first stream, which will become the result stream.
+                // If it's `None`, create an empty stream.
+                let mut iter = streams.drain(..);
+                let mut res_stream_lrc = iter.next().unwrap().0;
+
+                // Append the subsequent elements to the result stream, after
+                // reserving space for them.
+                let res_vec_mut = Lrc::make_mut(&mut res_stream_lrc);
+                res_vec_mut.reserve(num_appends);
+                for stream in iter {
+                    let stream_iter = stream.0.iter().cloned();
+
+                    // If (a) `res_mut_vec` is not empty and the last tree
+                    // within it is a token tree marked with `Joint`, and (b)
+                    // `stream` is not empty and the first tree within it is a
+                    // token tree, and (c) the two tokens can be glued
+                    // together...
+                    if let Some((TokenTree::Token(last_tok), Spacing::Joint)) = res_vec_mut.last()
+                        && let Some((TokenTree::Token(tok), spacing)) = stream.0.first()
+                        && let Some(glued_tok) = last_tok.glue(&tok)
+                    {
+                        // ...then overwrite the last token tree in
+                        // `res_vec_mut` with the glued token, and skip the
+                        // first token tree from `stream`.
+                        *res_vec_mut.last_mut().unwrap() = (TokenTree::Token(glued_tok), *spacing);
+                        res_vec_mut.extend(stream_iter.skip(1));
+                    } else {
+                        // Append all of `stream`.
+                        res_vec_mut.extend(stream_iter);
+                    }
+                }
+
+                TokenStream(res_stream_lrc)
+            }
+        }
     }
 }
 
@@ -679,20 +655,6 @@ impl Cursor {
         })
     }
 
-    pub fn index(&self) -> usize {
-        self.index
-    }
-
-    pub fn append(&mut self, new_stream: TokenStream) {
-        if new_stream.is_empty() {
-            return;
-        }
-        let index = self.index;
-        let stream = mem::take(&mut self.stream);
-        *self = TokenStream::from_streams(smallvec![stream, new_stream]).into_trees();
-        self.index = index;
-    }
-
     pub fn look_ahead(&self, n: usize) -> Option<&TokenTree> {
         self.stream.0[self.index..].get(n).map(|(tree, _)| tree)
     }
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index b80a553b418..ad8dbfd506d 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -814,7 +814,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
     }
 
     fn bounds_to_string(&self, bounds: &[ast::GenericBound]) -> String {
-        Self::to_string(|s| s.print_type_bounds("", bounds))
+        Self::to_string(|s| s.print_type_bounds(bounds))
     }
 
     fn pat_to_string(&self, pat: &ast::Pat) -> String {
@@ -991,7 +991,12 @@ impl<'a> State<'a> {
                     Term::Const(c) => self.print_expr_anon_const(c, &[]),
                 }
             }
-            ast::AssocConstraintKind::Bound { bounds } => self.print_type_bounds(":", &*bounds),
+            ast::AssocConstraintKind::Bound { bounds } => {
+                if !bounds.is_empty() {
+                    self.word_nbsp(":");
+                    self.print_type_bounds(&bounds);
+                }
+            }
         }
     }
 
@@ -1045,11 +1050,14 @@ impl<'a> State<'a> {
             }
             ast::TyKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, false),
             ast::TyKind::TraitObject(ref bounds, syntax) => {
-                let prefix = if syntax == ast::TraitObjectSyntax::Dyn { "dyn" } else { "" };
-                self.print_type_bounds(prefix, &bounds);
+                if syntax == ast::TraitObjectSyntax::Dyn {
+                    self.word_nbsp("dyn");
+                }
+                self.print_type_bounds(bounds);
             }
             ast::TyKind::ImplTrait(_, ref bounds) => {
-                self.print_type_bounds("impl", &bounds);
+                self.word_nbsp("impl");
+                self.print_type_bounds(bounds);
             }
             ast::TyKind::Array(ref ty, ref length) => {
                 self.word("[");
@@ -1549,29 +1557,24 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_type_bounds(&mut self, prefix: &'static str, bounds: &[ast::GenericBound]) {
-        if !bounds.is_empty() {
-            self.word(prefix);
-            let mut first = true;
-            for bound in bounds {
-                if !(first && prefix.is_empty()) {
-                    self.nbsp();
-                }
-                if first {
-                    first = false;
-                } else {
-                    self.word_space("+");
-                }
+    pub fn print_type_bounds(&mut self, bounds: &[ast::GenericBound]) {
+        let mut first = true;
+        for bound in bounds {
+            if first {
+                first = false;
+            } else {
+                self.nbsp();
+                self.word_space("+");
+            }
 
-                match bound {
-                    GenericBound::Trait(tref, modifier) => {
-                        if modifier == &TraitBoundModifier::Maybe {
-                            self.word("?");
-                        }
-                        self.print_poly_trait_ref(tref);
+            match bound {
+                GenericBound::Trait(tref, modifier) => {
+                    if modifier == &TraitBoundModifier::Maybe {
+                        self.word("?");
                     }
-                    GenericBound::Outlives(lt) => self.print_lifetime(*lt),
+                    self.print_poly_trait_ref(tref);
                 }
+                GenericBound::Outlives(lt) => self.print_lifetime(*lt),
             }
         }
     }
@@ -1580,22 +1583,14 @@ impl<'a> State<'a> {
         self.print_name(lifetime.ident.name)
     }
 
-    pub(crate) fn print_lifetime_bounds(
-        &mut self,
-        lifetime: ast::Lifetime,
-        bounds: &ast::GenericBounds,
-    ) {
-        self.print_lifetime(lifetime);
-        if !bounds.is_empty() {
-            self.word(": ");
-            for (i, bound) in bounds.iter().enumerate() {
-                if i != 0 {
-                    self.word(" + ");
-                }
-                match bound {
-                    ast::GenericBound::Outlives(lt) => self.print_lifetime(*lt),
-                    _ => panic!(),
-                }
+    pub(crate) fn print_lifetime_bounds(&mut self, bounds: &ast::GenericBounds) {
+        for (i, bound) in bounds.iter().enumerate() {
+            if i != 0 {
+                self.word(" + ");
+            }
+            match bound {
+                ast::GenericBound::Outlives(lt) => self.print_lifetime(*lt),
+                _ => panic!(),
             }
         }
     }
@@ -1613,11 +1608,18 @@ impl<'a> State<'a> {
             match param.kind {
                 ast::GenericParamKind::Lifetime => {
                     let lt = ast::Lifetime { id: param.id, ident: param.ident };
-                    s.print_lifetime_bounds(lt, &param.bounds)
+                    s.print_lifetime(lt);
+                    if !param.bounds.is_empty() {
+                        s.word_nbsp(":");
+                        s.print_lifetime_bounds(&param.bounds)
+                    }
                 }
                 ast::GenericParamKind::Type { ref default } => {
                     s.print_ident(param.ident);
-                    s.print_type_bounds(":", &param.bounds);
+                    if !param.bounds.is_empty() {
+                        s.word_nbsp(":");
+                        s.print_type_bounds(&param.bounds);
+                    }
                     if let Some(ref default) = default {
                         s.space();
                         s.word_space("=");
@@ -1630,7 +1632,10 @@ impl<'a> State<'a> {
                     s.space();
                     s.word_space(":");
                     s.print_type(ty);
-                    s.print_type_bounds(":", &param.bounds);
+                    if !param.bounds.is_empty() {
+                        s.word_nbsp(":");
+                        s.print_type_bounds(&param.bounds);
+                    }
                     if let Some(ref default) = default {
                         s.space();
                         s.word_space("=");
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index 67b539a7ad4..f1caf22f364 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -114,7 +114,10 @@ impl<'a> State<'a> {
         self.word_space("type");
         self.print_ident(ident);
         self.print_generic_params(&generics.params);
-        self.print_type_bounds(":", bounds);
+        if !bounds.is_empty() {
+            self.word_nbsp(":");
+            self.print_type_bounds(bounds);
+        }
         self.print_where_clause_parts(where_clauses.0.0, before_predicates);
         if let Some(ty) = ty {
             self.space();
@@ -320,7 +323,10 @@ impl<'a> State<'a> {
                         real_bounds.push(b.clone());
                     }
                 }
-                self.print_type_bounds(":", &real_bounds);
+                if !real_bounds.is_empty() {
+                    self.word_nbsp(":");
+                    self.print_type_bounds(&real_bounds);
+                }
                 self.print_where_clause(&generics.where_clause);
                 self.word(" ");
                 self.bopen();
@@ -347,7 +353,10 @@ impl<'a> State<'a> {
                     }
                 }
                 self.nbsp();
-                self.print_type_bounds("=", &real_bounds);
+                if !real_bounds.is_empty() {
+                    self.word_nbsp("=");
+                    self.print_type_bounds(&real_bounds);
+                }
                 self.print_where_clause(&generics.where_clause);
                 self.word(";");
                 self.end(); // end inner head-block
@@ -618,14 +627,23 @@ impl<'a> State<'a> {
             }) => {
                 self.print_formal_generic_params(bound_generic_params);
                 self.print_type(bounded_ty);
-                self.print_type_bounds(":", bounds);
+                self.word(":");
+                if !bounds.is_empty() {
+                    self.nbsp();
+                    self.print_type_bounds(bounds);
+                }
             }
             ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
                 lifetime,
                 bounds,
                 ..
             }) => {
-                self.print_lifetime_bounds(*lifetime, bounds);
+                self.print_lifetime(*lifetime);
+                self.word(":");
+                if !bounds.is_empty() {
+                    self.nbsp();
+                    self.print_lifetime_bounds(bounds);
+                }
             }
             ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { lhs_ty, rhs_ty, .. }) => {
                 self.print_type(lhs_ty);
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 2c460bcb72d..fcb0978111e 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -500,7 +500,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     }
 
     /// Returns an iterator over all the region indices.
-    pub fn regions(&self) -> impl Iterator<Item = RegionVid> + '_ {
+    pub fn regions(&self) -> impl Iterator<Item = RegionVid> + 'tcx {
         self.definitions.indices()
     }
 
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index ae6b8e0ae30..355254fe942 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -357,12 +357,20 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
                 .add_element(live_region_vid, location);
         });
 
+        // HACK(compiler-errors): Constants that are gathered into Body.required_consts
+        // have their locations erased...
+        let locations = if location != Location::START {
+            location.to_locations()
+        } else {
+            Locations::All(constant.span)
+        };
+
         if let Some(annotation_index) = constant.user_ty {
             if let Err(terr) = self.cx.relate_type_and_user_type(
                 constant.literal.ty(),
                 ty::Variance::Invariant,
                 &UserTypeProjection { base: annotation_index, projs: vec![] },
-                location.to_locations(),
+                locations,
                 ConstraintCategory::Boring,
             ) {
                 let annotation = &self.cx.user_type_annotations[annotation_index];
@@ -390,12 +398,9 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
                                      promoted: &Body<'tcx>,
                                      ty,
                                      san_ty| {
-                        if let Err(terr) = verifier.cx.eq_types(
-                            ty,
-                            san_ty,
-                            location.to_locations(),
-                            ConstraintCategory::Boring,
-                        ) {
+                        if let Err(terr) =
+                            verifier.cx.eq_types(ty, san_ty, locations, ConstraintCategory::Boring)
+                        {
                             span_mirbug!(
                                 verifier,
                                 promoted,
@@ -416,7 +421,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
                     }
                 } else {
                     if let Err(terr) = self.cx.fully_perform_op(
-                        location.to_locations(),
+                        locations,
                         ConstraintCategory::Boring,
                         self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
                             constant.literal.ty(),
@@ -435,7 +440,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
                 }
             } else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
                 let unnormalized_ty = tcx.type_of(static_def_id);
-                let locations = location.to_locations();
                 let normalized_ty = self.cx.normalize(unnormalized_ty, locations);
                 let literal_ty = constant.literal.ty().builtin_deref(true).unwrap().ty;
 
@@ -454,7 +458,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
                 self.cx.normalize_and_prove_instantiated_predicates(
                     def_id,
                     instantiated_predicates,
-                    location.to_locations(),
+                    locations,
                 );
             }
         }
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index 37a4bf5fdca..cad30181212 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -5,7 +5,7 @@ use rustc_ast::{
     token,
     tokenstream::{DelimSpan, TokenStream, TokenTree},
     BorrowKind, Expr, ExprKind, ItemKind, MacArgs, MacCall, MacDelimiter, Mutability, Path,
-    PathSegment, Stmt, UseTree, UseTreeKind, DUMMY_NODE_ID,
+    PathSegment, Stmt, StructRest, UseTree, UseTreeKind, DUMMY_NODE_ID,
 };
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
@@ -167,15 +167,103 @@ impl<'cx, 'a> Context<'cx, 'a> {
     /// See [Self::manage_initial_capture] and [Self::manage_try_capture]
     fn manage_cond_expr(&mut self, expr: &mut P<Expr>) {
         match (*expr).kind {
+            ExprKind::AddrOf(_, _, ref mut local_expr) => {
+                self.manage_cond_expr(local_expr);
+            }
+            ExprKind::Array(ref mut local_exprs) => {
+                for local_expr in local_exprs {
+                    self.manage_cond_expr(local_expr);
+                }
+            }
             ExprKind::Binary(_, ref mut lhs, ref mut rhs) => {
                 self.manage_cond_expr(lhs);
                 self.manage_cond_expr(rhs);
             }
+            ExprKind::Call(_, ref mut local_exprs) => {
+                for local_expr in local_exprs {
+                    self.manage_cond_expr(local_expr);
+                }
+            }
+            ExprKind::Cast(ref mut local_expr, _) => {
+                self.manage_cond_expr(local_expr);
+            }
+            ExprKind::Index(ref mut prefix, ref mut suffix) => {
+                self.manage_cond_expr(prefix);
+                self.manage_cond_expr(suffix);
+            }
+            ExprKind::MethodCall(_, ref mut local_exprs, _) => {
+                for local_expr in local_exprs.iter_mut().skip(1) {
+                    self.manage_cond_expr(local_expr);
+                }
+            }
             ExprKind::Path(_, Path { ref segments, .. }) if let &[ref path_segment] = &segments[..] => {
                 let path_ident = path_segment.ident;
                 self.manage_initial_capture(expr, path_ident);
             }
-            _ => {}
+            ExprKind::Paren(ref mut local_expr) => {
+                self.manage_cond_expr(local_expr);
+            }
+            ExprKind::Range(ref mut prefix, ref mut suffix, _) => {
+                if let Some(ref mut elem) = prefix {
+                    self.manage_cond_expr(elem);
+                }
+                if let Some(ref mut elem) = suffix {
+                    self.manage_cond_expr(elem);
+                }
+            }
+            ExprKind::Repeat(ref mut local_expr, ref mut elem) => {
+                self.manage_cond_expr(local_expr);
+                self.manage_cond_expr(&mut elem.value);
+            }
+            ExprKind::Struct(ref mut elem) => {
+                for field in &mut elem.fields {
+                    self.manage_cond_expr(&mut field.expr);
+                }
+                if let StructRest::Base(ref mut local_expr) = elem.rest {
+                    self.manage_cond_expr(local_expr);
+                }
+            }
+            ExprKind::Tup(ref mut local_exprs) => {
+                for local_expr in local_exprs {
+                    self.manage_cond_expr(local_expr);
+                }
+            }
+            ExprKind::Unary(_, ref mut local_expr) => {
+                self.manage_cond_expr(local_expr);
+            }
+            // Expressions that are not worth or can not be captured.
+            //
+            // Full list instead of `_` to catch possible future inclusions and to
+            // sync with the `rfc-2011-nicer-assert-messages/all-expr-kinds.rs` test.
+            ExprKind::Assign(_, _, _)
+            | ExprKind::AssignOp(_, _, _)
+            | ExprKind::Async(_, _, _)
+            | ExprKind::Await(_)
+            | ExprKind::Block(_, _)
+            | ExprKind::Box(_)
+            | ExprKind::Break(_, _)
+            | ExprKind::Closure(_, _, _, _, _, _)
+            | ExprKind::ConstBlock(_)
+            | ExprKind::Continue(_)
+            | ExprKind::Err
+            | ExprKind::Field(_, _)
+            | ExprKind::ForLoop(_, _, _, _)
+            | ExprKind::If(_, _, _)
+            | ExprKind::InlineAsm(_)
+            | ExprKind::Let(_, _, _)
+            | ExprKind::Lit(_)
+            | ExprKind::Loop(_, _)
+            | ExprKind::MacCall(_)
+            | ExprKind::Match(_, _)
+            | ExprKind::Path(_, _)
+            | ExprKind::Ret(_)
+            | ExprKind::Try(_)
+            | ExprKind::TryBlock(_)
+            | ExprKind::Type(_, _)
+            | ExprKind::Underscore
+            | ExprKind::While(_, _, _)
+            | ExprKind::Yeet(_)
+            | ExprKind::Yield(_) => {}
         }
     }
 
diff --git a/compiler/rustc_codegen_cranelift/src/archive.rs b/compiler/rustc_codegen_cranelift/src/archive.rs
index a099e8b3a6a..0812f930b5d 100644
--- a/compiler/rustc_codegen_cranelift/src/archive.rs
+++ b/compiler/rustc_codegen_cranelift/src/archive.rs
@@ -30,25 +30,7 @@ pub(crate) struct ArArchiveBuilder<'a> {
 }
 
 impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
-    fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self {
-        let (src_archives, entries) = if let Some(input) = input {
-            let read_cache = ReadCache::new(File::open(input).unwrap());
-            let archive = ArchiveFile::parse(&read_cache).unwrap();
-            let mut entries = Vec::new();
-
-            for entry in archive.members() {
-                let entry = entry.unwrap();
-                entries.push((
-                    entry.name().to_vec(),
-                    ArchiveEntry::FromArchive { archive_index: 0, file_range: entry.file_range() },
-                ));
-            }
-
-            (vec![read_cache.into_inner()], entries)
-        } else {
-            (vec![], Vec::new())
-        };
-
+    fn new(sess: &'a Session, output: &Path) -> Self {
         ArArchiveBuilder {
             sess,
             dst: output.to_path_buf(),
@@ -56,24 +38,11 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
             // FIXME fix builtin ranlib on macOS
             no_builtin_ranlib: sess.target.is_like_osx,
 
-            src_archives,
-            entries,
+            src_archives: vec![],
+            entries: vec![],
         }
     }
 
-    fn src_files(&mut self) -> Vec<String> {
-        self.entries.iter().map(|(name, _)| String::from_utf8(name.clone()).unwrap()).collect()
-    }
-
-    fn remove_file(&mut self, name: &str) {
-        let index = self
-            .entries
-            .iter()
-            .position(|(entry_name, _)| entry_name == name.as_bytes())
-            .expect("Tried to remove file not existing in src archive");
-        self.entries.remove(index);
-    }
-
     fn add_file(&mut self, file: &Path) {
         self.entries.push((
             file.file_name().unwrap().to_str().unwrap().to_string().into_bytes(),
@@ -105,7 +74,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
         Ok(())
     }
 
-    fn build(mut self) {
+    fn build(mut self) -> bool {
         enum BuilderKind {
             Bsd(ar::Builder<File>),
             Gnu(ar::GnuBuilder<File>),
@@ -204,6 +173,8 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
             )
         };
 
+        let any_members = !entries.is_empty();
+
         // Add all files
         for (entry_name, data) in entries.into_iter() {
             let header = ar::Header::new(entry_name, data.len() as u64);
@@ -229,6 +200,8 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
                 self.sess.fatal(&format!("Ranlib exited with code {:?}", status.code()));
             }
         }
+
+        any_members
     }
 
     fn inject_dll_import_lib(
diff --git a/compiler/rustc_codegen_gcc/src/archive.rs b/compiler/rustc_codegen_gcc/src/archive.rs
index fac532f3e9c..411ec27139e 100644
--- a/compiler/rustc_codegen_gcc/src/archive.rs
+++ b/compiler/rustc_codegen_gcc/src/archive.rs
@@ -32,7 +32,7 @@ pub struct ArArchiveBuilder<'a> {
 }
 
 impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
-    fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self {
+    fn new(sess: &'a Session, output: &Path) -> Self {
         let config = ArchiveConfig {
             sess,
             dst: output.to_path_buf(),
@@ -41,48 +41,13 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
             use_gnu_style_archive: sess.target.options.archive_format == "gnu",
         };
 
-        let (src_archives, entries) = if let Some(input) = input {
-            let mut archive = ar::Archive::new(File::open(input).unwrap());
-            let mut entries = Vec::new();
-
-            let mut i = 0;
-            while let Some(entry) = archive.next_entry() {
-                let entry = entry.unwrap();
-                entries.push((
-                    String::from_utf8(entry.header().identifier().to_vec()).unwrap(),
-                    ArchiveEntry::FromArchive {
-                        archive_index: 0,
-                        entry_index: i,
-                    },
-                ));
-                i += 1;
-            }
-
-            (vec![(input.to_owned(), archive)], entries)
-        } else {
-            (vec![], Vec::new())
-        };
-
         ArArchiveBuilder {
             config,
-            src_archives,
-            entries,
+            src_archives: vec![],
+            entries: vec![],
         }
     }
 
-    fn src_files(&mut self) -> Vec<String> {
-        self.entries.iter().map(|(name, _)| name.clone()).collect()
-    }
-
-    fn remove_file(&mut self, name: &str) {
-        let index = self
-            .entries
-            .iter()
-            .position(|(entry_name, _)| entry_name == name)
-            .expect("Tried to remove file not existing in src archive");
-        self.entries.remove(index);
-    }
-
     fn add_file(&mut self, file: &Path) {
         self.entries.push((
             file.file_name().unwrap().to_str().unwrap().to_string(),
@@ -113,7 +78,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
         Ok(())
     }
 
-    fn build(mut self) {
+    fn build(mut self) -> bool {
         use std::process::Command;
 
         fn add_file_using_ar(archive: &Path, file: &Path) {
@@ -146,6 +111,8 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
             BuilderKind::Bsd(ar::Builder::new(File::create(&self.config.dst).unwrap()))
         };
 
+        let any_members = !self.entries.is_empty();
+
         // Add all files
         for (entry_name, entry) in self.entries.into_iter() {
             match entry {
@@ -206,6 +173,8 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
         if !status.success() {
             self.config.sess.fatal(&format!("Ranlib exited with code {:?}", status.code()));
         }
+
+        any_members
     }
 
     fn inject_dll_import_lib(&mut self, _lib_name: &str, _dll_imports: &[DllImport], _tmpdir: &MaybeTempDir) {
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index 8f6438e85ad..da9d8b5fb33 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -15,19 +15,12 @@ use rustc_data_structures::temp_dir::MaybeTempDir;
 use rustc_session::cstore::{DllCallingConvention, DllImport};
 use rustc_session::Session;
 
-struct ArchiveConfig<'a> {
-    pub sess: &'a Session,
-    pub dst: PathBuf,
-    pub src: Option<PathBuf>,
-}
-
 /// Helper for adding many files to an archive.
 #[must_use = "must call build() to finish building the archive"]
 pub struct LlvmArchiveBuilder<'a> {
-    config: ArchiveConfig<'a>,
-    removals: Vec<String>,
+    sess: &'a Session,
+    dst: PathBuf,
     additions: Vec<Addition>,
-    src_archive: Option<Option<ArchiveRO>>,
 }
 
 enum Addition {
@@ -50,10 +43,6 @@ fn is_relevant_child(c: &Child<'_>) -> bool {
     }
 }
 
-fn archive_config<'a>(sess: &'a Session, output: &Path, input: Option<&Path>) -> ArchiveConfig<'a> {
-    ArchiveConfig { sess, dst: output.to_path_buf(), src: input.map(|p| p.to_path_buf()) }
-}
-
 /// Map machine type strings to values of LLVM's MachineTypes enum.
 fn llvm_machine_type(cpu: &str) -> LLVMMachineType {
     match cpu {
@@ -68,37 +57,8 @@ fn llvm_machine_type(cpu: &str) -> LLVMMachineType {
 impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
     /// Creates a new static archive, ready for modifying the archive specified
     /// by `config`.
-    fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> LlvmArchiveBuilder<'a> {
-        let config = archive_config(sess, output, input);
-        LlvmArchiveBuilder {
-            config,
-            removals: Vec::new(),
-            additions: Vec::new(),
-            src_archive: None,
-        }
-    }
-
-    /// Removes a file from this archive
-    fn remove_file(&mut self, file: &str) {
-        self.removals.push(file.to_string());
-    }
-
-    /// Lists all files in an archive
-    fn src_files(&mut self) -> Vec<String> {
-        if self.src_archive().is_none() {
-            return Vec::new();
-        }
-
-        let archive = self.src_archive.as_ref().unwrap().as_ref().unwrap();
-
-        archive
-            .iter()
-            .filter_map(|child| child.ok())
-            .filter(is_relevant_child)
-            .filter_map(|child| child.name())
-            .filter(|name| !self.removals.iter().any(|x| x == name))
-            .map(|name| name.to_owned())
-            .collect()
+    fn new(sess: &'a Session, output: &Path) -> LlvmArchiveBuilder<'a> {
+        LlvmArchiveBuilder { sess, dst: output.to_path_buf(), additions: Vec::new() }
     }
 
     fn add_archive<F>(&mut self, archive: &Path, skip: F) -> io::Result<()>
@@ -129,13 +89,10 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
 
     /// Combine the provided files, rlibs, and native libraries into a single
     /// `Archive`.
-    fn build(mut self) {
-        let kind = self.llvm_archive_kind().unwrap_or_else(|kind| {
-            self.config.sess.fatal(&format!("Don't know how to build archive of type: {}", kind))
-        });
-
-        if let Err(e) = self.build_with_llvm(kind) {
-            self.config.sess.fatal(&format!("failed to build archive: {}", e));
+    fn build(mut self) -> bool {
+        match self.build_with_llvm() {
+            Ok(any_members) => any_members,
+            Err(e) => self.sess.fatal(&format!("failed to build archive: {}", e)),
         }
     }
 
@@ -151,7 +108,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
             output_path.with_extension("lib")
         };
 
-        let target = &self.config.sess.target;
+        let target = &self.sess.target;
         let mingw_gnu_toolchain = target.vendor == "pc"
             && target.os == "windows"
             && target.env == "gnu"
@@ -160,7 +117,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
         let import_name_and_ordinal_vector: Vec<(String, Option<u16>)> = dll_imports
             .iter()
             .map(|import: &DllImport| {
-                if self.config.sess.target.arch == "x86" {
+                if self.sess.target.arch == "x86" {
                     (
                         LlvmArchiveBuilder::i686_decorated_name(import, mingw_gnu_toolchain),
                         import.ordinal,
@@ -197,11 +154,11 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
             match std::fs::write(&def_file_path, def_file_content) {
                 Ok(_) => {}
                 Err(e) => {
-                    self.config.sess.fatal(&format!("Error writing .DEF file: {}", e));
+                    self.sess.fatal(&format!("Error writing .DEF file: {}", e));
                 }
             };
 
-            let dlltool = find_binutils_dlltool(self.config.sess);
+            let dlltool = find_binutils_dlltool(self.sess);
             let result = std::process::Command::new(dlltool)
                 .args([
                     "-d",
@@ -215,9 +172,9 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
 
             match result {
                 Err(e) => {
-                    self.config.sess.fatal(&format!("Error calling dlltool: {}", e));
+                    self.sess.fatal(&format!("Error calling dlltool: {}", e));
                 }
-                Ok(output) if !output.status.success() => self.config.sess.fatal(&format!(
+                Ok(output) if !output.status.success() => self.sess.fatal(&format!(
                     "Dlltool could not create import library: {}\n{}",
                     String::from_utf8_lossy(&output.stdout),
                     String::from_utf8_lossy(&output.stderr)
@@ -263,13 +220,13 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
                     output_path_z.as_ptr(),
                     ffi_exports.as_ptr(),
                     ffi_exports.len(),
-                    llvm_machine_type(&self.config.sess.target.arch) as u16,
-                    !self.config.sess.target.is_like_msvc,
+                    llvm_machine_type(&self.sess.target.arch) as u16,
+                    !self.sess.target.is_like_msvc,
                 )
             };
 
             if result == crate::llvm::LLVMRustResult::Failure {
-                self.config.sess.fatal(&format!(
+                self.sess.fatal(&format!(
                     "Error creating import library for {}: {}",
                     lib_name,
                     llvm::last_error().unwrap_or("unknown LLVM error".to_string())
@@ -278,7 +235,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
         };
 
         self.add_archive(&output_path, |_| false).unwrap_or_else(|e| {
-            self.config.sess.fatal(&format!(
+            self.sess.fatal(&format!(
                 "failed to add native library {}: {}",
                 output_path.display(),
                 e
@@ -288,46 +245,19 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
 }
 
 impl<'a> LlvmArchiveBuilder<'a> {
-    fn src_archive(&mut self) -> Option<&ArchiveRO> {
-        if let Some(ref a) = self.src_archive {
-            return a.as_ref();
-        }
-        let src = self.config.src.as_ref()?;
-        self.src_archive = Some(ArchiveRO::open(src).ok());
-        self.src_archive.as_ref().unwrap().as_ref()
-    }
-
-    fn llvm_archive_kind(&self) -> Result<ArchiveKind, &str> {
-        let kind = &*self.config.sess.target.archive_format;
-        kind.parse().map_err(|_| kind)
-    }
+    fn build_with_llvm(&mut self) -> io::Result<bool> {
+        let kind = &*self.sess.target.archive_format;
+        let kind = kind.parse::<ArchiveKind>().map_err(|_| kind).unwrap_or_else(|kind| {
+            self.sess.fatal(&format!("Don't know how to build archive of type: {}", kind))
+        });
 
-    fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> {
-        let removals = mem::take(&mut self.removals);
         let mut additions = mem::take(&mut self.additions);
         let mut strings = Vec::new();
         let mut members = Vec::new();
 
-        let dst = CString::new(self.config.dst.to_str().unwrap())?;
+        let dst = CString::new(self.dst.to_str().unwrap())?;
 
         unsafe {
-            if let Some(archive) = self.src_archive() {
-                for child in archive.iter() {
-                    let child = child.map_err(string_to_io_error)?;
-                    let Some(child_name) = child.name() else { continue };
-                    if removals.iter().any(|r| r == child_name) {
-                        continue;
-                    }
-
-                    let name = CString::new(child_name)?;
-                    members.push(llvm::LLVMRustArchiveMemberNew(
-                        ptr::null(),
-                        name.as_ptr(),
-                        Some(child.raw),
-                    ));
-                    strings.push(name);
-                }
-            }
             for addition in &mut additions {
                 match addition {
                     Addition::File { path, name_in_archive } => {
@@ -389,7 +319,7 @@ impl<'a> LlvmArchiveBuilder<'a> {
                 };
                 Err(io::Error::new(io::ErrorKind::Other, msg))
             } else {
-                Ok(())
+                Ok(!members.is_empty())
             };
             for member in members {
                 llvm::LLVMRustArchiveMemberFree(member);
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index a2f74b94214..553486ae8ec 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -42,17 +42,15 @@ pub(super) fn find_library(
 }
 
 pub trait ArchiveBuilder<'a> {
-    fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self;
+    fn new(sess: &'a Session, output: &Path) -> Self;
 
     fn add_file(&mut self, path: &Path);
-    fn remove_file(&mut self, name: &str);
-    fn src_files(&mut self) -> Vec<String>;
 
     fn add_archive<F>(&mut self, archive: &Path, skip: F) -> io::Result<()>
     where
         F: FnMut(&str) -> bool + 'static;
 
-    fn build(self);
+    fn build(self) -> bool;
 
     fn inject_dll_import_lib(
         &mut self,
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 39c7a408fb5..edf49b8c80e 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -270,7 +270,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
 
     let lib_search_paths = archive_search_paths(sess);
 
-    let mut ab = <B as ArchiveBuilder>::new(sess, out_filename, None);
+    let mut ab = <B as ArchiveBuilder>::new(sess, out_filename);
 
     let trailing_metadata = match flavor {
         RlibFlavor::Normal => {
@@ -2466,17 +2466,19 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
         let name = &name[3..name.len() - 5]; // chop off lib/.rlib
 
         sess.prof.generic_activity_with_arg("link_altering_rlib", name).run(|| {
-            let mut archive = <B as ArchiveBuilder>::new(sess, &dst, Some(cratepath));
-
-            let mut any_objects = false;
-            for f in archive.src_files() {
+            let canonical_name = name.replace('-', "_");
+            let upstream_rust_objects_already_included =
+                are_upstream_rust_objects_already_included(sess);
+            let is_builtins = sess.target.no_builtins
+                || !codegen_results.crate_info.is_no_builtins.contains(&cnum);
+
+            let mut archive = <B as ArchiveBuilder>::new(sess, &dst);
+            if let Err(e) = archive.add_archive(cratepath, move |f| {
                 if f == METADATA_FILENAME {
-                    archive.remove_file(&f);
-                    continue;
+                    return true;
                 }
 
                 let canonical = f.replace('-', "_");
-                let canonical_name = name.replace('-', "_");
 
                 let is_rust_object =
                     canonical.starts_with(&canonical_name) && looks_like_rust_object_file(&f);
@@ -2490,23 +2492,20 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
                 // file, then we don't need the object file as it's part of the
                 // LTO module. Note that `#![no_builtins]` is excluded from LTO,
                 // though, so we let that object file slide.
-                let skip_because_lto = are_upstream_rust_objects_already_included(sess)
-                    && is_rust_object
-                    && (sess.target.no_builtins
-                        || !codegen_results.crate_info.is_no_builtins.contains(&cnum));
+                let skip_because_lto =
+                    upstream_rust_objects_already_included && is_rust_object && is_builtins;
 
                 if skip_because_cfg_say_so || skip_because_lto {
-                    archive.remove_file(&f);
-                } else {
-                    any_objects = true;
+                    return true;
                 }
-            }
 
-            if !any_objects {
-                return;
+                false
+            }) {
+                sess.fatal(&format!("failed to build archive from rlib: {}", e));
+            }
+            if archive.build() {
+                link_upstream(&dst);
             }
-            archive.build();
-            link_upstream(&dst);
         });
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index ee097b5f051..8ac5f094cf6 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -1120,8 +1120,6 @@ impl<'a> Linker for EmLinker<'a> {
             OptLevel::Size => "-Os",
             OptLevel::SizeMin => "-Oz",
         });
-        // Unusable until https://github.com/rust-lang/rust/issues/38454 is resolved
-        self.cmd.args(&["--memory-init-file", "0"]);
     }
 
     fn pgo_gen(&mut self) {
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 08be4c0a7b6..2e655ae94cc 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -118,22 +118,20 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
     }
 
     pub fn deref<Cx: LayoutTypeMethods<'tcx>>(self, cx: &Cx) -> PlaceRef<'tcx, V> {
+        if self.layout.ty.is_box() {
+            bug!("dereferencing {:?} in codegen", self.layout.ty);
+        }
+
         let projected_ty = self
             .layout
             .ty
             .builtin_deref(true)
             .unwrap_or_else(|| bug!("deref of non-pointer {:?}", self))
             .ty;
+
         let (llptr, llextra) = match self.val {
             OperandValue::Immediate(llptr) => (llptr, None),
-            OperandValue::Pair(llptr, llextra) => {
-                // if the box's allocator isn't a ZST, then "llextra" is actually the allocator
-                if self.layout.ty.is_box() && !self.layout.field(cx, 1).is_zst() {
-                    (llptr, None)
-                } else {
-                    (llptr, Some(llextra))
-                }
-            }
+            OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)),
             OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self),
         };
         let layout = cx.layout_of(projected_ty);
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 3185b952ab8..5b88635982f 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -446,16 +446,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref },
                     );
 
-                    // a box with a non-zst allocator should not be directly dereferenced
-                    if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() {
-                        // Extract `Box<T>` -> `Unique<T>` -> `NonNull<T>` -> `*const T`
-                        let ptr =
-                            cg_base.extract_field(bx, 0).extract_field(bx, 0).extract_field(bx, 0);
-
-                        ptr.deref(bx.cx())
-                    } else {
-                        cg_base.deref(bx.cx())
-                    }
+                    cg_base.deref(bx.cx())
                 } else {
                     bug!("using operand local {:?} as place", place_ref);
                 }
@@ -463,18 +454,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         };
         for elem in place_ref.projection[base..].iter() {
             cg_base = match *elem {
-                mir::ProjectionElem::Deref => {
-                    // a box with a non-zst allocator should not be directly dereferenced
-                    if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() {
-                        // Project `Box<T>` -> `Unique<T>` -> `NonNull<T>` -> `*const T`
-                        let ptr =
-                            cg_base.project_field(bx, 0).project_field(bx, 0).project_field(bx, 0);
-
-                        bx.load_operand(ptr).deref(bx.cx())
-                    } else {
-                        bx.load_operand(cg_base).deref(bx.cx())
-                    }
-                }
+                mir::ProjectionElem::Deref => bx.load_operand(cg_base).deref(bx.cx()),
                 mir::ProjectionElem::Field(ref field, _) => {
                     cg_base.project_field(bx, field.index())
                 }
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index d6f62062d1f..f1674d04f8d 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -17,13 +17,14 @@ pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
 
 pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
     let parent_id = tcx.local_parent(def_id);
-    tcx.def_kind(parent_id) == DefKind::Impl
-        && tcx.impl_constness(parent_id) == hir::Constness::Const
+    tcx.def_kind(parent_id) == DefKind::Impl && tcx.constness(parent_id) == hir::Constness::Const
 }
 
-/// Checks whether the function has a `const` modifier or, in case it is an intrinsic, whether
-/// said intrinsic has a `rustc_const_{un,}stable` attribute.
-fn impl_constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
+/// Checks whether an item is considered to be `const`. If it is a constructor, it is const. If
+/// it is a trait impl/function, return if it has a `const` modifier. If it is an intrinsic,
+/// report whether said intrinsic has a `rustc_const_{un,}stable` attribute. Otherwise, return
+/// `Constness::NotConst`.
+fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
     let def_id = def_id.expect_local();
     let node = tcx.hir().get_by_def_id(def_id);
 
@@ -77,5 +78,5 @@ fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
 }
 
 pub fn provide(providers: &mut Providers) {
-    *providers = Providers { impl_constness, is_promotable_const_fn, ..*providers };
+    *providers = Providers { constness, is_promotable_const_fn, ..*providers };
 }
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 5377535b9fa..c18ac84171d 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -334,12 +334,14 @@ pub trait Machine<'mir, 'tcx>: Sized {
     /// allocation (because a copy had to be done to add tags or metadata), machine memory will
     /// cache the result. (This relies on `AllocMap::get_or` being able to add the
     /// owned allocation to the map even when the map is shared.)
+    ///
+    /// This must only fail if `alloc` contains relocations.
     fn init_allocation_extra<'b>(
         ecx: &InterpCx<'mir, 'tcx, Self>,
         id: AllocId,
         alloc: Cow<'b, Allocation>,
         kind: Option<MemoryKind<Self::MemoryKind>>,
-    ) -> Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>;
+    ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>>;
 
     /// Hook for performing extra checks on a memory read access.
     ///
@@ -485,9 +487,9 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
         _id: AllocId,
         alloc: Cow<'b, Allocation>,
         _kind: Option<MemoryKind<Self::MemoryKind>>,
-    ) -> Cow<'b, Allocation<Self::PointerTag>> {
+    ) -> InterpResult<$tcx, Cow<'b, Allocation<Self::PointerTag>>> {
         // We do not use a tag so we can just cheaply forward the allocation
-        alloc
+        Ok(alloc)
     }
 
     fn extern_static_base_pointer(
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index f725a0591c5..d46f2f38d3a 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -199,7 +199,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         kind: MemoryKind<M::MemoryKind>,
     ) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
         let alloc = Allocation::uninit(size, align, M::PANIC_ON_ALLOC_FAIL)?;
-        Ok(self.allocate_raw_ptr(alloc, kind))
+        // We can `unwrap` since `alloc` contains no pointers.
+        Ok(self.allocate_raw_ptr(alloc, kind).unwrap())
     }
 
     pub fn allocate_bytes_ptr(
@@ -210,23 +211,25 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         mutability: Mutability,
     ) -> Pointer<M::PointerTag> {
         let alloc = Allocation::from_bytes(bytes, align, mutability);
-        self.allocate_raw_ptr(alloc, kind)
+        // We can `unwrap` since `alloc` contains no pointers.
+        self.allocate_raw_ptr(alloc, kind).unwrap()
     }
 
+    /// This can fail only of `alloc` contains relocations.
     pub fn allocate_raw_ptr(
         &mut self,
         alloc: Allocation,
         kind: MemoryKind<M::MemoryKind>,
-    ) -> Pointer<M::PointerTag> {
+    ) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
         let id = self.tcx.reserve_alloc_id();
         debug_assert_ne!(
             Some(kind),
             M::GLOBAL_KIND.map(MemoryKind::Machine),
             "dynamically allocating global memory"
         );
-        let alloc = M::init_allocation_extra(self, id, Cow::Owned(alloc), Some(kind));
+        let alloc = M::init_allocation_extra(self, id, Cow::Owned(alloc), Some(kind))?;
         self.memory.alloc_map.insert(id, (kind, alloc.into_owned()));
-        M::tag_alloc_base_pointer(self, Pointer::from(id))
+        Ok(M::tag_alloc_base_pointer(self, Pointer::from(id)))
     }
 
     pub fn reallocate_ptr(
@@ -510,13 +513,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         };
         M::before_access_global(*self.tcx, &self.machine, id, alloc, def_id, is_write)?;
         // We got tcx memory. Let the machine initialize its "extra" stuff.
-        let alloc = M::init_allocation_extra(
+        M::init_allocation_extra(
             self,
             id, // always use the ID we got as input, not the "hidden" one.
             Cow::Borrowed(alloc.inner()),
             M::GLOBAL_KIND.map(MemoryKind::Machine),
-        );
-        Ok(alloc)
+        )
     }
 
     /// Gives raw access to the `Allocation`, without bounds or alignment checks.
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index ae7180b674f..3dbcba72baf 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -313,6 +313,11 @@ where
     ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
         let val = self.read_immediate(src)?;
         trace!("deref to {} on {:?}", val.layout.ty, *val);
+
+        if val.layout.ty.is_box() {
+            bug!("dereferencing {:?}", val.layout.ty);
+        }
+
         let mplace = self.ref_to_mplace(&val)?;
         self.check_mplace_access(mplace, CheckInAllocMsg::DerefTest)?;
         Ok(mplace)
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 b8a14e37a09..069fbed36ee 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -753,7 +753,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                                 callee = did;
                             }
 
-                            if let hir::Constness::NotConst = tcx.impl_constness(data.impl_def_id) {
+                            if let hir::Constness::NotConst = tcx.constness(data.impl_def_id) {
                                 self.check_op(ops::FnCallNonConst {
                                     caller,
                                     callee,
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index 4e71baa77b0..0c587220cb7 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -10,7 +10,8 @@ use rustc_middle::mir;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
 use rustc_middle::ty::{
-    suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, TraitPredicate, Ty,
+    suggest_constraining_type_param, Adt, Closure, DefIdTree, FnDef, FnPtr, Param, TraitPredicate,
+    Ty,
 };
 use rustc_middle::ty::{Binder, BoundConstness, ImplPolarity, TraitRef};
 use rustc_session::parse::feature_err;
@@ -300,6 +301,15 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
                 diag_trait(&mut err, self_ty, tcx.lang_items().deref_trait().unwrap());
                 err
             }
+            _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentV1Methods) => {
+                struct_span_err!(
+                    ccx.tcx.sess,
+                    span,
+                    E0015,
+                    "cannot call non-const formatting macro in {}s",
+                    ccx.const_kind(),
+                )
+            }
             _ => struct_span_err!(
                 ccx.tcx.sess,
                 span,
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 3f54d864297..66d66ea9510 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -240,65 +240,79 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
         context: PlaceContext,
         location: Location,
     ) {
-        if let ProjectionElem::Index(index) = elem {
-            let index_ty = self.body.local_decls[index].ty;
-            if index_ty != self.tcx.types.usize {
-                self.fail(location, format!("bad index ({:?} != usize)", index_ty))
+        match elem {
+            ProjectionElem::Index(index) => {
+                let index_ty = self.body.local_decls[index].ty;
+                if index_ty != self.tcx.types.usize {
+                    self.fail(location, format!("bad index ({:?} != usize)", index_ty))
+                }
             }
-        }
-        if let ProjectionElem::Field(f, ty) = elem {
-            let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) };
-            let parent_ty = parent.ty(&self.body.local_decls, self.tcx);
-            let fail_out_of_bounds = |this: &Self, location| {
-                this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty));
-            };
-            let check_equal = |this: &Self, location, f_ty| {
-                if !this.mir_assign_valid_types(ty, f_ty) {
-                    this.fail(
+            ProjectionElem::Deref if self.mir_phase >= MirPhase::GeneratorsLowered => {
+                let base_ty = Place::ty_from(local, proj_base, &self.body.local_decls, self.tcx).ty;
+
+                if base_ty.is_box() {
+                    self.fail(
+                        location,
+                        format!("{:?} dereferenced after ElaborateBoxDerefs", base_ty),
+                    )
+                }
+            }
+            ProjectionElem::Field(f, ty) => {
+                let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) };
+                let parent_ty = parent.ty(&self.body.local_decls, self.tcx);
+                let fail_out_of_bounds = |this: &Self, location| {
+                    this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty));
+                };
+                let check_equal = |this: &Self, location, f_ty| {
+                    if !this.mir_assign_valid_types(ty, f_ty) {
+                        this.fail(
                         location,
                         format!(
                             "Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is {:?}",
                             parent, f, ty, f_ty
                         )
                     )
-                }
-            };
-            match parent_ty.ty.kind() {
-                ty::Tuple(fields) => {
-                    let Some(f_ty) = fields.get(f.as_usize()) else {
-                        fail_out_of_bounds(self, location);
-                        return;
-                    };
-                    check_equal(self, location, *f_ty);
-                }
-                ty::Adt(adt_def, substs) => {
-                    let var = parent_ty.variant_index.unwrap_or(VariantIdx::from_u32(0));
-                    let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else {
-                        fail_out_of_bounds(self, location);
-                        return;
-                    };
-                    check_equal(self, location, field.ty(self.tcx, substs));
-                }
-                ty::Closure(_, substs) => {
-                    let substs = substs.as_closure();
-                    let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else {
-                        fail_out_of_bounds(self, location);
-                        return;
-                    };
-                    check_equal(self, location, f_ty);
-                }
-                ty::Generator(_, substs, _) => {
-                    let substs = substs.as_generator();
-                    let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else {
-                        fail_out_of_bounds(self, location);
-                        return;
-                    };
-                    check_equal(self, location, f_ty);
-                }
-                _ => {
-                    self.fail(location, format!("{:?} does not have fields", parent_ty.ty));
+                    }
+                };
+
+                match parent_ty.ty.kind() {
+                    ty::Tuple(fields) => {
+                        let Some(f_ty) = fields.get(f.as_usize()) else {
+                            fail_out_of_bounds(self, location);
+                            return;
+                        };
+                        check_equal(self, location, *f_ty);
+                    }
+                    ty::Adt(adt_def, substs) => {
+                        let var = parent_ty.variant_index.unwrap_or(VariantIdx::from_u32(0));
+                        let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else {
+                            fail_out_of_bounds(self, location);
+                            return;
+                        };
+                        check_equal(self, location, field.ty(self.tcx, substs));
+                    }
+                    ty::Closure(_, substs) => {
+                        let substs = substs.as_closure();
+                        let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else {
+                            fail_out_of_bounds(self, location);
+                            return;
+                        };
+                        check_equal(self, location, f_ty);
+                    }
+                    ty::Generator(_, substs, _) => {
+                        let substs = substs.as_generator();
+                        let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else {
+                            fail_out_of_bounds(self, location);
+                            return;
+                        };
+                        check_equal(self, location, f_ty);
+                    }
+                    _ => {
+                        self.fail(location, format!("{:?} does not have fields", parent_ty.ty));
+                    }
                 }
             }
+            _ => {}
         }
         self.super_projection_elem(local, proj_base, elem, context, location);
     }
diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
index 74f432a7967..07a96dd7dbb 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
@@ -42,7 +42,7 @@
 //!   now considered to be in error.
 //!
 //! When the call to `process_obligations` completes, you get back an `Outcome`,
-//! which includes three bits of information:
+//! which includes two bits of information:
 //!
 //! - `completed`: a list of obligations where processing was fully
 //!   completed without error (meaning that all transitive subobligations
@@ -53,13 +53,10 @@
 //!   all the obligations in `C` have been found completed.
 //! - `errors`: a list of errors that occurred and associated backtraces
 //!   at the time of error, which can be used to give context to the user.
-//! - `stalled`: if true, then none of the existing obligations were
-//!   *shallowly successful* (that is, no callback returned `Changed(_)`).
-//!   This implies that all obligations were either errors or returned an
-//!   ambiguous result, which means that any further calls to
-//!   `process_obligations` would simply yield back further ambiguous
-//!   results. This is used by the `FulfillmentContext` to decide when it
-//!   has reached a steady state.
+//!
+//! Upon completion, none of the existing obligations were *shallowly
+//! successful* (that is, no callback returned `Changed(_)`). This implies that
+//! all obligations were either errors or returned an ambiguous result.
 //!
 //! ### Implementation details
 //!
@@ -99,6 +96,8 @@ pub trait ObligationProcessor {
     type Obligation: ForestObligation;
     type Error: Debug;
 
+    fn needs_process_obligation(&self, obligation: &Self::Obligation) -> bool;
+
     fn process_obligation(
         &mut self,
         obligation: &mut Self::Obligation,
@@ -146,7 +145,7 @@ pub struct ObligationForest<O: ForestObligation> {
 
     /// A cache of the nodes in `nodes`, indexed by predicate. Unfortunately,
     /// its contents are not guaranteed to match those of `nodes`. See the
-    /// comments in [`Self::process_obligation` for details.
+    /// comments in `Self::process_obligation` for details.
     active_cache: FxHashMap<O::CacheKey, usize>,
 
     /// A vector reused in [Self::compress()] and [Self::find_cycles_from_node()],
@@ -260,8 +259,6 @@ pub trait OutcomeTrait {
     type Obligation;
 
     fn new() -> Self;
-    fn mark_not_stalled(&mut self);
-    fn is_stalled(&self) -> bool;
     fn record_completed(&mut self, outcome: &Self::Obligation);
     fn record_error(&mut self, error: Self::Error);
 }
@@ -270,14 +267,6 @@ pub trait OutcomeTrait {
 pub struct Outcome<O, E> {
     /// Backtrace of obligations that were found to be in error.
     pub errors: Vec<Error<O, E>>,
-
-    /// If true, then we saw no successful obligations, which means
-    /// there is no point in further iteration. This is based on the
-    /// assumption that when trait matching returns `Error` or
-    /// `Unchanged`, those results do not affect environmental
-    /// inference state. (Note that if we invoke `process_obligations`
-    /// with no pending obligations, stalled will be true.)
-    pub stalled: bool,
 }
 
 impl<O, E> OutcomeTrait for Outcome<O, E> {
@@ -285,15 +274,7 @@ impl<O, E> OutcomeTrait for Outcome<O, E> {
     type Obligation = O;
 
     fn new() -> Self {
-        Self { stalled: true, errors: vec![] }
-    }
-
-    fn mark_not_stalled(&mut self) {
-        self.stalled = false;
-    }
-
-    fn is_stalled(&self) -> bool {
-        self.stalled
+        Self { errors: vec![] }
     }
 
     fn record_completed(&mut self, _outcome: &Self::Obligation) {
@@ -415,10 +396,7 @@ impl<O: ForestObligation> ObligationForest<O> {
             .insert(node.obligation.as_cache_key());
     }
 
-    /// Performs a pass through the obligation list. This must
-    /// be called in a loop until `outcome.stalled` is false.
-    ///
-    /// This _cannot_ be unrolled (presently, at least).
+    /// Performs a fixpoint computation over the obligation list.
     #[inline(never)]
     pub fn process_obligations<P, OUT>(&mut self, processor: &mut P) -> OUT
     where
@@ -427,55 +405,69 @@ impl<O: ForestObligation> ObligationForest<O> {
     {
         let mut outcome = OUT::new();
 
-        // Note that the loop body can append new nodes, and those new nodes
-        // will then be processed by subsequent iterations of the loop.
-        //
-        // We can't use an iterator for the loop because `self.nodes` is
-        // appended to and the borrow checker would complain. We also can't use
-        // `for index in 0..self.nodes.len() { ... }` because the range would
-        // be computed with the initial length, and we would miss the appended
-        // nodes. Therefore we use a `while` loop.
-        let mut index = 0;
-        while let Some(node) = self.nodes.get_mut(index) {
-            // `processor.process_obligation` can modify the predicate within
-            // `node.obligation`, and that predicate is the key used for
-            // `self.active_cache`. This means that `self.active_cache` can get
-            // out of sync with `nodes`. It's not very common, but it does
-            // happen, and code in `compress` has to allow for it.
-            if node.state.get() != NodeState::Pending {
-                index += 1;
-                continue;
-            }
-
-            match processor.process_obligation(&mut node.obligation) {
-                ProcessResult::Unchanged => {
-                    // No change in state.
+        // Fixpoint computation: we repeat until the inner loop stalls.
+        loop {
+            let mut has_changed = false;
+
+            // Note that the loop body can append new nodes, and those new nodes
+            // will then be processed by subsequent iterations of the loop.
+            //
+            // We can't use an iterator for the loop because `self.nodes` is
+            // appended to and the borrow checker would complain. We also can't use
+            // `for index in 0..self.nodes.len() { ... }` because the range would
+            // be computed with the initial length, and we would miss the appended
+            // nodes. Therefore we use a `while` loop.
+            let mut index = 0;
+            while let Some(node) = self.nodes.get_mut(index) {
+                if node.state.get() != NodeState::Pending
+                    || !processor.needs_process_obligation(&node.obligation)
+                {
+                    index += 1;
+                    continue;
                 }
-                ProcessResult::Changed(children) => {
-                    // We are not (yet) stalled.
-                    outcome.mark_not_stalled();
-                    node.state.set(NodeState::Success);
-
-                    for child in children {
-                        let st = self.register_obligation_at(child, Some(index));
-                        if let Err(()) = st {
-                            // Error already reported - propagate it
-                            // to our node.
-                            self.error_at(index);
+
+                // `processor.process_obligation` can modify the predicate within
+                // `node.obligation`, and that predicate is the key used for
+                // `self.active_cache`. This means that `self.active_cache` can get
+                // out of sync with `nodes`. It's not very common, but it does
+                // happen, and code in `compress` has to allow for it.
+
+                match processor.process_obligation(&mut node.obligation) {
+                    ProcessResult::Unchanged => {
+                        // No change in state.
+                    }
+                    ProcessResult::Changed(children) => {
+                        // We are not (yet) stalled.
+                        has_changed = true;
+                        node.state.set(NodeState::Success);
+
+                        for child in children {
+                            let st = self.register_obligation_at(child, Some(index));
+                            if let Err(()) = st {
+                                // Error already reported - propagate it
+                                // to our node.
+                                self.error_at(index);
+                            }
                         }
                     }
+                    ProcessResult::Error(err) => {
+                        has_changed = true;
+                        outcome.record_error(Error { error: err, backtrace: self.error_at(index) });
+                    }
                 }
-                ProcessResult::Error(err) => {
-                    outcome.mark_not_stalled();
-                    outcome.record_error(Error { error: err, backtrace: self.error_at(index) });
-                }
+                index += 1;
+            }
+
+            // If unchanged, then we saw no successful obligations, which means
+            // there is no point in further iteration. This is based on the
+            // assumption that when trait matching returns `Error` or
+            // `Unchanged`, those results do not affect environmental inference
+            // state. (Note that this will occur if we invoke
+            // `process_obligations` with no pending obligations.)
+            if !has_changed {
+                break;
             }
-            index += 1;
-        }
 
-        // There's no need to perform marking, cycle processing and compression when nothing
-        // changed.
-        if !outcome.is_stalled() {
             self.mark_successes();
             self.process_cycles(processor);
             self.compress(|obl| outcome.record_completed(obl));
@@ -634,17 +626,14 @@ impl<O: ForestObligation> ObligationForest<O> {
                     }
                 }
                 NodeState::Done => {
-                    // This lookup can fail because the contents of
+                    // The removal lookup might fail because the contents of
                     // `self.active_cache` are not guaranteed to match those of
                     // `self.nodes`. See the comment in `process_obligation`
                     // for more details.
-                    if let Some((predicate, _)) =
-                        self.active_cache.remove_entry(&node.obligation.as_cache_key())
-                    {
-                        self.done_cache.insert(predicate);
-                    } else {
-                        self.done_cache.insert(node.obligation.as_cache_key().clone());
-                    }
+                    let cache_key = node.obligation.as_cache_key();
+                    self.active_cache.remove(&cache_key);
+                    self.done_cache.insert(cache_key);
+
                     // Extract the success stories.
                     outcome_cb(&node.obligation);
                     node_rewrites[index] = orig_nodes_len;
diff --git a/compiler/rustc_data_structures/src/obligation_forest/tests.rs b/compiler/rustc_data_structures/src/obligation_forest/tests.rs
index 371c62c063f..e2991aae174 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/tests.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/tests.rs
@@ -20,7 +20,6 @@ struct ClosureObligationProcessor<OF, BF, O, E> {
 struct TestOutcome<O, E> {
     pub completed: Vec<O>,
     pub errors: Vec<Error<O, E>>,
-    pub stalled: bool,
 }
 
 impl<O, E> OutcomeTrait for TestOutcome<O, E>
@@ -31,15 +30,7 @@ where
     type Obligation = O;
 
     fn new() -> Self {
-        Self { errors: vec![], stalled: false, completed: vec![] }
-    }
-
-    fn mark_not_stalled(&mut self) {
-        self.stalled = false;
-    }
-
-    fn is_stalled(&self) -> bool {
-        self.stalled
+        Self { errors: vec![], completed: vec![] }
     }
 
     fn record_completed(&mut self, outcome: &Self::Obligation) {
@@ -74,6 +65,10 @@ where
     type Obligation = O;
     type Error = E;
 
+    fn needs_process_obligation(&self, _obligation: &Self::Obligation) -> bool {
+        true
+    }
+
     fn process_obligation(
         &mut self,
         obligation: &mut Self::Obligation,
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index fefcaa898c1..ba7cc4908b8 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -1,6 +1,5 @@
 #![feature(let_chains)]
 #![feature(once_cell)]
-#![feature(path_try_exists)]
 #![feature(rustc_attrs)]
 #![feature(type_alias_impl_trait)]
 
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 093896c339d..1e4193a5a16 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -329,6 +329,7 @@ impl Ident {
         sess.symbol_gallery.insert(sym, span);
         Ident { sym, is_raw, span }
     }
+
     fn dollar_crate(span: Span) -> Ident {
         // `$crate` is accepted as an ident only if it comes from the compiler.
         Ident { sym: kw::DollarCrate, is_raw: false, span }
@@ -403,6 +404,7 @@ impl server::TokenStream for Rustc<'_, '_> {
     fn is_empty(&mut self, stream: &Self::TokenStream) -> bool {
         stream.is_empty()
     }
+
     fn from_str(&mut self, src: &str) -> Self::TokenStream {
         parse_stream_from_source_str(
             FileName::proc_macro_source_code(src),
@@ -411,9 +413,11 @@ impl server::TokenStream for Rustc<'_, '_> {
             Some(self.call_site),
         )
     }
+
     fn to_string(&mut self, stream: &Self::TokenStream) -> String {
         pprust::tts_to_string(stream)
     }
+
     fn expand_expr(&mut self, stream: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
         // Parse the expression from our tokenstream.
         let expr: PResult<'_, _> = try {
@@ -464,12 +468,14 @@ impl server::TokenStream for Rustc<'_, '_> {
             _ => Err(()),
         }
     }
+
     fn from_token_tree(
         &mut self,
         tree: TokenTree<Self::Group, Self::Punct, Self::Ident, Self::Literal>,
     ) -> Self::TokenStream {
         tree.to_internal()
     }
+
     fn concat_trees(
         &mut self,
         base: Option<Self::TokenStream>,
@@ -484,6 +490,7 @@ impl server::TokenStream for Rustc<'_, '_> {
         }
         builder.build()
     }
+
     fn concat_streams(
         &mut self,
         base: Option<Self::TokenStream>,
@@ -498,6 +505,7 @@ impl server::TokenStream for Rustc<'_, '_> {
         }
         builder.build()
     }
+
     fn into_trees(
         &mut self,
         stream: Self::TokenStream,
@@ -522,10 +530,10 @@ impl server::TokenStream for Rustc<'_, '_> {
                     // FIXME: It needs to be removed, but there are some
                     // compatibility issues (see #73345).
                     if group.flatten {
-                        cursor.append(group.stream);
-                        continue;
+                        tts.append(&mut self.into_trees(group.stream));
+                    } else {
+                        tts.push(TokenTree::Group(group));
                     }
-                    tts.push(TokenTree::Group(group));
                 }
                 Some(tt) => tts.push(tt),
                 None => return tts,
@@ -543,21 +551,27 @@ impl server::Group for Rustc<'_, '_> {
             flatten: false,
         }
     }
+
     fn delimiter(&mut self, group: &Self::Group) -> Delimiter {
         group.delimiter
     }
+
     fn stream(&mut self, group: &Self::Group) -> Self::TokenStream {
         group.stream.clone()
     }
+
     fn span(&mut self, group: &Self::Group) -> Self::Span {
         group.span.entire()
     }
+
     fn span_open(&mut self, group: &Self::Group) -> Self::Span {
         group.span.open
     }
+
     fn span_close(&mut self, group: &Self::Group) -> Self::Span {
         group.span.close
     }
+
     fn set_span(&mut self, group: &mut Self::Group, span: Self::Span) {
         group.span = DelimSpan::from_single(span);
     }
@@ -567,15 +581,19 @@ impl server::Punct for Rustc<'_, '_> {
     fn new(&mut self, ch: char, spacing: Spacing) -> Self::Punct {
         Punct::new(ch, spacing == Spacing::Joint, server::Span::call_site(self))
     }
+
     fn as_char(&mut self, punct: Self::Punct) -> char {
         punct.ch
     }
+
     fn spacing(&mut self, punct: Self::Punct) -> Spacing {
         if punct.joint { Spacing::Joint } else { Spacing::Alone }
     }
+
     fn span(&mut self, punct: Self::Punct) -> Self::Span {
         punct.span
     }
+
     fn with_span(&mut self, punct: Self::Punct, span: Self::Span) -> Self::Punct {
         Punct { span, ..punct }
     }
@@ -585,9 +603,11 @@ impl server::Ident for Rustc<'_, '_> {
     fn new(&mut self, string: &str, span: Self::Span, is_raw: bool) -> Self::Ident {
         Ident::new(self.sess(), Symbol::intern(string), is_raw, span)
     }
+
     fn span(&mut self, ident: Self::Ident) -> Self::Span {
         ident.span
     }
+
     fn with_span(&mut self, ident: Self::Ident, span: Self::Span) -> Self::Ident {
         Ident { span, ..ident }
     }
@@ -639,45 +659,57 @@ impl server::Literal for Rustc<'_, '_> {
 
         Ok(Literal { lit, span: self.call_site })
     }
+
     fn to_string(&mut self, literal: &Self::Literal) -> String {
         literal.lit.to_string()
     }
+
     fn debug_kind(&mut self, literal: &Self::Literal) -> String {
         format!("{:?}", literal.lit.kind)
     }
+
     fn symbol(&mut self, literal: &Self::Literal) -> String {
         literal.lit.symbol.to_string()
     }
+
     fn suffix(&mut self, literal: &Self::Literal) -> Option<String> {
         literal.lit.suffix.as_ref().map(Symbol::to_string)
     }
+
     fn integer(&mut self, n: &str) -> Self::Literal {
         self.lit(token::Integer, Symbol::intern(n), None)
     }
+
     fn typed_integer(&mut self, n: &str, kind: &str) -> Self::Literal {
         self.lit(token::Integer, Symbol::intern(n), Some(Symbol::intern(kind)))
     }
+
     fn float(&mut self, n: &str) -> Self::Literal {
         self.lit(token::Float, Symbol::intern(n), None)
     }
+
     fn f32(&mut self, n: &str) -> Self::Literal {
         self.lit(token::Float, Symbol::intern(n), Some(sym::f32))
     }
+
     fn f64(&mut self, n: &str) -> Self::Literal {
         self.lit(token::Float, Symbol::intern(n), Some(sym::f64))
     }
+
     fn string(&mut self, string: &str) -> Self::Literal {
         let quoted = format!("{:?}", string);
         assert!(quoted.starts_with('"') && quoted.ends_with('"'));
         let symbol = &quoted[1..quoted.len() - 1];
         self.lit(token::Str, Symbol::intern(symbol), None)
     }
+
     fn character(&mut self, ch: char) -> Self::Literal {
         let quoted = format!("{:?}", ch);
         assert!(quoted.starts_with('\'') && quoted.ends_with('\''));
         let symbol = &quoted[1..quoted.len() - 1];
         self.lit(token::Char, Symbol::intern(symbol), None)
     }
+
     fn byte_string(&mut self, bytes: &[u8]) -> Self::Literal {
         let string = bytes
             .iter()
@@ -687,12 +719,15 @@ impl server::Literal for Rustc<'_, '_> {
             .collect::<String>();
         self.lit(token::ByteStr, Symbol::intern(&string), None)
     }
+
     fn span(&mut self, literal: &Self::Literal) -> Self::Span {
         literal.span
     }
+
     fn set_span(&mut self, literal: &mut Self::Literal, span: Self::Span) {
         literal.span = span;
     }
+
     fn subspan(
         &mut self,
         literal: &Self::Literal,
@@ -735,6 +770,7 @@ impl server::SourceFile for Rustc<'_, '_> {
     fn eq(&mut self, file1: &Self::SourceFile, file2: &Self::SourceFile) -> bool {
         Lrc::ptr_eq(file1, file2)
     }
+
     fn path(&mut self, file: &Self::SourceFile) -> String {
         match file.name {
             FileName::Real(ref name) => name
@@ -746,6 +782,7 @@ impl server::SourceFile for Rustc<'_, '_> {
             _ => file.name.prefer_local().to_string(),
         }
     }
+
     fn is_real(&mut self, file: &Self::SourceFile) -> bool {
         file.is_real_file()
     }
@@ -755,6 +792,7 @@ impl server::MultiSpan for Rustc<'_, '_> {
     fn new(&mut self) -> Self::MultiSpan {
         vec![]
     }
+
     fn push(&mut self, spans: &mut Self::MultiSpan, span: Self::Span) {
         spans.push(span)
     }
@@ -766,6 +804,7 @@ impl server::Diagnostic for Rustc<'_, '_> {
         diag.set_span(MultiSpan::from_spans(spans));
         diag
     }
+
     fn sub(
         &mut self,
         diag: &mut Self::Diagnostic,
@@ -775,6 +814,7 @@ impl server::Diagnostic for Rustc<'_, '_> {
     ) {
         diag.sub(level.to_internal(), msg, MultiSpan::from_spans(spans), None);
     }
+
     fn emit(&mut self, mut diag: Self::Diagnostic) {
         self.sess().span_diagnostic.emit_diagnostic(&mut diag);
     }
@@ -788,38 +828,49 @@ impl server::Span for Rustc<'_, '_> {
             format!("{:?} bytes({}..{})", span.ctxt(), span.lo().0, span.hi().0)
         }
     }
+
     fn def_site(&mut self) -> Self::Span {
         self.def_site
     }
+
     fn call_site(&mut self) -> Self::Span {
         self.call_site
     }
+
     fn mixed_site(&mut self) -> Self::Span {
         self.mixed_site
     }
+
     fn source_file(&mut self, span: Self::Span) -> Self::SourceFile {
         self.sess().source_map().lookup_char_pos(span.lo()).file
     }
+
     fn parent(&mut self, span: Self::Span) -> Option<Self::Span> {
         span.parent_callsite()
     }
+
     fn source(&mut self, span: Self::Span) -> Self::Span {
         span.source_callsite()
     }
+
     fn start(&mut self, span: Self::Span) -> LineColumn {
         let loc = self.sess().source_map().lookup_char_pos(span.lo());
         LineColumn { line: loc.line, column: loc.col.to_usize() }
     }
+
     fn end(&mut self, span: Self::Span) -> LineColumn {
         let loc = self.sess().source_map().lookup_char_pos(span.hi());
         LineColumn { line: loc.line, column: loc.col.to_usize() }
     }
+
     fn before(&mut self, span: Self::Span) -> Self::Span {
         span.shrink_to_lo()
     }
+
     fn after(&mut self, span: Self::Span) -> Self::Span {
         span.shrink_to_hi()
     }
+
     fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
         let self_loc = self.sess().source_map().lookup_char_pos(first.lo());
         let other_loc = self.sess().source_map().lookup_char_pos(second.lo());
@@ -830,9 +881,11 @@ impl server::Span for Rustc<'_, '_> {
 
         Some(first.to(second))
     }
+
     fn resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span {
         span.with_ctxt(at.ctxt())
     }
+
     fn source_text(&mut self, span: Self::Span) -> Option<String> {
         self.sess().source_map().span_to_snippet(span).ok()
     }
@@ -863,6 +916,7 @@ impl server::Span for Rustc<'_, '_> {
     fn save_span(&mut self, span: Self::Span) -> usize {
         self.sess().save_proc_macro_span(span)
     }
+
     fn recover_proc_macro_span(&mut self, id: usize) -> Self::Span {
         let (resolver, krate, def_site) = (&*self.ecx.resolver, self.krate, self.def_site);
         *self.rebased_spans.entry(id).or_insert_with(|| {
diff --git a/compiler/rustc_expand/src/tokenstream/tests.rs b/compiler/rustc_expand/src/tokenstream/tests.rs
index 270532f8ede..e4a4db204d9 100644
--- a/compiler/rustc_expand/src/tokenstream/tests.rs
+++ b/compiler/rustc_expand/src/tokenstream/tests.rs
@@ -4,7 +4,6 @@ use rustc_ast::token;
 use rustc_ast::tokenstream::{Spacing, TokenStream, TokenStreamBuilder, TokenTree};
 use rustc_span::create_default_session_globals_then;
 use rustc_span::{BytePos, Span, Symbol};
-use smallvec::smallvec;
 
 fn string_to_ts(string: &str) -> TokenStream {
     string_to_stream(string.to_owned())
@@ -24,7 +23,10 @@ fn test_concat() {
         let test_res = string_to_ts("foo::bar::baz");
         let test_fst = string_to_ts("foo::bar");
         let test_snd = string_to_ts("::baz");
-        let eq_res = TokenStream::from_streams(smallvec![test_fst, test_snd]);
+        let mut builder = TokenStreamBuilder::new();
+        builder.push(test_fst);
+        builder.push(test_snd);
+        let eq_res = builder.build();
         assert_eq!(test_res.trees().count(), 5);
         assert_eq!(eq_res.trees().count(), 5);
         assert_eq!(test_res.eq_unspanned(&eq_res), true);
diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs
index f2eaef1e149..976874c7cee 100644
--- a/compiler/rustc_index/src/bit_set.rs
+++ b/compiler/rustc_index/src/bit_set.rs
@@ -340,6 +340,12 @@ impl<T: Idx> BitRelations<BitSet<T>> for BitSet<T> {
     }
 }
 
+impl<T: Idx> From<GrowableBitSet<T>> for BitSet<T> {
+    fn from(bit_set: GrowableBitSet<T>) -> Self {
+        bit_set.bit_set
+    }
+}
+
 /// A fixed-size bitset type with a partially dense, partially sparse
 /// representation. The bitset is broken into chunks, and chunks that are all
 /// zeros or all ones are represented and handled very efficiently.
@@ -1542,6 +1548,12 @@ impl<T: Idx> GrowableBitSet<T> {
     }
 }
 
+impl<T: Idx> From<BitSet<T>> for GrowableBitSet<T> {
+    fn from(bit_set: BitSet<T>) -> Self {
+        Self { bit_set }
+    }
+}
+
 /// A fixed-size 2D bit matrix type with a dense representation.
 ///
 /// `R` and `C` are index types used to identify rows and columns respectively;
diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs
index 0d38b94965a..1570a08f3ca 100644
--- a/compiler/rustc_infer/src/infer/glb.rs
+++ b/compiler/rustc_infer/src/infer/glb.rs
@@ -95,12 +95,20 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
         T: Relate<'tcx>,
     {
         debug!("binders(a={:?}, b={:?})", a, b);
-
-        // When higher-ranked types are involved, computing the LUB is
-        // very challenging, switch to invariance. This is obviously
-        // overly conservative but works ok in practice.
-        self.relate_with_variance(ty::Variance::Invariant, ty::VarianceDiagInfo::default(), a, b)?;
-        Ok(a)
+        if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
+            // When higher-ranked types are involved, computing the GLB is
+            // very challenging, switch to invariance. This is obviously
+            // overly conservative but works ok in practice.
+            self.relate_with_variance(
+                ty::Variance::Invariant,
+                ty::VarianceDiagInfo::default(),
+                a,
+                b,
+            )?;
+            Ok(a)
+        } else {
+            Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?))
+        }
     }
 }
 
diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs
index 498c1e907c4..9f96d52c850 100644
--- a/compiler/rustc_infer/src/infer/lub.rs
+++ b/compiler/rustc_infer/src/infer/lub.rs
@@ -95,12 +95,20 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
         T: Relate<'tcx>,
     {
         debug!("binders(a={:?}, b={:?})", a, b);
-
-        // When higher-ranked types are involved, computing the LUB is
-        // very challenging, switch to invariance. This is obviously
-        // overly conservative but works ok in practice.
-        self.relate_with_variance(ty::Variance::Invariant, ty::VarianceDiagInfo::default(), a, b)?;
-        Ok(a)
+        if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
+            // When higher-ranked types are involved, computing the LUB is
+            // very challenging, switch to invariance. This is obviously
+            // overly conservative but works ok in practice.
+            self.relate_with_variance(
+                ty::Variance::Invariant,
+                ty::VarianceDiagInfo::default(),
+                a,
+                b,
+            )?;
+            Ok(a)
+        } else {
+            Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?))
+        }
     }
 }
 
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index ebe156d081d..846e7f7b921 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -662,7 +662,11 @@ where
         match b.kind() {
             ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
                 // Forbid inference variables in the RHS.
-                bug!("unexpected inference var {:?}", b)
+                self.infcx.tcx.sess.delay_span_bug(
+                    self.delegate.span(),
+                    format!("unexpected inference var {:?}", b,),
+                );
+                Ok(a)
             }
             // FIXME(invariance): see the related FIXME above.
             _ => self.infcx.super_combine_consts(self, a, b),
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 7cf447a1419..8266f1566c4 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1610,13 +1610,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedBrokenConst {
             hir::ItemKind::Const(_, body_id) => {
                 let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id();
                 // trigger the query once for all constants since that will already report the errors
-                // FIXME: Use ensure here
-                let _ = cx.tcx.const_eval_poly(def_id);
+                cx.tcx.ensure().const_eval_poly(def_id);
             }
             hir::ItemKind::Static(_, _, body_id) => {
                 let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id();
-                // FIXME: Use ensure here
-                let _ = cx.tcx.eval_static_initializer(def_id);
+                cx.tcx.ensure().eval_static_initializer(def_id);
             }
             _ => {}
         }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index f0182883d2b..c1255ae5056 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -159,28 +159,16 @@ macro_rules! late_lint_passes {
         $macro!(
             $args,
             [
-                // FIXME: Look into regression when this is used as a module lint
-                // May Depend on constants elsewhere
-                UnusedBrokenConst: UnusedBrokenConst,
-                // Needs to run after UnusedAttributes as it marks all `feature` attributes as used.
-                UnstableFeatures: UnstableFeatures,
                 // Tracks state across modules
                 UnnameableTestItems: UnnameableTestItems::new(),
                 // Tracks attributes of parents
                 MissingDoc: MissingDoc::new(),
-                // Depends on access levels
+                // Builds a global list of all impls of `Debug`.
                 // FIXME: Turn the computation of types which implement Debug into a query
                 // and change this to a module lint pass
                 MissingDebugImplementations: MissingDebugImplementations::default(),
-                ArrayIntoIter: ArrayIntoIter::default(),
+                // Keeps a global list of foreign declarations.
                 ClashingExternDeclarations: ClashingExternDeclarations::new(),
-                DropTraitConstraints: DropTraitConstraints,
-                TemporaryCStringAsPtr: TemporaryCStringAsPtr,
-                NonPanicFmt: NonPanicFmt,
-                NoopMethodCall: NoopMethodCall,
-                EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums,
-                InvalidAtomicOrdering: InvalidAtomicOrdering,
-                NamedAsmLabels: NamedAsmLabels,
             ]
         );
     };
@@ -216,6 +204,17 @@ macro_rules! late_lint_mod_passes {
                 ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
                 InvalidValue: InvalidValue,
                 DerefNullPtr: DerefNullPtr,
+                // May Depend on constants elsewhere
+                UnusedBrokenConst: UnusedBrokenConst,
+                UnstableFeatures: UnstableFeatures,
+                ArrayIntoIter: ArrayIntoIter::default(),
+                DropTraitConstraints: DropTraitConstraints,
+                TemporaryCStringAsPtr: TemporaryCStringAsPtr,
+                NonPanicFmt: NonPanicFmt,
+                NoopMethodCall: NoopMethodCall,
+                EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums,
+                InvalidAtomicOrdering: InvalidAtomicOrdering,
+                NamedAsmLabels: NamedAsmLabels,
             ]
         );
     };
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index e3581a7607f..0bea2a10da8 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -214,7 +214,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     impl_parent => { table }
     impl_polarity => { table_direct }
     impl_defaultness => { table_direct }
-    impl_constness => { table_direct }
+    constness => { table_direct }
     coerce_unsized_info => { table }
     mir_const_qualif => { table }
     rendered_const => { table }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 463af64a2a4..75286b89068 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1063,7 +1063,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         };
 
         record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
-        self.tables.impl_constness.set(def_id.index, hir::Constness::Const);
+        self.tables.constness.set(def_id.index, hir::Constness::Const);
         record_array!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
             assert!(f.did.is_local());
             f.did.index
@@ -1092,7 +1092,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         };
 
         record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
-        self.tables.impl_constness.set(def_id.index, hir::Constness::Const);
+        self.tables.constness.set(def_id.index, hir::Constness::Const);
         self.encode_item_type(def_id);
         if variant.ctor_kind == CtorKind::Fn {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
@@ -1175,7 +1175,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         };
 
         record!(self.tables.repr_options[def_id] <- adt_def.repr());
-        self.tables.impl_constness.set(def_id.index, hir::Constness::Const);
+        self.tables.constness.set(def_id.index, hir::Constness::Const);
         record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data)));
         self.encode_item_type(def_id);
         if variant.ctor_kind == CtorKind::Fn {
@@ -1226,7 +1226,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     }
                 };
                 self.tables.asyncness.set(def_id.index, m_sig.header.asyncness);
-                self.tables.impl_constness.set(def_id.index, hir::Constness::NotConst);
+                self.tables.constness.set(def_id.index, hir::Constness::NotConst);
                 record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData {
                     container,
                     has_self: trait_item.fn_has_self_parameter,
@@ -1290,7 +1290,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 } else {
                     hir::Constness::NotConst
                 };
-                self.tables.impl_constness.set(def_id.index, constness);
+                self.tables.constness.set(def_id.index, constness);
                 record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData {
                     container,
                     has_self: impl_item.fn_has_self_parameter,
@@ -1413,7 +1413,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hir::ItemKind::Fn(ref sig, .., body) => {
                 self.tables.asyncness.set(def_id.index, sig.header.asyncness);
                 record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
-                self.tables.impl_constness.set(def_id.index, sig.header.constness);
+                self.tables.constness.set(def_id.index, sig.header.constness);
                 EntryKind::Fn
             }
             hir::ItemKind::Macro(ref macro_def, _) => {
@@ -1437,7 +1437,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hir::ItemKind::Struct(ref struct_def, _) => {
                 let adt_def = self.tcx.adt_def(def_id);
                 record!(self.tables.repr_options[def_id] <- adt_def.repr());
-                self.tables.impl_constness.set(def_id.index, hir::Constness::Const);
+                self.tables.constness.set(def_id.index, hir::Constness::Const);
 
                 // Encode def_ids for each field and method
                 // for methods, write all the stuff get_trait_method
@@ -1468,7 +1468,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             }
             hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
                 self.tables.impl_defaultness.set(def_id.index, *defaultness);
-                self.tables.impl_constness.set(def_id.index, *constness);
+                self.tables.constness.set(def_id.index, *constness);
 
                 let trait_ref = self.tcx.impl_trait_ref(def_id);
                 if let Some(trait_ref) = trait_ref {
@@ -1934,7 +1934,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 } else {
                     hir::Constness::NotConst
                 };
-                self.tables.impl_constness.set(def_id.index, constness);
+                self.tables.constness.set(def_id.index, constness);
                 record!(self.tables.kind[def_id] <- EntryKind::ForeignFn);
             }
             hir::ForeignItemKind::Static(..) => {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 04f0847f5cc..a58c0e68ee3 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -364,7 +364,7 @@ define_tables! {
     thir_abstract_const: Table<DefIndex, LazyValue<&'static [thir::abstract_const::Node<'static>]>>,
     impl_parent: Table<DefIndex, RawDefId>,
     impl_polarity: Table<DefIndex, ty::ImplPolarity>,
-    impl_constness: Table<DefIndex, hir::Constness>,
+    constness: Table<DefIndex, hir::Constness>,
     is_intrinsic: Table<DefIndex, ()>,
     impl_defaultness: Table<DefIndex, hir::Defaultness>,
     // FIXME(eddyb) perhaps compute this on the fly if cheap enough?
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 11a35109fde..10c4ea63a68 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -244,12 +244,12 @@ impl<Tag> Allocation<Tag> {
 
 impl Allocation {
     /// Convert Tag and add Extra fields
-    pub fn convert_tag_add_extra<Tag, Extra>(
+    pub fn convert_tag_add_extra<Tag, Extra, Err>(
         self,
         cx: &impl HasDataLayout,
         extra: Extra,
-        mut tagger: impl FnMut(Pointer<AllocId>) -> Pointer<Tag>,
-    ) -> Allocation<Tag, Extra> {
+        mut tagger: impl FnMut(Pointer<AllocId>) -> Result<Pointer<Tag>, Err>,
+    ) -> Result<Allocation<Tag, Extra>, Err> {
         // Compute new pointer tags, which also adjusts the bytes.
         let mut bytes = self.bytes;
         let mut new_relocations = Vec::with_capacity(self.relocations.0.len());
@@ -260,19 +260,19 @@ impl Allocation {
             let ptr_bytes = &mut bytes[idx..idx + ptr_size];
             let bits = read_target_uint(endian, ptr_bytes).unwrap();
             let (ptr_tag, ptr_offset) =
-                tagger(Pointer::new(alloc_id, Size::from_bytes(bits))).into_parts();
+                tagger(Pointer::new(alloc_id, Size::from_bytes(bits)))?.into_parts();
             write_target_uint(endian, ptr_bytes, ptr_offset.bytes().into()).unwrap();
             new_relocations.push((offset, ptr_tag));
         }
         // Create allocation.
-        Allocation {
+        Ok(Allocation {
             bytes,
             relocations: Relocations::from_presorted(new_relocations),
             init_mask: self.init_mask,
             align: self.align,
             mutability: self.mutability,
             extra,
-        }
+        })
     }
 }
 
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 5f32f0d5e89..4895b53bb26 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -3,7 +3,7 @@ use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId}
 use crate::mir;
 use crate::ty::fold::TypeFoldable;
 use crate::ty::subst::InternalSubsts;
-use crate::ty::{self, query::TyCtxtAt, TyCtxt};
+use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt};
 use rustc_hir::def_id::DefId;
 use rustc_span::{Span, DUMMY_SP};
 
@@ -171,6 +171,39 @@ impl<'tcx> TyCtxtAt<'tcx> {
     }
 }
 
+impl<'tcx> TyCtxtEnsure<'tcx> {
+    /// Evaluates a constant without providing any substitutions. This is useful to evaluate consts
+    /// that can't take any generic arguments like statics, const items or enum discriminants. If a
+    /// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
+    #[instrument(skip(self), level = "debug")]
+    pub fn const_eval_poly(self, def_id: DefId) {
+        // In some situations def_id will have substitutions within scope, but they aren't allowed
+        // to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions
+        // into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
+        // encountered.
+        let substs = InternalSubsts::identity_for_item(self.tcx, def_id);
+        let instance = ty::Instance::new(def_id, substs);
+        let cid = GlobalId { instance, promoted: None };
+        let param_env =
+            self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx).with_const();
+        // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
+        // improve caching of queries.
+        let inputs = self.tcx.erase_regions(param_env.and(cid));
+        self.eval_to_const_value_raw(inputs)
+    }
+
+    /// Evaluate a static's initializer, returning the allocation of the initializer's memory.
+    pub fn eval_static_initializer(self, def_id: DefId) {
+        trace!("eval_static_initializer: Need to compute {:?}", def_id);
+        assert!(self.tcx.is_static(def_id));
+        let instance = ty::Instance::mono(self.tcx, def_id);
+        let gid = GlobalId { instance, promoted: None };
+        let param_env = ty::ParamEnv::reveal_all().with_const();
+        trace!("eval_to_allocation: Need to compute {:?}", gid);
+        self.eval_to_allocation_raw(param_env.and(gid))
+    }
+}
+
 impl<'tcx> TyCtxt<'tcx> {
     /// Destructure a type-level constant ADT or array into its variant index and its field values.
     /// Panics if the destructuring fails, use `try_destructure_const` for fallible version.
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index c173d453041..4265559cd31 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -195,6 +195,7 @@ pub enum MirPhase {
     /// Beginning with this phase, the following variants are disallowed:
     /// * [`TerminatorKind::Yield`](terminator::TerminatorKind::Yield)
     /// * [`TerminatorKind::GeneratorDrop`](terminator::TerminatorKind::GeneratorDrop)
+    /// * [`ProjectionElem::Deref`] of `Box`
     GeneratorsLowered = 6,
     Optimized = 7,
 }
diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs
index afcd5db8f48..4418b848e51 100644
--- a/compiler/rustc_middle/src/mir/spanview.rs
+++ b/compiler/rustc_middle/src/mir/spanview.rs
@@ -667,7 +667,7 @@ fn trim_span_hi(span: Span, to_pos: BytePos) -> Span {
 fn fn_span<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Span {
     let fn_decl_span = tcx.def_span(def_id);
     if let Some(body_span) = hir_body(tcx, def_id).map(|hir_body| hir_body.value.span) {
-        if fn_decl_span.ctxt() == body_span.ctxt() { fn_decl_span.to(body_span) } else { body_span }
+        if fn_decl_span.eq_ctxt(body_span) { fn_decl_span.to(body_span) } else { body_span }
     } else {
         fn_decl_span
     }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index e0b4eced075..ca2c03cb614 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -590,9 +590,9 @@ rustc_queries! {
     /// not have the feature gate active).
     ///
     /// **Do not call this function manually.** It is only meant to cache the base data for the
-    /// `is_const_fn` function.
-    query impl_constness(key: DefId) -> hir::Constness {
-        desc { |tcx| "checking if item is const fn: `{}`", tcx.def_path_str(key) }
+    /// `is_const_fn` function. Consider using `is_const_fn` or `is_const_fn_raw` instead.
+    query constness(key: DefId) -> hir::Constness {
+        desc { |tcx| "checking if item is const: `{}`", tcx.def_path_str(key) }
         cache_on_disk_if { key.is_local() }
         separate_provide_extern
     }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index c43cf07b3ad..c9589a70488 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -114,6 +114,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     type DelaySpanBugEmitted = DelaySpanBugEmitted;
     type PredicateKind = ty::PredicateKind<'tcx>;
     type AllocId = crate::mir::interpret::AllocId;
+
+    type EarlyBoundRegion = ty::EarlyBoundRegion;
+    type BoundRegion = ty::BoundRegion;
+    type FreeRegion = ty::FreeRegion;
+    type RegionVid = ty::RegionVid;
+    type PlaceholderRegion = ty::PlaceholderRegion;
 }
 
 /// A type that is not publicly constructable. This prevents people from making [`TyKind::Error`]s
@@ -136,7 +142,7 @@ pub struct CtxtInterners<'tcx> {
     type_: InternedSet<'tcx, WithStableHash<TyS<'tcx>>>,
     substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
     canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
-    region: InternedSet<'tcx, RegionKind>,
+    region: InternedSet<'tcx, RegionKind<'tcx>>,
     poly_existential_predicates:
         InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>,
     predicate: InternedSet<'tcx, PredicateS<'tcx>>,
@@ -2175,7 +2181,7 @@ macro_rules! direct_interners {
 }
 
 direct_interners! {
-    region: mk_region(RegionKind): Region -> Region<'tcx>,
+    region: mk_region(RegionKind<'tcx>): Region -> Region<'tcx>,
     const_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>,
     const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
     layout: intern_layout(LayoutS<'tcx>): Layout -> Layout<'tcx>,
@@ -2274,7 +2280,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Same a `self.mk_region(kind)`, but avoids accessing the interners if
     /// `*r == kind`.
     #[inline]
-    pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind) -> Region<'tcx> {
+    pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
         if *r == kind { r } else { self.mk_region(kind) }
     }
 
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index 99aa182f3a6..31b8fa1ce95 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -371,6 +371,13 @@ where
         Ok(self.fold_const(c))
     }
 
+    fn try_fold_unevaluated(
+        &mut self,
+        c: ty::Unevaluated<'tcx>,
+    ) -> Result<ty::Unevaluated<'tcx>, Self::Error> {
+        Ok(self.fold_unevaluated(c))
+    }
+
     fn try_fold_predicate(
         &mut self,
         p: ty::Predicate<'tcx>,
diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs
index 42e5a05d63b..88397a2bb56 100644
--- a/compiler/rustc_middle/src/ty/impls_ty.rs
+++ b/compiler/rustc_middle/src/ty/impls_ty.rs
@@ -11,7 +11,6 @@ use rustc_data_structures::stable_hasher::HashingControls;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
 use rustc_query_system::ich::StableHashingContext;
 use std::cell::RefCell;
-use std::mem;
 
 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for &'tcx ty::List<T>
 where
@@ -102,43 +101,12 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArgKin
     }
 }
 
-impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionKind {
+impl<'a> HashStable<StableHashingContext<'a>> for ty::EarlyBoundRegion {
+    #[inline]
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        mem::discriminant(self).hash_stable(hcx, hasher);
-        match *self {
-            ty::ReErased | ty::ReStatic => {
-                // No variant fields to hash for these ...
-            }
-            ty::ReEmpty(universe) => {
-                universe.hash_stable(hcx, hasher);
-            }
-            ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrAnon(i), .. }) => {
-                db.hash_stable(hcx, hasher);
-                i.hash_stable(hcx, hasher);
-            }
-            ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrNamed(def_id, name), .. }) => {
-                db.hash_stable(hcx, hasher);
-                def_id.hash_stable(hcx, hasher);
-                name.hash_stable(hcx, hasher);
-            }
-            ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrEnv, .. }) => {
-                db.hash_stable(hcx, hasher);
-            }
-            ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
-                def_id.hash_stable(hcx, hasher);
-                index.hash_stable(hcx, hasher);
-                name.hash_stable(hcx, hasher);
-            }
-            ty::ReFree(ref free_region) => {
-                free_region.hash_stable(hcx, hasher);
-            }
-            ty::RePlaceholder(p) => {
-                p.hash_stable(hcx, hasher);
-            }
-            ty::ReVar(reg) => {
-                reg.hash_stable(hcx, hasher);
-            }
-        }
+        self.def_id.hash_stable(hcx, hasher);
+        self.index.hash_stable(hcx, hasher);
+        self.name.hash_stable(hcx, hasher);
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 749feb850b0..9c1972e81e1 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -55,6 +55,7 @@ use std::{fmt, str};
 
 pub use crate::ty::diagnostics::*;
 pub use rustc_type_ir::InferTy::*;
+pub use rustc_type_ir::RegionKind::*;
 pub use rustc_type_ir::TyKind::*;
 pub use rustc_type_ir::*;
 
@@ -80,7 +81,6 @@ pub use self::list::List;
 pub use self::parameterized::ParameterizedOverTcx;
 pub use self::rvalue_scopes::RvalueScopes;
 pub use self::sty::BoundRegionKind::*;
-pub use self::sty::RegionKind::*;
 pub use self::sty::{
     Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar,
     BoundVariableKind, CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid,
@@ -1161,83 +1161,6 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
     }
 }
 
-rustc_index::newtype_index! {
-    /// "Universes" are used during type- and trait-checking in the
-    /// presence of `for<..>` binders to control what sets of names are
-    /// visible. Universes are arranged into a tree: the root universe
-    /// contains names that are always visible. Each child then adds a new
-    /// set of names that are visible, in addition to those of its parent.
-    /// We say that the child universe "extends" the parent universe with
-    /// new names.
-    ///
-    /// To make this more concrete, consider this program:
-    ///
-    /// ```ignore (illustrative)
-    /// struct Foo { }
-    /// fn bar<T>(x: T) {
-    ///   let y: for<'a> fn(&'a u8, Foo) = ...;
-    /// }
-    /// ```
-    ///
-    /// The struct name `Foo` is in the root universe U0. But the type
-    /// parameter `T`, introduced on `bar`, is in an extended universe U1
-    /// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside
-    /// of `bar`, we cannot name `T`. Then, within the type of `y`, the
-    /// region `'a` is in a universe U2 that extends U1, because we can
-    /// name it inside the fn type but not outside.
-    ///
-    /// Universes are used to do type- and trait-checking around these
-    /// "forall" binders (also called **universal quantification**). The
-    /// idea is that when, in the body of `bar`, we refer to `T` as a
-    /// type, we aren't referring to any type in particular, but rather a
-    /// kind of "fresh" type that is distinct from all other types we have
-    /// actually declared. This is called a **placeholder** type, and we
-    /// use universes to talk about this. In other words, a type name in
-    /// universe 0 always corresponds to some "ground" type that the user
-    /// declared, but a type name in a non-zero universe is a placeholder
-    /// type -- an idealized representative of "types in general" that we
-    /// use for checking generic functions.
-    pub struct UniverseIndex {
-        derive [HashStable]
-        DEBUG_FORMAT = "U{}",
-    }
-}
-
-impl UniverseIndex {
-    pub const ROOT: UniverseIndex = UniverseIndex::from_u32(0);
-
-    /// Returns the "next" universe index in order -- this new index
-    /// is considered to extend all previous universes. This
-    /// corresponds to entering a `forall` quantifier. So, for
-    /// example, suppose we have this type in universe `U`:
-    ///
-    /// ```ignore (illustrative)
-    /// for<'a> fn(&'a u32)
-    /// ```
-    ///
-    /// Once we "enter" into this `for<'a>` quantifier, we are in a
-    /// new universe that extends `U` -- in this new universe, we can
-    /// name the region `'a`, but that region was not nameable from
-    /// `U` because it was not in scope there.
-    pub fn next_universe(self) -> UniverseIndex {
-        UniverseIndex::from_u32(self.private.checked_add(1).unwrap())
-    }
-
-    /// Returns `true` if `self` can name a name from `other` -- in other words,
-    /// if the set of names in `self` is a superset of those in
-    /// `other` (`self >= other`).
-    pub fn can_name(self, other: UniverseIndex) -> bool {
-        self.private >= other.private
-    }
-
-    /// Returns `true` if `self` cannot name some names from `other` -- in other
-    /// words, if the set of names in `self` is a strict subset of
-    /// those in `other` (`self < other`).
-    pub fn cannot_name(self, other: UniverseIndex) -> bool {
-        self.private < other.private
-    }
-}
-
 /// The "placeholder index" fully defines a placeholder region, type, or const. Placeholders are
 /// identified by both a universe, as well as a name residing within that universe. Distinct bound
 /// regions/types/consts within the same universe simply have an unknown relationship to one
@@ -2341,7 +2264,7 @@ impl<'tcx> TyCtxt<'tcx> {
     #[inline]
     pub fn is_const_fn_raw(self, def_id: DefId) -> bool {
         matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..))
-            && self.impl_constness(def_id) == hir::Constness::Const
+            && self.constness(def_id) == hir::Constness::Const
     }
 
     #[inline]
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 7ae23d371e5..d57cf8f0149 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -57,7 +57,7 @@ pub trait Printer<'tcx>: Sized {
         self.default_print_impl_path(impl_def_id, substs, self_ty, trait_ref)
     }
 
-    fn print_region(self, region: ty::Region<'_>) -> Result<Self::Region, Self::Error>;
+    fn print_region(self, region: ty::Region<'tcx>) -> Result<Self::Region, Self::Error>;
 
     fn print_type(self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>;
 
@@ -291,7 +291,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
     characteristic_def_id_of_type_cached(ty, &mut SsoHashSet::new())
 }
 
-impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Region<'_> {
+impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Region<'tcx> {
     type Output = P::Region;
     type Error = P::Error;
     fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 58dab0f96ab..97e5a4983fc 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -182,7 +182,7 @@ impl<'tcx> RegionHighlightMode<'tcx> {
     }
 
     /// Returns `Some(n)` with the number to use for the given region, if any.
-    fn region_highlighted(&self, region: ty::Region<'_>) -> Option<usize> {
+    fn region_highlighted(&self, region: ty::Region<'tcx>) -> Option<usize> {
         self.highlight_regions.iter().find_map(|h| match h {
             Some((r, n)) if *r == region => Some(*n),
             _ => None,
@@ -276,7 +276,7 @@ pub trait PrettyPrinter<'tcx>:
     /// Returns `true` if the region should be printed in
     /// optional positions, e.g., `&'a T` or `dyn Tr + 'b`.
     /// This is typically the case for all non-`'_` regions.
-    fn should_print_region(&self, region: ty::Region<'_>) -> bool;
+    fn should_print_region(&self, region: ty::Region<'tcx>) -> bool;
 
     // Defaults (should not be overridden):
 
@@ -1706,7 +1706,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
         self.default_print_def_path(def_id, substs)
     }
 
-    fn print_region(self, region: ty::Region<'_>) -> Result<Self::Region, Self::Error> {
+    fn print_region(self, region: ty::Region<'tcx>) -> Result<Self::Region, Self::Error> {
         self.pretty_print_region(region)
     }
 
@@ -1911,7 +1911,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
         Ok(inner)
     }
 
-    fn should_print_region(&self, region: ty::Region<'_>) -> bool {
+    fn should_print_region(&self, region: ty::Region<'tcx>) -> bool {
         let highlight = self.region_highlight_mode;
         if highlight.region_highlighted(region).is_some() {
             return true;
@@ -1978,8 +1978,8 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
 }
 
 // HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`.
-impl FmtPrinter<'_, '_> {
-    pub fn pretty_print_region(mut self, region: ty::Region<'_>) -> Result<Self, fmt::Error> {
+impl<'tcx> FmtPrinter<'_, 'tcx> {
+    pub fn pretty_print_region(mut self, region: ty::Region<'tcx>) -> Result<Self, fmt::Error> {
         define_scoped_cx!(self);
 
         // Watch out for region highlights.
@@ -2383,15 +2383,6 @@ macro_rules! define_print_and_forward_display {
     };
 }
 
-// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting.
-impl<'tcx> fmt::Display for ty::Region<'tcx> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ty::tls::with(|tcx| {
-            f.write_str(&self.print(FmtPrinter::new(tcx, Namespace::TypeNS))?.into_buffer())
-        })
-    }
-}
-
 /// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only
 /// the trait path. That is, it will print `Trait<U>` instead of
 /// `<T as Trait<U>>`.
@@ -2456,6 +2447,7 @@ impl<'tcx> ty::PolyTraitPredicate<'tcx> {
 }
 
 forward_display_to_print! {
+    ty::Region<'tcx>,
     Ty<'tcx>,
     &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
     ty::Const<'tcx>,
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 961792260e4..8ba5b882fdd 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -81,30 +81,6 @@ impl fmt::Debug for ty::BoundRegionKind {
     }
 }
 
-impl fmt::Debug for ty::RegionKind {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            ty::ReEarlyBound(ref data) => write!(f, "ReEarlyBound({}, {})", data.index, data.name),
-
-            ty::ReLateBound(binder_id, ref bound_region) => {
-                write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region)
-            }
-
-            ty::ReFree(ref fr) => fr.fmt(f),
-
-            ty::ReStatic => write!(f, "ReStatic"),
-
-            ty::ReVar(ref vid) => vid.fmt(f),
-
-            ty::RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
-
-            ty::ReEmpty(ui) => write!(f, "ReEmpty({:?})", ui),
-
-            ty::ReErased => write!(f, "ReErased"),
-        }
-    }
-}
-
 impl fmt::Debug for ty::FreeRegion {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region)
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index cc85859e1cc..296442e2436 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -29,11 +29,13 @@ use std::ops::{ControlFlow, Deref, Range};
 use ty::util::IntTypeExt;
 
 use rustc_type_ir::sty::TyKind::*;
+use rustc_type_ir::RegionKind as IrRegionKind;
 use rustc_type_ir::TyKind as IrTyKind;
 
 // Re-export the `TyKind` from `rustc_type_ir` here for convenience
 #[rustc_diagnostic_item = "TyKind"]
 pub type TyKind<'tcx> = IrTyKind<TyCtxt<'tcx>>;
+pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
 
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable, Lift)]
@@ -1308,12 +1310,12 @@ impl ParamConst {
 /// Use this rather than `RegionKind`, whenever possible.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
 #[rustc_pass_by_value]
-pub struct Region<'tcx>(pub Interned<'tcx, RegionKind>);
+pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
 
 impl<'tcx> Deref for Region<'tcx> {
-    type Target = RegionKind;
+    type Target = RegionKind<'tcx>;
 
-    fn deref(&self) -> &RegionKind {
+    fn deref(&self) -> &RegionKind<'tcx> {
         &self.0.0
     }
 }
@@ -1324,157 +1326,19 @@ impl<'tcx> fmt::Debug for Region<'tcx> {
     }
 }
 
-/// Representation of regions. Note that the NLL checker uses a distinct
-/// representation of regions. For this reason, it internally replaces all the
-/// regions with inference variables -- the index of the variable is then used
-/// to index into internal NLL data structures. See `rustc_const_eval::borrow_check`
-/// module for more information.
-///
-/// Note: operations are on the wrapper `Region` type, which is interned,
-/// rather than this type.
-///
-/// ## The Region lattice within a given function
-///
-/// In general, the region lattice looks like
-///
-/// ```text
-/// static ----------+-----...------+       (greatest)
-/// |                |              |
-/// early-bound and  |              |
-/// free regions     |              |
-/// |                |              |
-/// |                |              |
-/// empty(root)   placeholder(U1)   |
-/// |            /                  |
-/// |           /         placeholder(Un)
-/// empty(U1) --         /
-/// |                   /
-/// ...                /
-/// |                 /
-/// empty(Un) --------                      (smallest)
-/// ```
-///
-/// Early-bound/free regions are the named lifetimes in scope from the
-/// function declaration. They have relationships to one another
-/// determined based on the declared relationships from the
-/// function.
-///
-/// Note that inference variables and bound regions are not included
-/// in this diagram. In the case of inference variables, they should
-/// be inferred to some other region from the diagram.  In the case of
-/// bound regions, they are excluded because they don't make sense to
-/// include -- the diagram indicates the relationship between free
-/// regions.
-///
-/// ## Inference variables
-///
-/// During region inference, we sometimes create inference variables,
-/// represented as `ReVar`. These will be inferred by the code in
-/// `infer::lexical_region_resolve` to some free region from the
-/// lattice above (the minimal region that meets the
-/// constraints).
-///
-/// During NLL checking, where regions are defined differently, we
-/// also use `ReVar` -- in that case, the index is used to index into
-/// the NLL region checker's data structures. The variable may in fact
-/// represent either a free region or an inference variable, in that
-/// case.
-///
-/// ## Bound Regions
-///
-/// These are regions that are stored behind a binder and must be substituted
-/// with some concrete region before being used. There are two kind of
-/// bound regions: early-bound, which are bound in an item's `Generics`,
-/// and are substituted by an `InternalSubsts`, and late-bound, which are part of
-/// higher-ranked types (e.g., `for<'a> fn(&'a ())`), and are substituted by
-/// the likes of `liberate_late_bound_regions`. The distinction exists
-/// because higher-ranked lifetimes aren't supported in all places. See [1][2].
-///
-/// Unlike `Param`s, bound regions are not supposed to exist "in the wild"
-/// outside their binder, e.g., in types passed to type inference, and
-/// should first be substituted (by placeholder regions, free regions,
-/// or region variables).
-///
-/// ## Placeholder and Free Regions
-///
-/// One often wants to work with bound regions without knowing their precise
-/// identity. For example, when checking a function, the lifetime of a borrow
-/// can end up being assigned to some region parameter. In these cases,
-/// it must be ensured that bounds on the region can't be accidentally
-/// assumed without being checked.
-///
-/// To do this, we replace the bound regions with placeholder markers,
-/// which don't satisfy any relation not explicitly provided.
-///
-/// There are two kinds of placeholder regions in rustc: `ReFree` and
-/// `RePlaceholder`. When checking an item's body, `ReFree` is supposed
-/// to be used. These also support explicit bounds: both the internally-stored
-/// *scope*, which the region is assumed to outlive, as well as other
-/// relations stored in the `FreeRegionMap`. Note that these relations
-/// aren't checked when you `make_subregion` (or `eq_types`), only by
-/// `resolve_regions_and_report_errors`.
-///
-/// When working with higher-ranked types, some region relations aren't
-/// yet known, so you can't just call `resolve_regions_and_report_errors`.
-/// `RePlaceholder` is designed for this purpose. In these contexts,
-/// there's also the risk that some inference variable laying around will
-/// get unified with your placeholder region: if you want to check whether
-/// `for<'a> Foo<'_>: 'a`, and you substitute your bound region `'a`
-/// with a placeholder region `'%a`, the variable `'_` would just be
-/// instantiated to the placeholder region `'%a`, which is wrong because
-/// the inference variable is supposed to satisfy the relation
-/// *for every value of the placeholder region*. To ensure that doesn't
-/// happen, you can use `leak_check`. This is more clearly explained
-/// by the [rustc dev guide].
-///
-/// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
-/// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
-/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
-#[derive(Clone, PartialEq, Eq, Hash, Copy, TyEncodable, TyDecodable, PartialOrd, Ord)]
-pub enum RegionKind {
-    /// Region bound in a type or fn declaration which will be
-    /// substituted 'early' -- that is, at the same time when type
-    /// parameters are substituted.
-    ReEarlyBound(EarlyBoundRegion),
-
-    /// Region bound in a function scope, which will be substituted when the
-    /// function is called.
-    ReLateBound(ty::DebruijnIndex, BoundRegion),
-
-    /// When checking a function body, the types of all arguments and so forth
-    /// that refer to bound region parameters are modified to refer to free
-    /// region parameters.
-    ReFree(FreeRegion),
-
-    /// Static data that has an "infinite" lifetime. Top in the region lattice.
-    ReStatic,
-
-    /// A region variable. Should not exist outside of type inference.
-    ReVar(RegionVid),
-
-    /// A placeholder region -- basically, the higher-ranked version of `ReFree`.
-    /// Should not exist outside of type inference.
-    RePlaceholder(ty::PlaceholderRegion),
-
-    /// Empty lifetime is for data that is never accessed.  We tag the
-    /// empty lifetime with a universe -- the idea is that we don't
-    /// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable.
-    /// Therefore, the `'empty` in a universe `U` is less than all
-    /// regions visible from `U`, but not less than regions not visible
-    /// from `U`.
-    ReEmpty(ty::UniverseIndex),
-
-    /// Erased region, used by trait selection, in MIR and during codegen.
-    ReErased,
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)]
 pub struct EarlyBoundRegion {
     pub def_id: DefId,
     pub index: u32,
     pub name: Symbol,
 }
 
+impl fmt::Debug for EarlyBoundRegion {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}, {}", self.index, self.name)
+    }
+}
+
 /// A **`const`** **v**ariable **ID**.
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
 pub struct ConstVid<'tcx> {
@@ -1590,7 +1454,7 @@ impl<'tcx> PolyExistentialProjection<'tcx> {
 
 /// Region utilities
 impl<'tcx> Region<'tcx> {
-    pub fn kind(self) -> RegionKind {
+    pub fn kind(self) -> RegionKind<'tcx> {
         *self.0.0
     }
 
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index ca29dd7c08f..ad2898ccd67 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -82,7 +82,7 @@ impl<'tcx> GenericArgKind<'tcx> {
             GenericArgKind::Lifetime(lt) => {
                 // Ensure we can use the tag bits.
                 assert_eq!(mem::align_of_val(&*lt.0.0) & TAG_MASK, 0);
-                (REGION_TAG, lt.0.0 as *const ty::RegionKind as usize)
+                (REGION_TAG, lt.0.0 as *const ty::RegionKind<'tcx> as usize)
             }
             GenericArgKind::Type(ty) => {
                 // Ensure we can use the tag bits.
@@ -153,7 +153,7 @@ impl<'tcx> GenericArg<'tcx> {
         unsafe {
             match ptr & TAG_MASK {
                 REGION_TAG => GenericArgKind::Lifetime(ty::Region(Interned::new_unchecked(
-                    &*((ptr & !TAG_MASK) as *const ty::RegionKind),
+                    &*((ptr & !TAG_MASK) as *const ty::RegionKind<'tcx>),
                 ))),
                 TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
                     &*((ptr & !TAG_MASK) as *const WithStableHash<ty::TyS<'tcx>>),
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 33ef0283745..38846031bad 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -376,7 +376,7 @@ impl<'tcx> TyCtxt<'tcx> {
         let (did, constness) = self.find_map_relevant_impl(drop_trait, ty, |impl_did| {
             if let Some(item_id) = self.associated_item_def_ids(impl_did).first() {
                 if validate(self, impl_did).is_ok() {
-                    return Some((*item_id, self.impl_constness(impl_did)));
+                    return Some((*item_id, self.constness(impl_did)));
                 }
             }
             None
@@ -574,7 +574,7 @@ impl<'tcx> TyCtxt<'tcx> {
         self,
         closure_def_id: DefId,
         closure_substs: SubstsRef<'tcx>,
-        env_region: ty::RegionKind,
+        env_region: ty::RegionKind<'tcx>,
     ) -> Option<Ty<'tcx>> {
         let closure_ty = self.mk_closure(closure_def_id, closure_substs);
         let closure_kind_ty = closure_substs.as_closure().kind_ty();
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index ccbb518e72d..cffb67ef013 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -63,6 +63,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         (if_then_scope, then_source_info),
                         LintLevel::Inherited,
                         |this| {
+                            let source_info = if this.is_let(cond) {
+                                let variable_scope = this.new_source_scope(
+                                    then_expr.span,
+                                    LintLevel::Inherited,
+                                    None,
+                                );
+                                this.source_scope = variable_scope;
+                                SourceInfo { span: then_expr.span, scope: variable_scope }
+                            } else {
+                                this.source_info(then_expr.span)
+                            };
                             let (then_block, else_block) =
                                 this.in_if_then_scope(condition_scope, |this| {
                                     let then_blk = unpack!(this.then_else_break(
@@ -70,8 +81,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                                         &this.thir[cond],
                                         Some(condition_scope),
                                         condition_scope,
-                                        then_expr.span,
+                                        source_info
                                     ));
+
                                     this.expr_into_dest(destination, then_blk, then_expr)
                                 });
                             then_block.and(else_block)
@@ -97,7 +109,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             ExprKind::Let { expr, ref pat } => {
                 let scope = this.local_scope();
                 let (true_block, false_block) = this.in_if_then_scope(scope, |this| {
-                    this.lower_let_expr(block, &this.thir[expr], pat, scope, expr_span)
+                    this.lower_let_expr(block, &this.thir[expr], pat, scope, None, expr_span)
                 });
 
                 this.cfg.push_assign_constant(
@@ -575,4 +587,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
         block_and
     }
+
+    fn is_let(&self, expr: ExprId) -> bool {
+        match self.thir[expr].kind {
+            ExprKind::Let { .. } => true,
+            ExprKind::Scope { value, .. } => self.is_let(value),
+            _ => false,
+        }
+    }
 }
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index dc1860cb112..1628f1a4b85 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -40,7 +40,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         expr: &Expr<'tcx>,
         temp_scope_override: Option<region::Scope>,
         break_scope: region::Scope,
-        variable_scope_span: Span,
+        variable_source_info: SourceInfo,
     ) -> BlockAnd<()> {
         let this = self;
         let expr_span = expr.span;
@@ -52,7 +52,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     &this.thir[lhs],
                     temp_scope_override,
                     break_scope,
-                    variable_scope_span,
+                    variable_source_info,
                 ));
 
                 let rhs_then_block = unpack!(this.then_else_break(
@@ -60,7 +60,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     &this.thir[rhs],
                     temp_scope_override,
                     break_scope,
-                    variable_scope_span,
+                    variable_source_info,
                 ));
 
                 rhs_then_block.unit()
@@ -73,13 +73,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         &this.thir[value],
                         temp_scope_override,
                         break_scope,
-                        variable_scope_span,
+                        variable_source_info,
                     )
                 })
             }
-            ExprKind::Let { expr, ref pat } => {
-                this.lower_let_expr(block, &this.thir[expr], pat, break_scope, variable_scope_span)
-            }
+            ExprKind::Let { expr, ref pat } => this.lower_let_expr(
+                block,
+                &this.thir[expr],
+                pat,
+                break_scope,
+                Some(variable_source_info.scope),
+                variable_source_info.span,
+            ),
             _ => {
                 let temp_scope = temp_scope_override.unwrap_or_else(|| this.local_scope());
                 let mutability = Mutability::Mut;
@@ -1772,6 +1777,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         expr: &Expr<'tcx>,
         pat: &Pat<'tcx>,
         else_target: region::Scope,
+        source_scope: Option<SourceScope>,
         span: Span,
     ) -> BlockAnd<()> {
         let expr_span = expr.span;
@@ -1797,7 +1803,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap();
         self.break_for_else(otherwise_post_guard_block, else_target, self.source_info(expr_span));
 
-        self.declare_bindings(None, pat.span.to(span), pat, ArmHasGuard(false), opt_expr_place);
+        self.declare_bindings(
+            source_scope,
+            pat.span.to(span),
+            pat,
+            ArmHasGuard(false),
+            opt_expr_place,
+        );
+
         let post_guard_block = self.bind_pattern(
             self.source_info(pat.span),
             guard_candidate,
@@ -1969,12 +1982,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     Guard::If(e) => {
                         let e = &this.thir[e];
                         guard_span = e.span;
-                        this.then_else_break(block, e, None, match_scope, arm_span)
+                        this.then_else_break(
+                            block,
+                            e,
+                            None,
+                            match_scope,
+                            this.source_info(arm_span),
+                        )
                     }
                     Guard::IfLet(ref pat, scrutinee) => {
                         let s = &this.thir[scrutinee];
                         guard_span = s.span;
-                        this.lower_let_expr(block, s, pat, match_scope, arm_span)
+                        this.lower_let_expr(block, s, pat, match_scope, None, arm_span)
                     }
                 });
 
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index dc204eb47ae..76333b755b7 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -803,7 +803,7 @@ fn non_exhaustive_match<'p, 'tcx>(
     let mut suggestion = None;
     let sm = cx.tcx.sess.source_map();
     match arms {
-        [] if sp.ctxt() == expr_span.ctxt() => {
+        [] if sp.eq_ctxt(expr_span) => {
             // Get the span for the empty match body `{}`.
             let (indentation, more) = if let Some(snippet) = sm.indentation_before(sp) {
                 (format!("\n{}", snippet), "    ")
@@ -821,24 +821,36 @@ fn non_exhaustive_match<'p, 'tcx>(
             ));
         }
         [only] => {
-            let pre_indentation = if let (Some(snippet), true) = (
-                sm.indentation_before(only.span),
-                sm.is_multiline(sp.shrink_to_hi().with_hi(only.span.lo())),
-            ) {
-                format!("\n{}", snippet)
+            let (pre_indentation, is_multiline) = if let Some(snippet) = sm.indentation_before(only.span)
+                && let Ok(with_trailing) = sm.span_extend_while(only.span, |c| c.is_whitespace() || c == ',')
+                && sm.is_multiline(with_trailing)
+            {
+                (format!("\n{}", snippet), true)
+            } else {
+                (" ".to_string(), false)
+            };
+            let comma = if matches!(only.body.kind, hir::ExprKind::Block(..))
+                && only.span.eq_ctxt(only.body.span)
+                && is_multiline
+            {
+                ""
             } else {
-                " ".to_string()
+                ","
             };
-            let comma = if matches!(only.body.kind, hir::ExprKind::Block(..)) { "" } else { "," };
             suggestion = Some((
                 only.span.shrink_to_hi(),
                 format!("{}{}{} => todo!()", comma, pre_indentation, pattern),
             ));
         }
-        [.., prev, last] if prev.span.ctxt() == last.span.ctxt() => {
+        [.., prev, last] if prev.span.eq_ctxt(last.span) => {
             if let Ok(snippet) = sm.span_to_snippet(prev.span.between(last.span)) {
-                let comma =
-                    if matches!(last.body.kind, hir::ExprKind::Block(..)) { "" } else { "," };
+                let comma = if matches!(last.body.kind, hir::ExprKind::Block(..))
+                    && last.span.eq_ctxt(last.body.span)
+                {
+                    ""
+                } else {
+                    ","
+                };
                 suggestion = Some((
                     last.span.shrink_to_hi(),
                     format!(
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 8d16c5f22c3..c0b0cc3c591 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -410,7 +410,18 @@ where
     fn open_drop_for_box(&mut self, adt: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> BasicBlock {
         debug!("open_drop_for_box({:?}, {:?}, {:?})", self, adt, substs);
 
-        let interior = self.tcx().mk_place_deref(self.place);
+        // drop glue is sent straight to codegen
+        // box cannot be directly dereferenced
+        let unique_ty = adt.non_enum_variant().fields[0].ty(self.tcx(), substs);
+        let nonnull_ty =
+            unique_ty.ty_adt_def().unwrap().non_enum_variant().fields[0].ty(self.tcx(), substs);
+        let ptr_ty = self.tcx().mk_imm_ptr(substs[0].expect_ty());
+
+        let unique_place = self.tcx().mk_place_field(self.place, Field::new(0), unique_ty);
+        let nonnull_place = self.tcx().mk_place_field(unique_place, Field::new(0), nonnull_ty);
+        let ptr_place = self.tcx().mk_place_field(nonnull_place, Field::new(0), ptr_ty);
+        let interior = self.tcx().mk_place_deref(ptr_place);
+
         let interior_path = self.elaborator.deref_subpath(self.path);
 
         let succ = self.box_free_block(adt, substs, self.succ, self.unwind);
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 2bb9f48f9b7..782b620e28f 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -121,7 +121,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
 
         let source_file = source_map.lookup_source_file(body_span.lo());
         let fn_sig_span = match some_fn_sig.filter(|fn_sig| {
-            fn_sig.span.ctxt() == body_span.ctxt()
+            fn_sig.span.eq_ctxt(body_span)
                 && Lrc::ptr_eq(&source_file, &source_map.lookup_source_file(fn_sig.span.lo()))
         }) {
             Some(fn_sig) => fn_sig.span.with_hi(body_span.lo()),
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index 512d4daf343..82070b90325 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -195,7 +195,7 @@ impl CoverageSpan {
             .expn_span
             .parent_callsite()
             .unwrap_or_else(|| bug!("macro must have a parent"))
-            .ctxt() == body_span.ctxt()
+            .eq_ctxt(body_span)
         {
             return Some(current_macro);
         }
diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
new file mode 100644
index 00000000000..a80d2fbd644
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
@@ -0,0 +1,184 @@
+//! This pass transforms derefs of Box into a deref of the pointer inside Box.
+//!
+//! Box is not actually a pointer so it is incorrect to dereference it directly.
+
+use crate::MirPass;
+use rustc_hir::def_id::DefId;
+use rustc_index::vec::Idx;
+use rustc_middle::mir::patch::MirPatch;
+use rustc_middle::mir::visit::MutVisitor;
+use rustc_middle::mir::*;
+use rustc_middle::ty::subst::Subst;
+use rustc_middle::ty::{Ty, TyCtxt};
+
+/// Constructs the types used when accessing a Box's pointer
+pub fn build_ptr_tys<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    pointee: Ty<'tcx>,
+    unique_did: DefId,
+    nonnull_did: DefId,
+) -> (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>) {
+    let substs = tcx.intern_substs(&[pointee.into()]);
+    let unique_ty = tcx.bound_type_of(unique_did).subst(tcx, substs);
+    let nonnull_ty = tcx.bound_type_of(nonnull_did).subst(tcx, substs);
+    let ptr_ty = tcx.mk_imm_ptr(pointee);
+
+    (unique_ty, nonnull_ty, ptr_ty)
+}
+
+// Constructs the projection needed to access a Box's pointer
+pub fn build_projection<'tcx>(
+    unique_ty: Ty<'tcx>,
+    nonnull_ty: Ty<'tcx>,
+    ptr_ty: Ty<'tcx>,
+) -> [PlaceElem<'tcx>; 3] {
+    [
+        PlaceElem::Field(Field::new(0), unique_ty),
+        PlaceElem::Field(Field::new(0), nonnull_ty),
+        PlaceElem::Field(Field::new(0), ptr_ty),
+    ]
+}
+
+struct ElaborateBoxDerefVisitor<'tcx, 'a> {
+    tcx: TyCtxt<'tcx>,
+    unique_did: DefId,
+    nonnull_did: DefId,
+    local_decls: &'a mut LocalDecls<'tcx>,
+    patch: MirPatch<'tcx>,
+}
+
+impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn visit_place(
+        &mut self,
+        place: &mut Place<'tcx>,
+        context: visit::PlaceContext,
+        location: Location,
+    ) {
+        let tcx = self.tcx;
+
+        let base_ty = self.local_decls[place.local].ty;
+
+        // Derefer ensures that derefs are always the first projection
+        if place.projection.first() == Some(&PlaceElem::Deref) && base_ty.is_box() {
+            let source_info = self.local_decls[place.local].source_info;
+
+            let (unique_ty, nonnull_ty, ptr_ty) =
+                build_ptr_tys(tcx, base_ty.boxed_ty(), self.unique_did, self.nonnull_did);
+
+            let ptr_local = self.patch.new_temp(ptr_ty, source_info.span);
+            self.local_decls.push(LocalDecl::new(ptr_ty, source_info.span));
+
+            self.patch.add_statement(location, StatementKind::StorageLive(ptr_local));
+
+            self.patch.add_assign(
+                location,
+                Place::from(ptr_local),
+                Rvalue::Use(Operand::Copy(
+                    Place::from(place.local)
+                        .project_deeper(&build_projection(unique_ty, nonnull_ty, ptr_ty), tcx),
+                )),
+            );
+
+            place.local = ptr_local;
+
+            self.patch.add_statement(
+                Location { block: location.block, statement_index: location.statement_index + 1 },
+                StatementKind::StorageDead(ptr_local),
+            );
+        }
+
+        self.super_place(place, context, location);
+    }
+}
+
+pub struct ElaborateBoxDerefs;
+
+impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+        if let Some(def_id) = tcx.lang_items().owned_box() {
+            let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[0].did;
+
+            let Some(nonnull_def) = tcx.type_of(unique_did).ty_adt_def() else {
+                span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique")
+            };
+
+            let nonnull_did = nonnull_def.non_enum_variant().fields[0].did;
+
+            let patch = MirPatch::new(body);
+
+            let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
+
+            let mut visitor =
+                ElaborateBoxDerefVisitor { tcx, unique_did, nonnull_did, local_decls, patch };
+
+            for (block, BasicBlockData { statements, terminator, .. }) in
+                basic_blocks.iter_enumerated_mut()
+            {
+                let mut index = 0;
+                for statement in statements {
+                    let location = Location { block, statement_index: index };
+                    visitor.visit_statement(statement, location);
+                    index += 1;
+                }
+
+                if let Some(terminator) = terminator
+                && !matches!(terminator.kind, TerminatorKind::Yield{..})
+                {
+                    let location = Location { block, statement_index: index };
+                    visitor.visit_terminator(terminator, location);
+                }
+
+                let location = Location { block, statement_index: index };
+                match terminator {
+                    // yielding into a box is handled when lowering generators
+                    Some(Terminator { kind: TerminatorKind::Yield { value, .. }, .. }) => {
+                        visitor.visit_operand(value, location);
+                    }
+                    Some(terminator) => {
+                        visitor.visit_terminator(terminator, location);
+                    }
+                    None => {}
+                }
+            }
+
+            visitor.patch.apply(body);
+
+            for debug_info in body.var_debug_info.iter_mut() {
+                if let VarDebugInfoContents::Place(place) = &mut debug_info.value {
+                    let mut new_projections: Option<Vec<_>> = None;
+                    let mut last_deref = 0;
+
+                    for (i, (base, elem)) in place.iter_projections().enumerate() {
+                        let base_ty = base.ty(&body.local_decls, tcx).ty;
+
+                        if elem == PlaceElem::Deref && base_ty.is_box() {
+                            let new_projections = new_projections.get_or_insert_default();
+
+                            let (unique_ty, nonnull_ty, ptr_ty) =
+                                build_ptr_tys(tcx, base_ty.boxed_ty(), unique_did, nonnull_did);
+
+                            new_projections.extend_from_slice(&base.projection[last_deref..]);
+                            new_projections.extend_from_slice(&build_projection(
+                                unique_ty, nonnull_ty, ptr_ty,
+                            ));
+                            new_projections.push(PlaceElem::Deref);
+
+                            last_deref = i;
+                        }
+                    }
+
+                    if let Some(mut new_projections) = new_projections {
+                        new_projections.extend_from_slice(&place.projection[last_deref..]);
+                        place.projection = tcx.intern_place_elems(&new_projections);
+                    }
+                }
+            }
+        } else {
+            // box is not present, this pass doesn't need to do anything
+        }
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 7f0d3b0a612..9078b8a1cb7 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -56,7 +56,7 @@ use crate::MirPass;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::lang_items::LangItem;
-use rustc_index::bit_set::{BitMatrix, BitSet};
+use rustc_index::bit_set::{BitMatrix, BitSet, GrowableBitSet};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_middle::mir::dump_mir;
 use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
@@ -195,6 +195,11 @@ const RETURNED: usize = GeneratorSubsts::RETURNED;
 /// Generator has panicked and is poisoned.
 const POISONED: usize = GeneratorSubsts::POISONED;
 
+/// Number of variants to reserve in generator state. Corresponds to
+/// `UNRESUMED` (beginning of a generator) and `RETURNED`/`POISONED`
+/// (end of a generator) states.
+const RESERVED_VARIANTS: usize = 3;
+
 /// A `yield` point in the generator.
 struct SuspensionPoint<'tcx> {
     /// State discriminant used when suspending or resuming at this point.
@@ -206,7 +211,7 @@ struct SuspensionPoint<'tcx> {
     /// Which block to jump to if the generator is dropped in this state.
     drop: Option<BasicBlock>,
     /// Set of locals that have live storage while at this suspension point.
-    storage_liveness: BitSet<Local>,
+    storage_liveness: GrowableBitSet<Local>,
 }
 
 struct TransformVisitor<'tcx> {
@@ -345,7 +350,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
             data.statements.extend(self.make_state(state_idx, v, source_info));
             let state = if let Some((resume, mut resume_arg)) = resume {
                 // Yield
-                let state = 3 + self.suspension_points.len();
+                let state = RESERVED_VARIANTS + self.suspension_points.len();
 
                 // The resume arg target location might itself be remapped if its base local is
                 // live across a yield.
@@ -362,7 +367,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
                     resume,
                     resume_arg,
                     drop,
-                    storage_liveness: self.storage_liveness[block].clone().unwrap(),
+                    storage_liveness: self.storage_liveness[block].clone().unwrap().into(),
                 });
 
                 VariantIdx::new(state)
@@ -792,7 +797,6 @@ fn compute_layout<'tcx>(
     // Leave empty variants for the UNRESUMED, RETURNED, and POISONED states.
     // In debuginfo, these will correspond to the beginning (UNRESUMED) or end
     // (RETURNED, POISONED) of the function.
-    const RESERVED_VARIANTS: usize = 3;
     let body_span = body.source_scopes[OUTERMOST_SOURCE_SCOPE].span;
     let mut variant_source_info: IndexVec<VariantIdx, SourceInfo> = [
         SourceInfo::outermost(body_span.shrink_to_lo()),
@@ -1178,6 +1182,8 @@ fn create_cases<'tcx>(
     transform: &TransformVisitor<'tcx>,
     operation: Operation,
 ) -> Vec<(usize, BasicBlock)> {
+    let tcx = transform.tcx;
+
     let source_info = SourceInfo::outermost(body.span);
 
     transform
@@ -1210,13 +1216,85 @@ fn create_cases<'tcx>(
                 if operation == Operation::Resume {
                     // Move the resume argument to the destination place of the `Yield` terminator
                     let resume_arg = Local::new(2); // 0 = return, 1 = self
-                    statements.push(Statement {
-                        source_info,
-                        kind: StatementKind::Assign(Box::new((
-                            point.resume_arg,
-                            Rvalue::Use(Operand::Move(resume_arg.into())),
-                        ))),
-                    });
+
+                    // handle `box yield` properly
+                    let box_place = if let [projection @ .., ProjectionElem::Deref] =
+                        &**point.resume_arg.projection
+                    {
+                        let box_place =
+                            Place::from(point.resume_arg.local).project_deeper(projection, tcx);
+
+                        let box_ty = box_place.ty(&body.local_decls, tcx).ty;
+
+                        if box_ty.is_box() { Some((box_place, box_ty)) } else { None }
+                    } else {
+                        None
+                    };
+
+                    if let Some((box_place, box_ty)) = box_place {
+                        let unique_did = box_ty
+                            .ty_adt_def()
+                            .expect("expected Box to be an Adt")
+                            .non_enum_variant()
+                            .fields[0]
+                            .did;
+
+                        let Some(nonnull_def) = tcx.type_of(unique_did).ty_adt_def() else {
+                            span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique")
+                        };
+
+                        let nonnull_did = nonnull_def.non_enum_variant().fields[0].did;
+
+                        let (unique_ty, nonnull_ty, ptr_ty) =
+                            crate::elaborate_box_derefs::build_ptr_tys(
+                                tcx,
+                                box_ty.boxed_ty(),
+                                unique_did,
+                                nonnull_did,
+                            );
+
+                        let ptr_local = body.local_decls.push(LocalDecl::new(ptr_ty, body.span));
+
+                        statements.push(Statement {
+                            source_info,
+                            kind: StatementKind::StorageLive(ptr_local),
+                        });
+
+                        statements.push(Statement {
+                            source_info,
+                            kind: StatementKind::Assign(Box::new((
+                                Place::from(ptr_local),
+                                Rvalue::Use(Operand::Copy(box_place.project_deeper(
+                                    &crate::elaborate_box_derefs::build_projection(
+                                        unique_ty, nonnull_ty, ptr_ty,
+                                    ),
+                                    tcx,
+                                ))),
+                            ))),
+                        });
+
+                        statements.push(Statement {
+                            source_info,
+                            kind: StatementKind::Assign(Box::new((
+                                Place::from(ptr_local)
+                                    .project_deeper(&[ProjectionElem::Deref], tcx),
+                                Rvalue::Use(Operand::Move(resume_arg.into())),
+                            ))),
+                        });
+
+                        statements.push(Statement {
+                            source_info,
+                            kind: StatementKind::StorageDead(ptr_local),
+                        });
+                    } else {
+                        statements.push(Statement {
+                            source_info,
+                            kind: StatementKind::Assign(Box::new((
+                                point.resume_arg,
+                                Rvalue::Use(Operand::Move(resume_arg.into())),
+                            ))),
+                        });
+                    }
                 }
 
                 // Then jump to the real target
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index b8932251465..b7caa61ef07 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -57,6 +57,7 @@ mod deref_separator;
 mod dest_prop;
 pub mod dump_mir;
 mod early_otherwise_branch;
+mod elaborate_box_derefs;
 mod elaborate_drops;
 mod function_item_references;
 mod generator;
@@ -427,6 +428,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
         // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
         // but before optimizations begin.
         &deref_separator::Derefer,
+        &elaborate_box_derefs::ElaborateBoxDerefs,
         &add_retag::AddRetag,
         &lower_intrinsics::LowerIntrinsics,
         &simplify::SimplifyCfg::new("elaborate-drops"),
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index acf892cec53..ba325d70422 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -1355,7 +1355,10 @@ impl<'a> Parser<'a> {
                     s.print_mutability(mut_ty.mutbl, false);
                     s.popen();
                     s.print_type(&mut_ty.ty);
-                    s.print_type_bounds(" +", &bounds);
+                    if !bounds.is_empty() {
+                        s.word(" + ");
+                        s.print_type_bounds(&bounds);
+                    }
                     s.pclose()
                 });
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 4ef0f590a1f..536d45b2399 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -4,8 +4,7 @@
 //! conflicts between multiple such attributes attached to the same
 //! item.
 
-use rustc_ast::tokenstream::DelimSpan;
-use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MacArgs, MetaItemKind, NestedMetaItem};
+use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
 use rustc_expand::base::resolve_path;
@@ -899,68 +898,6 @@ impl CheckAttrVisitor<'_> {
         }
     }
 
-    /// Checks `#[doc(hidden)]` attributes. Returns `true` if valid.
-    fn check_doc_hidden(
-        &self,
-        attr: &Attribute,
-        meta_index: usize,
-        meta: &NestedMetaItem,
-        hir_id: HirId,
-        target: Target,
-    ) -> bool {
-        if let Target::AssocConst
-        | Target::AssocTy
-        | Target::Method(MethodKind::Trait { body: true }) = target
-        {
-            let parent_hir_id = self.tcx.hir().get_parent_item(hir_id);
-            let containing_item = self.tcx.hir().expect_item(parent_hir_id);
-
-            if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = containing_item.kind {
-                let meta_items = attr.meta_item_list().unwrap();
-
-                let (span, replacement_span) = if meta_items.len() == 1 {
-                    (attr.span, attr.span)
-                } else {
-                    let meta_span = meta.span();
-                    (
-                        meta_span,
-                        meta_span.until(match meta_items.get(meta_index + 1) {
-                            Some(next_item) => next_item.span(),
-                            None => match attr.get_normal_item().args {
-                                MacArgs::Delimited(DelimSpan { close, .. }, ..) => close,
-                                _ => unreachable!(),
-                            },
-                        }),
-                    )
-                };
-
-                // FIXME: #[doc(hidden)] was previously erroneously allowed on trait impl items,
-                // so for backward compatibility only emit a warning and do not mark it as invalid.
-                self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, span, |lint| {
-                    lint.build("`#[doc(hidden)]` is ignored on trait impl items")
-                        .warn(
-                            "this was previously accepted by the compiler but is \
-                             being phased out; it will become a hard error in \
-                             a future release!",
-                        )
-                        .note(
-                            "whether the impl item is `doc(hidden)` or not \
-                             entirely depends on the corresponding trait item",
-                        )
-                        .span_suggestion(
-                            replacement_span,
-                            "remove this attribute",
-                            "",
-                            Applicability::MachineApplicable,
-                        )
-                        .emit();
-                });
-            }
-        }
-
-        true
-    }
-
     /// Checks that an attribute is *not* used at the crate level. Returns `true` if valid.
     fn check_attr_not_crate_level(
         &self,
@@ -1079,7 +1016,7 @@ impl CheckAttrVisitor<'_> {
         let mut is_valid = true;
 
         if let Some(mi) = attr.meta() && let Some(list) = mi.meta_item_list() {
-            for (meta_index, meta) in list.into_iter().enumerate() {
+            for meta in list {
                 if let Some(i_meta) = meta.meta_item() {
                     match i_meta.name_or_empty() {
                         sym::alias
@@ -1127,15 +1064,6 @@ impl CheckAttrVisitor<'_> {
                             is_valid = false;
                         }
 
-                        sym::hidden if !self.check_doc_hidden(attr,
-                            meta_index,
-                            meta,
-                            hir_id,
-                            target,
-                            ) => {
-                            is_valid = false;
-                        }
-
                         // no_default_passes: deprecated
                         // passes: deprecated
                         // plugins: removed, but rustdoc warns about it itself
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index e7c8886f054..86dbcba6c0d 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1914,6 +1914,8 @@ impl<'a> Resolver<'a> {
                 };
             }
             (msg, None)
+        } else if ident.name == kw::SelfUpper {
+            ("`Self` is only available in impls, traits, and type definitions".to_string(), None)
         } else if ident.name.as_str().chars().next().map_or(false, |c| c.is_ascii_uppercase()) {
             // Check whether the name refers to an item in the value namespace.
             let binding = if let Some(ribs) = ribs {
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 1a99bff610a..7d2b7de17bf 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -332,6 +332,16 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                 span,
                 "`Self` is only available in impls, traits, and type definitions".to_string(),
             );
+            if let Some(item_kind) = self.diagnostic_metadata.current_item {
+                err.span_label(
+                    item_kind.ident.span,
+                    format!(
+                        "`Self` not allowed in {} {}",
+                        item_kind.kind.article(),
+                        item_kind.kind.descr()
+                    ),
+                );
+            }
             return (err, Vec::new());
         }
         if is_self_value(path, ns) {
@@ -389,6 +399,15 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                         );
                     }
                 }
+            } else if let Some(item_kind) = self.diagnostic_metadata.current_item {
+                err.span_label(
+                    item_kind.ident.span,
+                    format!(
+                        "`self` not allowed in {} {}",
+                        item_kind.kind.article(),
+                        item_kind.kind.descr()
+                    ),
+                );
             }
             return (err, Vec::new());
         }
@@ -1788,7 +1807,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         path: &[Segment],
     ) -> Option<(Span, &'static str, String, Applicability)> {
         let (ident, span) = match path {
-            [segment] if !segment.has_generic_args => {
+            [segment] if !segment.has_generic_args && segment.ident.name != kw::SelfUpper => {
                 (segment.ident.to_string(), segment.ident.span)
             }
             _ => return None,
@@ -1875,7 +1894,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         let names = rib
             .bindings
             .iter()
-            .filter(|(id, _)| id.span.ctxt() == label.span.ctxt())
+            .filter(|(id, _)| id.span.eq_ctxt(label.span))
             .map(|(id, _)| id.name)
             .collect::<Vec<Symbol>>();
 
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 447f4174c10..55574b83607 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -846,8 +846,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 //                                      the opaque_ty generics
                 let opaque_ty = self.tcx.hir().item(item_id);
                 let (generics, bounds) = match opaque_ty.kind {
-                    // Named opaque `impl Trait` types are reached via `TyKind::Path`.
-                    // This arm is for `impl Trait` in the types of statics, constants and locals.
                     hir::ItemKind::OpaqueTy(hir::OpaqueTy {
                         origin: hir::OpaqueTyOrigin::TyAlias,
                         ..
@@ -866,7 +864,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
 
                         return;
                     }
-                    // RPIT (return position impl trait)
                     hir::ItemKind::OpaqueTy(hir::OpaqueTy {
                         origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..),
                         ref generics,
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 89d724626cc..14ad1a42a7d 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1102,41 +1102,96 @@ impl CrateCheckConfig {
             .extend(atomic_values);
 
         // Target specific values
-        for target in
-            TARGETS.iter().map(|target| Target::expect_builtin(&TargetTriple::from_triple(target)))
+        #[cfg(bootstrap)]
         {
-            self.values_valid
-                .entry(sym::target_os)
-                .or_default()
-                .insert(Symbol::intern(&target.options.os));
-            self.values_valid
-                .entry(sym::target_family)
-                .or_default()
-                .extend(target.options.families.iter().map(|family| Symbol::intern(family)));
-            self.values_valid
-                .entry(sym::target_arch)
-                .or_default()
-                .insert(Symbol::intern(&target.arch));
-            self.values_valid
-                .entry(sym::target_endian)
-                .or_default()
-                .insert(Symbol::intern(&target.options.endian.as_str()));
-            self.values_valid
-                .entry(sym::target_env)
-                .or_default()
-                .insert(Symbol::intern(&target.options.env));
-            self.values_valid
-                .entry(sym::target_abi)
-                .or_default()
-                .insert(Symbol::intern(&target.options.abi));
-            self.values_valid
-                .entry(sym::target_vendor)
-                .or_default()
-                .insert(Symbol::intern(&target.options.vendor));
-            self.values_valid
-                .entry(sym::target_pointer_width)
-                .or_default()
-                .insert(sym::integer(target.pointer_width));
+            for target in TARGETS
+                .iter()
+                .map(|target| Target::expect_builtin(&TargetTriple::from_triple(target)))
+            {
+                self.values_valid
+                    .entry(sym::target_os)
+                    .or_default()
+                    .insert(Symbol::intern(&target.options.os));
+                self.values_valid
+                    .entry(sym::target_family)
+                    .or_default()
+                    .extend(target.options.families.iter().map(|family| Symbol::intern(family)));
+                self.values_valid
+                    .entry(sym::target_arch)
+                    .or_default()
+                    .insert(Symbol::intern(&target.arch));
+                self.values_valid
+                    .entry(sym::target_endian)
+                    .or_default()
+                    .insert(Symbol::intern(&target.options.endian.as_str()));
+                self.values_valid
+                    .entry(sym::target_env)
+                    .or_default()
+                    .insert(Symbol::intern(&target.options.env));
+                self.values_valid
+                    .entry(sym::target_abi)
+                    .or_default()
+                    .insert(Symbol::intern(&target.options.abi));
+                self.values_valid
+                    .entry(sym::target_vendor)
+                    .or_default()
+                    .insert(Symbol::intern(&target.options.vendor));
+                self.values_valid
+                    .entry(sym::target_pointer_width)
+                    .or_default()
+                    .insert(sym::integer(target.pointer_width));
+            }
+        }
+
+        // Target specific values
+        #[cfg(not(bootstrap))]
+        {
+            const VALUES: [&Symbol; 8] = [
+                &sym::target_os,
+                &sym::target_family,
+                &sym::target_arch,
+                &sym::target_endian,
+                &sym::target_env,
+                &sym::target_abi,
+                &sym::target_vendor,
+                &sym::target_pointer_width,
+            ];
+
+            // Initialize (if not already initialized)
+            for &e in VALUES {
+                self.values_valid.entry(e).or_default();
+            }
+
+            // Get all values map at once otherwise it would be costly.
+            // (8 values * 220 targets ~= 1760 times, at the time of writing this comment).
+            let [
+                values_target_os,
+                values_target_family,
+                values_target_arch,
+                values_target_endian,
+                values_target_env,
+                values_target_abi,
+                values_target_vendor,
+                values_target_pointer_width,
+            ] = self
+                .values_valid
+                .get_many_mut(VALUES)
+                .expect("unable to get all the check-cfg values buckets");
+
+            for target in TARGETS
+                .iter()
+                .map(|target| Target::expect_builtin(&TargetTriple::from_triple(target)))
+            {
+                values_target_os.insert(Symbol::intern(&target.options.os));
+                values_target_family
+                    .extend(target.options.families.iter().map(|family| Symbol::intern(family)));
+                values_target_arch.insert(Symbol::intern(&target.arch));
+                values_target_endian.insert(Symbol::intern(&target.options.endian.as_str()));
+                values_target_env.insert(Symbol::intern(&target.options.env));
+                values_target_abi.insert(Symbol::intern(&target.options.abi));
+                values_target_vendor.insert(Symbol::intern(&target.options.vendor));
+                values_target_pointer_width.insert(sym::integer(target.pointer_width));
+            }
         }
     }
 
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 044be906b55..35b55981e37 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -6,6 +6,7 @@
 #![feature(once_cell)]
 #![feature(option_get_or_insert_default)]
 #![feature(rustc_attrs)]
+#![cfg_attr(not(bootstrap), feature(map_many_mut))]
 #![recursion_limit = "256"]
 #![allow(rustc::potential_query_instability)]
 
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 5d3d56b1e66..a329fa15320 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -537,6 +537,9 @@ impl Span {
     pub fn ctxt(self) -> SyntaxContext {
         self.data_untracked().ctxt
     }
+    pub fn eq_ctxt(self, other: Span) -> bool {
+        self.data_untracked().ctxt == other.data_untracked().ctxt
+    }
     #[inline]
     pub fn with_ctxt(self, ctxt: SyntaxContext) -> Span {
         self.data_untracked().with_ctxt(ctxt)
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 6daf811e26f..8a6941a4516 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -131,6 +131,7 @@ symbols! {
         Arc,
         Argument,
         ArgumentV1,
+        ArgumentV1Methods,
         Arguments,
         AsMut,
         AsRef,
@@ -1641,7 +1642,7 @@ impl Ident {
 
 impl PartialEq for Ident {
     fn eq(&self, rhs: &Self) -> bool {
-        self.name == rhs.name && self.span.ctxt() == rhs.span.ctxt()
+        self.name == rhs.name && self.span.eq_ctxt(rhs.span)
     }
 }
 
diff --git a/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs
index a90c7b7bc6f..269bf8b8bcd 100644
--- a/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs
+++ b/compiler/rustc_target/src/spec/asmjs_unknown_emscripten.rs
@@ -2,10 +2,10 @@ use super::{wasm32_unknown_emscripten, LinkerFlavor, Target};
 
 pub fn target() -> Target {
     let mut target = wasm32_unknown_emscripten::target();
-    target
-        .post_link_args
-        .entry(LinkerFlavor::Em)
-        .or_default()
-        .extend(vec!["-s".into(), "WASM=0".into()]);
+    target.post_link_args.entry(LinkerFlavor::Em).or_default().extend(vec![
+        "-sWASM=0".into(),
+        "--memory-init-file".into(),
+        "0".into(),
+    ]);
     target
 }
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 422af667875..fd0c3f36e72 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -39,11 +39,13 @@ use crate::json::{Json, ToJson};
 use crate::spec::abi::{lookup as lookup_abi, Abi};
 use crate::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_span::symbol::{sym, Symbol};
 use serde_json::Value;
 use std::borrow::Cow;
 use std::collections::BTreeMap;
 use std::convert::TryFrom;
+use std::hash::{Hash, Hasher};
 use std::iter::FromIterator;
 use std::ops::{Deref, DerefMut};
 use std::path::{Path, PathBuf};
@@ -2183,7 +2185,7 @@ impl Target {
             TargetTriple::TargetTriple(ref target_triple) => {
                 load_builtin(target_triple).expect("built-in target")
             }
-            TargetTriple::TargetPath(..) => {
+            TargetTriple::TargetJson { .. } => {
                 panic!("built-in targets doens't support target-paths")
             }
         }
@@ -2248,11 +2250,9 @@ impl Target {
 
                 Err(format!("Could not find specification for target {:?}", target_triple))
             }
-            TargetTriple::TargetPath(ref target_path) => {
-                if target_path.is_file() {
-                    return load_file(&target_path);
-                }
-                Err(format!("Target path {:?} is not a valid file", target_path))
+            TargetTriple::TargetJson { ref contents, .. } => {
+                let obj = serde_json::from_str(contents).map_err(|e| e.to_string())?;
+                Target::from_json(obj)
             }
         }
     }
@@ -2421,10 +2421,77 @@ impl ToJson for Target {
 }
 
 /// Either a target triple string or a path to a JSON file.
-#[derive(PartialEq, Clone, Debug, Hash, Encodable, Decodable)]
+#[derive(Clone, Debug)]
 pub enum TargetTriple {
     TargetTriple(String),
-    TargetPath(PathBuf),
+    TargetJson {
+        /// Warning: This field may only be used by rustdoc. Using it anywhere else will lead to
+        /// inconsistencies as it is discarded during serialization.
+        path_for_rustdoc: PathBuf,
+        triple: String,
+        contents: String,
+    },
+}
+
+// Use a manual implementation to ignore the path field
+impl PartialEq for TargetTriple {
+    fn eq(&self, other: &Self) -> bool {
+        match (self, other) {
+            (Self::TargetTriple(l0), Self::TargetTriple(r0)) => l0 == r0,
+            (
+                Self::TargetJson { path_for_rustdoc: _, triple: l_triple, contents: l_contents },
+                Self::TargetJson { path_for_rustdoc: _, triple: r_triple, contents: r_contents },
+            ) => l_triple == r_triple && l_contents == r_contents,
+            _ => false,
+        }
+    }
+}
+
+// Use a manual implementation to ignore the path field
+impl Hash for TargetTriple {
+    fn hash<H: Hasher>(&self, state: &mut H) -> () {
+        match self {
+            TargetTriple::TargetTriple(triple) => {
+                0u8.hash(state);
+                triple.hash(state)
+            }
+            TargetTriple::TargetJson { path_for_rustdoc: _, triple, contents } => {
+                1u8.hash(state);
+                triple.hash(state);
+                contents.hash(state)
+            }
+        }
+    }
+}
+
+// Use a manual implementation to prevent encoding the target json file path in the crate metadata
+impl<S: Encoder> Encodable<S> for TargetTriple {
+    fn encode(&self, s: &mut S) {
+        match self {
+            TargetTriple::TargetTriple(triple) => s.emit_enum_variant(0, |s| s.emit_str(triple)),
+            TargetTriple::TargetJson { path_for_rustdoc: _, triple, contents } => s
+                .emit_enum_variant(1, |s| {
+                    s.emit_str(triple);
+                    s.emit_str(contents)
+                }),
+        }
+    }
+}
+
+impl<D: Decoder> Decodable<D> for TargetTriple {
+    fn decode(d: &mut D) -> Self {
+        match d.read_usize() {
+            0 => TargetTriple::TargetTriple(d.read_str().to_owned()),
+            1 => TargetTriple::TargetJson {
+                path_for_rustdoc: PathBuf::new(),
+                triple: d.read_str().to_owned(),
+                contents: d.read_str().to_owned(),
+            },
+            _ => {
+                panic!("invalid enum variant tag while decoding `TargetTriple`, expected 0..2");
+            }
+        }
+    }
 }
 
 impl TargetTriple {
@@ -2436,7 +2503,19 @@ impl TargetTriple {
     /// Creates a target triple from the passed target path.
     pub fn from_path(path: &Path) -> Result<Self, io::Error> {
         let canonicalized_path = path.canonicalize()?;
-        Ok(TargetTriple::TargetPath(canonicalized_path))
+        let contents = std::fs::read_to_string(&canonicalized_path).map_err(|err| {
+            io::Error::new(
+                io::ErrorKind::InvalidInput,
+                format!("target path {:?} is not a valid file: {}", canonicalized_path, err),
+            )
+        })?;
+        let triple = canonicalized_path
+            .file_stem()
+            .expect("target path must not be empty")
+            .to_str()
+            .expect("target path must be valid unicode")
+            .to_owned();
+        Ok(TargetTriple::TargetJson { path_for_rustdoc: canonicalized_path, triple, contents })
     }
 
     /// Returns a string triple for this target.
@@ -2444,12 +2523,8 @@ impl TargetTriple {
     /// If this target is a path, the file name (without extension) is returned.
     pub fn triple(&self) -> &str {
         match *self {
-            TargetTriple::TargetTriple(ref triple) => triple,
-            TargetTriple::TargetPath(ref path) => path
-                .file_stem()
-                .expect("target path must not be empty")
-                .to_str()
-                .expect("target path must be valid unicode"),
+            TargetTriple::TargetTriple(ref triple)
+            | TargetTriple::TargetJson { ref triple, .. } => triple,
         }
     }
 
@@ -2459,16 +2534,15 @@ impl TargetTriple {
     /// by `triple()`.
     pub fn debug_triple(&self) -> String {
         use std::collections::hash_map::DefaultHasher;
-        use std::hash::{Hash, Hasher};
-
-        let triple = self.triple();
-        if let TargetTriple::TargetPath(ref path) = *self {
-            let mut hasher = DefaultHasher::new();
-            path.hash(&mut hasher);
-            let hash = hasher.finish();
-            format!("{}-{}", triple, hash)
-        } else {
-            triple.into()
+
+        match self {
+            TargetTriple::TargetTriple(triple) => triple.to_owned(),
+            TargetTriple::TargetJson { path_for_rustdoc: _, triple, contents: content } => {
+                let mut hasher = DefaultHasher::new();
+                content.hash(&mut hasher);
+                let hash = hasher.finish();
+                format!("{}-{}", triple, hash)
+            }
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index e4da6172916..44ff3fd7306 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -1,4 +1,4 @@
-//! This crates defines the trait resolution method.
+//! This crate defines the trait resolution method.
 //!
 //! - **Traits.** Trait resolution is implemented in the `traits` module.
 //!
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 2f999f5ffad..af0803fbd54 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -259,7 +259,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         let cycle = self.resolve_vars_if_possible(cycle.to_owned());
         assert!(!cycle.is_empty());
 
-        debug!("report_overflow_error_cycle: cycle={:?}", cycle);
+        debug!(?cycle, "report_overflow_error_cycle");
 
         // The 'deepest' obligation is most likely to have a useful
         // cause 'backtrace'
@@ -1513,6 +1513,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip_all)]
     fn report_projection_error(
         &self,
         obligation: &PredicateObligation<'tcx>,
@@ -1551,15 +1552,9 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                     &mut obligations,
                 );
 
-                debug!(
-                    "report_projection_error obligation.cause={:?} obligation.param_env={:?}",
-                    obligation.cause, obligation.param_env
-                );
+                debug!(?obligation.cause, ?obligation.param_env);
 
-                debug!(
-                    "report_projection_error normalized_ty={:?} data.ty={:?}",
-                    normalized_ty, data.term,
-                );
+                debug!(?normalized_ty, data.ty = ?data.term);
 
                 let is_normalized_ty_expected = !matches!(
                     obligation.cause.code().peel_derives(),
@@ -2346,6 +2341,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip_all)]
     fn suggest_unsized_bound_if_applicable(
         &self,
         err: &mut Diagnostic,
@@ -2360,10 +2356,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
         )  else {
             return;
         };
-        debug!(
-            "suggest_unsized_bound_if_applicable: pred={:?} item_def_id={:?} span={:?}",
-            pred, item_def_id, span
-        );
+        debug!(?pred, ?item_def_id, ?span);
 
         let (Some(node), true) = (
             self.tcx.hir().get_if_local(item_def_id),
@@ -2374,6 +2367,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
         self.maybe_suggest_unsized_generics(err, span, node);
     }
 
+    #[instrument(level = "debug", skip_all)]
     fn maybe_suggest_unsized_generics<'hir>(
         &self,
         err: &mut Diagnostic,
@@ -2384,8 +2378,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
             return;
         };
         let sized_trait = self.tcx.lang_items().sized_trait();
-        debug!("maybe_suggest_unsized_generics: generics.params={:?}", generics.params);
-        debug!("maybe_suggest_unsized_generics: generics.predicates={:?}", generics.predicates);
+        debug!(?generics.params);
+        debug!(?generics.predicates);
         let Some(param) = generics.params.iter().find(|param| param.span == span) else {
             return;
         };
@@ -2399,7 +2393,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
         if explicitly_sized {
             return;
         }
-        debug!("maybe_suggest_unsized_generics: param={:?}", param);
+        debug!(?param);
         match node {
             hir::Node::Item(
                 item @ hir::Item {
@@ -2517,7 +2511,7 @@ impl<'v> Visitor<'v> for FindTypeParam {
                 if path.segments.len() == 1 && path.segments[0].ident.name == self.param =>
             {
                 if !self.nested {
-                    debug!("FindTypeParam::visit_ty: ty={:?}", ty);
+                    debug!(?ty, "FindTypeParam::visit_ty");
                     self.invalid_spans.push(ty.span);
                 }
             }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 09b73b982a0..d8003efba87 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1628,16 +1628,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
     /// ```
     ///
     /// Returns `true` if an async-await specific note was added to the diagnostic.
+    #[instrument(level = "debug", skip_all, fields(?obligation.predicate, ?obligation.cause.span))]
     fn maybe_note_obligation_cause_for_async_await(
         &self,
         err: &mut Diagnostic,
         obligation: &PredicateObligation<'tcx>,
     ) -> bool {
-        debug!(
-            "maybe_note_obligation_cause_for_async_await: obligation.predicate={:?} \
-                obligation.cause.span={:?}",
-            obligation.predicate, obligation.cause.span
-        );
         let hir = self.tcx.hir();
 
         // Attempt to detect an async-await error by looking at the obligation causes, looking
@@ -1677,7 +1673,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         let mut seen_upvar_tys_infer_tuple = false;
 
         while let Some(code) = next_code {
-            debug!("maybe_note_obligation_cause_for_async_await: code={:?}", code);
+            debug!(?code);
             match code {
                 ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => {
                     next_code = Some(parent_code);
@@ -1685,10 +1681,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 ObligationCauseCode::ImplDerivedObligation(cause) => {
                     let ty = cause.derived.parent_trait_pred.skip_binder().self_ty();
                     debug!(
-                        "maybe_note_obligation_cause_for_async_await: ImplDerived \
-                         parent_trait_ref={:?} self_ty.kind={:?}",
-                        cause.derived.parent_trait_pred,
-                        ty.kind()
+                        parent_trait_ref = ?cause.derived.parent_trait_pred,
+                        self_ty.kind = ?ty.kind(),
+                        "ImplDerived",
                     );
 
                     match *ty.kind() {
@@ -1717,10 +1712,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 | ObligationCauseCode::BuiltinDerivedObligation(derived_obligation) => {
                     let ty = derived_obligation.parent_trait_pred.skip_binder().self_ty();
                     debug!(
-                        "maybe_note_obligation_cause_for_async_await: \
-                         parent_trait_ref={:?} self_ty.kind={:?}",
-                        derived_obligation.parent_trait_pred,
-                        ty.kind()
+                        parent_trait_ref = ?derived_obligation.parent_trait_pred,
+                        self_ty.kind = ?ty.kind(),
                     );
 
                     match *ty.kind() {
@@ -1750,7 +1743,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         }
 
         // Only continue if a generator was found.
-        debug!(?generator, ?trait_ref, ?target_ty, "maybe_note_obligation_cause_for_async_await");
+        debug!(?generator, ?trait_ref, ?target_ty);
         let (Some(generator_did), Some(trait_ref), Some(target_ty)) = (generator, trait_ref, target_ty) else {
             return false;
         };
@@ -1760,12 +1753,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         let in_progress_typeck_results = self.in_progress_typeck_results.map(|t| t.borrow());
         let generator_did_root = self.tcx.typeck_root_def_id(generator_did);
         debug!(
-            "maybe_note_obligation_cause_for_async_await: generator_did={:?} \
-             generator_did_root={:?} in_progress_typeck_results.hir_owner={:?} span={:?}",
-            generator_did,
-            generator_did_root,
-            in_progress_typeck_results.as_ref().map(|t| t.hir_owner),
-            span
+            ?generator_did,
+            ?generator_did_root,
+            in_progress_typeck_results.hir_owner = ?in_progress_typeck_results.as_ref().map(|t| t.hir_owner),
+            ?span,
         );
 
         let generator_body = generator_did
@@ -1788,7 +1779,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         if let Some(body) = generator_body {
             visitor.visit_body(body);
         }
-        debug!("maybe_note_obligation_cause_for_async_await: awaits = {:?}", visitor.awaits);
+        debug!(awaits = ?visitor.awaits);
 
         // Look for a type inside the generator interior that matches the target type to get
         // a span.
@@ -1809,11 +1800,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             let ty_erased = self.tcx.erase_late_bound_regions(ty);
             let ty_erased = self.tcx.erase_regions(ty_erased);
             let eq = ty_erased == target_ty_erased;
-            debug!(
-                "maybe_note_obligation_cause_for_async_await: ty_erased={:?} \
-                    target_ty_erased={:?} eq={:?}",
-                ty_erased, target_ty_erased, eq
-            );
+            debug!(?ty_erased, ?target_ty_erased, ?eq);
             eq
         };
 
@@ -1888,6 +1875,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
 
     /// Unconditionally adds the diagnostic note described in
     /// `maybe_note_obligation_cause_for_async_await`'s documentation comment.
+    #[instrument(level = "debug", skip_all)]
     fn note_obligation_cause_for_async_await(
         &self,
         err: &mut Diagnostic,
@@ -2037,8 +2025,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     } else {
                         // Look at the last interior type to get a span for the `.await`.
                         debug!(
-                            "note_obligation_cause_for_async_await generator_interior_types: {:#?}",
-                            typeck_results.as_ref().map(|t| &t.generator_interior_types)
+                            generator_interior_types = ?format_args!(
+                                "{:#?}", typeck_results.as_ref().map(|t| &t.generator_interior_types)
+                            ),
                         );
                         explain_yield(interior_span, yield_span, scope_span);
                     }
@@ -2073,7 +2062,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                             // bar(Foo(std::ptr::null())).await;
                             //     ^^^^^^^^^^^^^^^^^^^^^ raw-ptr `*T` created inside this struct ctor.
                             // ```
-                            debug!("parent_def_kind: {:?}", self.tcx.def_kind(parent_did));
+                            debug!(parent_def_kind = ?self.tcx.def_kind(parent_did));
                             let is_raw_borrow_inside_fn_like_call =
                                 match self.tcx.def_kind(parent_did) {
                                     DefKind::Fn | DefKind::Ctor(..) => target_ty.is_unsafe_ptr(),
@@ -2131,7 +2120,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
 
         // Add a note for the item obligation that remains - normally a note pointing to the
         // bound that introduced the obligation (e.g. `T: Send`).
-        debug!("note_obligation_cause_for_async_await: next_code={:?}", next_code);
+        debug!(?next_code);
         self.note_obligation_cause_code(
             err,
             &obligation.predicate,
@@ -2688,6 +2677,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         ));
     }
 
+    #[instrument(
+        level = "debug", skip(self, err), fields(trait_pred.self_ty = ?trait_pred.self_ty())
+    )]
     fn suggest_await_before_try(
         &self,
         err: &mut Diagnostic,
@@ -2695,13 +2687,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         trait_pred: ty::PolyTraitPredicate<'tcx>,
         span: Span,
     ) {
-        debug!(
-            "suggest_await_before_try: obligation={:?}, span={:?}, trait_pred={:?}, trait_pred_self_ty={:?}",
-            obligation,
-            span,
-            trait_pred,
-            trait_pred.self_ty()
-        );
         let body_hir_id = obligation.cause.body_id;
         let item_id = self.tcx.hir().get_parent_node(body_hir_id);
 
@@ -2739,14 +2724,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 );
 
                 debug!(
-                    "suggest_await_before_try: normalized_projection_type {:?}",
-                    self.resolve_vars_if_possible(projection_ty)
+                    normalized_projection_type = ?self.resolve_vars_if_possible(projection_ty)
                 );
                 let try_obligation = self.mk_trait_obligation_with_new_self_ty(
                     obligation.param_env,
                     trait_pred.map_bound(|trait_pred| (trait_pred, projection_ty.skip_binder())),
                 );
-                debug!("suggest_await_before_try: try_trait_obligation {:?}", try_obligation);
+                debug!(try_trait_obligation = ?try_obligation);
                 if self.predicate_may_hold(&try_obligation)
                     && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
                     && snippet.ends_with('?')
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 70d8fdae651..d61166437d7 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -133,27 +133,16 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
 
         let mut errors = Vec::new();
 
-        loop {
-            debug!("select: starting another iteration");
+        // Process pending obligations.
+        let outcome: Outcome<_, _> = self.predicates.process_obligations(&mut FulfillProcessor {
+            selcx,
+            register_region_obligations: self.register_region_obligations,
+        });
 
-            // Process pending obligations.
-            let outcome: Outcome<_, _> =
-                self.predicates.process_obligations(&mut FulfillProcessor {
-                    selcx,
-                    register_region_obligations: self.register_region_obligations,
-                });
-            debug!("select: outcome={:#?}", outcome);
+        // FIXME: if we kept the original cache key, we could mark projection
+        // obligations as complete for the projection cache here.
 
-            // FIXME: if we kept the original cache key, we could mark projection
-            // obligations as complete for the projection cache here.
-
-            errors.extend(outcome.errors.into_iter().map(to_fulfillment_error));
-
-            // If nothing new was added, no need to keep looping.
-            if outcome.stalled {
-                break;
-            }
-        }
+        errors.extend(outcome.errors.into_iter().map(to_fulfillment_error));
 
         debug!(
             "select({} predicates remaining, {} errors) done",
@@ -264,22 +253,16 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
     type Obligation = PendingPredicateObligation<'tcx>;
     type Error = FulfillmentErrorCode<'tcx>;
 
-    /// Processes a predicate obligation and returns either:
-    /// - `Changed(v)` if the predicate is true, presuming that `v` are also true
-    /// - `Unchanged` if we don't have enough info to be sure
-    /// - `Error(e)` if the predicate does not hold
+    /// Identifies whether a predicate obligation needs processing.
     ///
     /// This is always inlined, despite its size, because it has a single
     /// callsite and it is called *very* frequently.
     #[inline(always)]
-    fn process_obligation(
-        &mut self,
-        pending_obligation: &mut Self::Obligation,
-    ) -> ProcessResult<Self::Obligation, Self::Error> {
+    fn needs_process_obligation(&self, pending_obligation: &Self::Obligation) -> bool {
         // If we were stalled on some unresolved variables, first check whether
         // any of them have been resolved; if not, don't bother doing more work
         // yet.
-        let change = match pending_obligation.stalled_on.len() {
+        match pending_obligation.stalled_on.len() {
             // Match arms are in order of frequency, which matters because this
             // code is so hot. 1 and 0 dominate; 2+ is fairly rare.
             1 => {
@@ -302,42 +285,18 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
                     false
                 })()
             }
-        };
-
-        if !change {
-            debug!(
-                "process_predicate: pending obligation {:?} still stalled on {:?}",
-                self.selcx.infcx().resolve_vars_if_possible(pending_obligation.obligation.clone()),
-                pending_obligation.stalled_on
-            );
-            return ProcessResult::Unchanged;
-        }
-
-        self.process_changed_obligations(pending_obligation)
-    }
-
-    fn process_backedge<'c, I>(
-        &mut self,
-        cycle: I,
-        _marker: PhantomData<&'c PendingPredicateObligation<'tcx>>,
-    ) where
-        I: Clone + Iterator<Item = &'c PendingPredicateObligation<'tcx>>,
-    {
-        if self.selcx.coinductive_match(cycle.clone().map(|s| s.obligation.predicate)) {
-            debug!("process_child_obligations: coinductive match");
-        } else {
-            let cycle: Vec<_> = cycle.map(|c| c.obligation.clone()).collect();
-            self.selcx.infcx().report_overflow_error_cycle(&cycle);
         }
     }
-}
 
-impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
-    // The code calling this method is extremely hot and only rarely
-    // actually uses this, so move this part of the code
-    // out of that loop.
+    /// Processes a predicate obligation and returns either:
+    /// - `Changed(v)` if the predicate is true, presuming that `v` are also true
+    /// - `Unchanged` if we don't have enough info to be sure
+    /// - `Error(e)` if the predicate does not hold
+    ///
+    /// This is called much less often than `needs_process_obligation`, so we
+    /// never inline it.
     #[inline(never)]
-    fn process_changed_obligations(
+    fn process_obligation(
         &mut self,
         pending_obligation: &mut PendingPredicateObligation<'tcx>,
     ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
@@ -352,6 +311,8 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
                 self.selcx.infcx().resolve_vars_if_possible(obligation.predicate);
         }
 
+        let obligation = &pending_obligation.obligation;
+
         debug!(?obligation, ?obligation.cause, "process_obligation");
 
         let infcx = self.selcx.infcx();
@@ -668,6 +629,23 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
         }
     }
 
+    fn process_backedge<'c, I>(
+        &mut self,
+        cycle: I,
+        _marker: PhantomData<&'c PendingPredicateObligation<'tcx>>,
+    ) where
+        I: Clone + Iterator<Item = &'c PendingPredicateObligation<'tcx>>,
+    {
+        if self.selcx.coinductive_match(cycle.clone().map(|s| s.obligation.predicate)) {
+            debug!("process_child_obligations: coinductive match");
+        } else {
+            let cycle: Vec<_> = cycle.map(|c| c.obligation.clone()).collect();
+            self.selcx.infcx().report_overflow_error_cycle(&cycle);
+        }
+    }
+}
+
+impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
     #[instrument(level = "debug", skip(self, obligation, stalled_on))]
     fn process_trait_obligation(
         &mut self,
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index c8b4303e1e0..cfd50c1afb9 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -970,7 +970,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
                 if let Some(impl_def_id) = relevant_impl {
                     // Check that `impl Drop` is actually const, if there is a custom impl
-                    if self.tcx().impl_constness(impl_def_id) == hir::Constness::Const {
+                    if self.tcx().constness(impl_def_id) == hir::Constness::Const {
                         candidates.vec.push(ConstDestructCandidate(Some(impl_def_id)));
                     }
                 } else {
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index ee2c8da5a00..297fbfa1c32 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1119,8 +1119,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             if obligation.is_const() {
                 match candidate {
                     // const impl
-                    ImplCandidate(def_id)
-                        if tcx.impl_constness(def_id) == hir::Constness::Const => {}
+                    ImplCandidate(def_id) if tcx.constness(def_id) == hir::Constness::Const => {}
                     // const param
                     ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
                     // auto trait impl
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 6380001b57c..cb1602816ae 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -42,6 +42,12 @@ pub trait Interner {
     type DelaySpanBugEmitted: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
     type PredicateKind: Clone + Debug + Hash + PartialEq + Eq;
     type AllocId: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+
+    type EarlyBoundRegion: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type BoundRegion: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type FreeRegion: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type RegionVid: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
+    type PlaceholderRegion: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord;
 }
 
 pub trait InternAs<T: ?Sized, R> {
@@ -767,3 +773,85 @@ impl fmt::Display for InferTy {
         }
     }
 }
+
+rustc_index::newtype_index! {
+    /// "Universes" are used during type- and trait-checking in the
+    /// presence of `for<..>` binders to control what sets of names are
+    /// visible. Universes are arranged into a tree: the root universe
+    /// contains names that are always visible. Each child then adds a new
+    /// set of names that are visible, in addition to those of its parent.
+    /// We say that the child universe "extends" the parent universe with
+    /// new names.
+    ///
+    /// To make this more concrete, consider this program:
+    ///
+    /// ```ignore (illustrative)
+    /// struct Foo { }
+    /// fn bar<T>(x: T) {
+    ///   let y: for<'a> fn(&'a u8, Foo) = ...;
+    /// }
+    /// ```
+    ///
+    /// The struct name `Foo` is in the root universe U0. But the type
+    /// parameter `T`, introduced on `bar`, is in an extended universe U1
+    /// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside
+    /// of `bar`, we cannot name `T`. Then, within the type of `y`, the
+    /// region `'a` is in a universe U2 that extends U1, because we can
+    /// name it inside the fn type but not outside.
+    ///
+    /// Universes are used to do type- and trait-checking around these
+    /// "forall" binders (also called **universal quantification**). The
+    /// idea is that when, in the body of `bar`, we refer to `T` as a
+    /// type, we aren't referring to any type in particular, but rather a
+    /// kind of "fresh" type that is distinct from all other types we have
+    /// actually declared. This is called a **placeholder** type, and we
+    /// use universes to talk about this. In other words, a type name in
+    /// universe 0 always corresponds to some "ground" type that the user
+    /// declared, but a type name in a non-zero universe is a placeholder
+    /// type -- an idealized representative of "types in general" that we
+    /// use for checking generic functions.
+    pub struct UniverseIndex {
+        DEBUG_FORMAT = "U{}",
+    }
+}
+
+impl UniverseIndex {
+    pub const ROOT: UniverseIndex = UniverseIndex::from_u32(0);
+
+    /// Returns the "next" universe index in order -- this new index
+    /// is considered to extend all previous universes. This
+    /// corresponds to entering a `forall` quantifier. So, for
+    /// example, suppose we have this type in universe `U`:
+    ///
+    /// ```ignore (illustrative)
+    /// for<'a> fn(&'a u32)
+    /// ```
+    ///
+    /// Once we "enter" into this `for<'a>` quantifier, we are in a
+    /// new universe that extends `U` -- in this new universe, we can
+    /// name the region `'a`, but that region was not nameable from
+    /// `U` because it was not in scope there.
+    pub fn next_universe(self) -> UniverseIndex {
+        UniverseIndex::from_u32(self.private.checked_add(1).unwrap())
+    }
+
+    /// Returns `true` if `self` can name a name from `other` -- in other words,
+    /// if the set of names in `self` is a superset of those in
+    /// `other` (`self >= other`).
+    pub fn can_name(self, other: UniverseIndex) -> bool {
+        self.private >= other.private
+    }
+
+    /// Returns `true` if `self` cannot name some names from `other` -- in other
+    /// words, if the set of names in `self` is a strict subset of
+    /// those in `other` (`self < other`).
+    pub fn cannot_name(self, other: UniverseIndex) -> bool {
+        self.private < other.private
+    }
+}
+
+impl<CTX> HashStable<CTX> for UniverseIndex {
+    fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
+        self.private.hash_stable(ctx, hasher);
+    }
+}
diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs
index 94072184399..5cd2901324a 100644
--- a/compiler/rustc_type_ir/src/sty.rs
+++ b/compiler/rustc_type_ir/src/sty.rs
@@ -10,7 +10,9 @@ use crate::Interner;
 use crate::TyDecoder;
 use crate::TyEncoder;
 use crate::UintTy;
+use crate::UniverseIndex;
 
+use self::RegionKind::*;
 use self::TyKind::*;
 
 use rustc_data_structures::stable_hasher::HashStable;
@@ -20,8 +22,6 @@ use rustc_serialize::{Decodable, Decoder, Encodable};
 ///
 /// Types written by the user start out as `hir::TyKind` and get
 /// converted to this representation using `AstConv::ast_ty_to_ty`.
-///
-/// The `HashStable` implementation for this type is defined in `rustc_query_system::ich`.
 #[rustc_diagnostic_item = "IrTyKind"]
 pub enum TyKind<I: Interner> {
     /// The primitive boolean type. Written as `bool`.
@@ -202,7 +202,7 @@ impl<I: Interner> TyKind<I> {
 // This is manually implemented for `TyKind` because `std::mem::discriminant`
 // returns an opaque value that is `PartialEq` but not `PartialOrd`
 #[inline]
-const fn discriminant<I: Interner>(value: &TyKind<I>) -> usize {
+const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
     match value {
         Bool => 0,
         Char => 1,
@@ -273,8 +273,8 @@ impl<I: Interner> Clone for TyKind<I> {
 impl<I: Interner> PartialEq for TyKind<I> {
     #[inline]
     fn eq(&self, other: &TyKind<I>) -> bool {
-        let __self_vi = discriminant(self);
-        let __arg_1_vi = discriminant(other);
+        let __self_vi = tykind_discriminant(self);
+        let __arg_1_vi = tykind_discriminant(other);
         if __self_vi == __arg_1_vi {
             match (&*self, &*other) {
                 (&Int(ref __self_0), &Int(ref __arg_1_0)) => __self_0 == __arg_1_0,
@@ -345,8 +345,8 @@ impl<I: Interner> PartialOrd for TyKind<I> {
 impl<I: Interner> Ord for TyKind<I> {
     #[inline]
     fn cmp(&self, other: &TyKind<I>) -> Ordering {
-        let __self_vi = discriminant(self);
-        let __arg_1_vi = discriminant(other);
+        let __self_vi = tykind_discriminant(self);
+        let __arg_1_vi = tykind_discriminant(other);
         if __self_vi == __arg_1_vi {
             match (&*self, &*other) {
                 (&Int(ref __self_0), &Int(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
@@ -444,109 +444,109 @@ impl<I: Interner> hash::Hash for TyKind<I> {
     fn hash<__H: hash::Hasher>(&self, state: &mut __H) -> () {
         match (&*self,) {
             (&Int(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&Uint(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&Float(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&Adt(ref __self_0, ref __self_1),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state);
                 hash::Hash::hash(__self_1, state)
             }
             (&Foreign(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&Array(ref __self_0, ref __self_1),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state);
                 hash::Hash::hash(__self_1, state)
             }
             (&Slice(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&RawPtr(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&Ref(ref __self_0, ref __self_1, ref __self_2),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state);
                 hash::Hash::hash(__self_1, state);
                 hash::Hash::hash(__self_2, state)
             }
             (&FnDef(ref __self_0, ref __self_1),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state);
                 hash::Hash::hash(__self_1, state)
             }
             (&FnPtr(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&Dynamic(ref __self_0, ref __self_1),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state);
                 hash::Hash::hash(__self_1, state)
             }
             (&Closure(ref __self_0, ref __self_1),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state);
                 hash::Hash::hash(__self_1, state)
             }
             (&Generator(ref __self_0, ref __self_1, ref __self_2),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state);
                 hash::Hash::hash(__self_1, state);
                 hash::Hash::hash(__self_2, state)
             }
             (&GeneratorWitness(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&Tuple(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&Projection(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&Opaque(ref __self_0, ref __self_1),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state);
                 hash::Hash::hash(__self_1, state)
             }
             (&Param(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&Bound(ref __self_0, ref __self_1),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state);
                 hash::Hash::hash(__self_1, state)
             }
             (&Placeholder(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&Infer(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
             (&Error(ref __self_0),) => {
-                hash::Hash::hash(&discriminant(self), state);
+                hash::Hash::hash(&tykind_discriminant(self), state);
                 hash::Hash::hash(__self_0, state)
             }
-            _ => hash::Hash::hash(&discriminant(self), state),
+            _ => hash::Hash::hash(&tykind_discriminant(self), state),
         }
     }
 }
@@ -716,7 +716,7 @@ where
     I::AllocId: Encodable<E>,
 {
     fn encode(&self, e: &mut E) {
-        let disc = discriminant(self);
+        let disc = tykind_discriminant(self);
         match self {
             Bool => e.emit_enum_variant(disc, |_| {}),
             Char => e.emit_enum_variant(disc, |_| {}),
@@ -991,3 +991,439 @@ where
         }
     }
 }
+
+/// Representation of regions. Note that the NLL checker uses a distinct
+/// representation of regions. For this reason, it internally replaces all the
+/// regions with inference variables -- the index of the variable is then used
+/// to index into internal NLL data structures. See `rustc_const_eval::borrow_check`
+/// module for more information.
+///
+/// Note: operations are on the wrapper `Region` type, which is interned,
+/// rather than this type.
+///
+/// ## The Region lattice within a given function
+///
+/// In general, the region lattice looks like
+///
+/// ```text
+/// static ----------+-----...------+       (greatest)
+/// |                |              |
+/// early-bound and  |              |
+/// free regions     |              |
+/// |                |              |
+/// |                |              |
+/// empty(root)   placeholder(U1)   |
+/// |            /                  |
+/// |           /         placeholder(Un)
+/// empty(U1) --         /
+/// |                   /
+/// ...                /
+/// |                 /
+/// empty(Un) --------                      (smallest)
+/// ```
+///
+/// Early-bound/free regions are the named lifetimes in scope from the
+/// function declaration. They have relationships to one another
+/// determined based on the declared relationships from the
+/// function.
+///
+/// Note that inference variables and bound regions are not included
+/// in this diagram. In the case of inference variables, they should
+/// be inferred to some other region from the diagram.  In the case of
+/// bound regions, they are excluded because they don't make sense to
+/// include -- the diagram indicates the relationship between free
+/// regions.
+///
+/// ## Inference variables
+///
+/// During region inference, we sometimes create inference variables,
+/// represented as `ReVar`. These will be inferred by the code in
+/// `infer::lexical_region_resolve` to some free region from the
+/// lattice above (the minimal region that meets the
+/// constraints).
+///
+/// During NLL checking, where regions are defined differently, we
+/// also use `ReVar` -- in that case, the index is used to index into
+/// the NLL region checker's data structures. The variable may in fact
+/// represent either a free region or an inference variable, in that
+/// case.
+///
+/// ## Bound Regions
+///
+/// These are regions that are stored behind a binder and must be substituted
+/// with some concrete region before being used. There are two kind of
+/// bound regions: early-bound, which are bound in an item's `Generics`,
+/// and are substituted by an `InternalSubsts`, and late-bound, which are part of
+/// higher-ranked types (e.g., `for<'a> fn(&'a ())`), and are substituted by
+/// the likes of `liberate_late_bound_regions`. The distinction exists
+/// because higher-ranked lifetimes aren't supported in all places. See [1][2].
+///
+/// Unlike `Param`s, bound regions are not supposed to exist "in the wild"
+/// outside their binder, e.g., in types passed to type inference, and
+/// should first be substituted (by placeholder regions, free regions,
+/// or region variables).
+///
+/// ## Placeholder and Free Regions
+///
+/// One often wants to work with bound regions without knowing their precise
+/// identity. For example, when checking a function, the lifetime of a borrow
+/// can end up being assigned to some region parameter. In these cases,
+/// it must be ensured that bounds on the region can't be accidentally
+/// assumed without being checked.
+///
+/// To do this, we replace the bound regions with placeholder markers,
+/// which don't satisfy any relation not explicitly provided.
+///
+/// There are two kinds of placeholder regions in rustc: `ReFree` and
+/// `RePlaceholder`. When checking an item's body, `ReFree` is supposed
+/// to be used. These also support explicit bounds: both the internally-stored
+/// *scope*, which the region is assumed to outlive, as well as other
+/// relations stored in the `FreeRegionMap`. Note that these relations
+/// aren't checked when you `make_subregion` (or `eq_types`), only by
+/// `resolve_regions_and_report_errors`.
+///
+/// When working with higher-ranked types, some region relations aren't
+/// yet known, so you can't just call `resolve_regions_and_report_errors`.
+/// `RePlaceholder` is designed for this purpose. In these contexts,
+/// there's also the risk that some inference variable laying around will
+/// get unified with your placeholder region: if you want to check whether
+/// `for<'a> Foo<'_>: 'a`, and you substitute your bound region `'a`
+/// with a placeholder region `'%a`, the variable `'_` would just be
+/// instantiated to the placeholder region `'%a`, which is wrong because
+/// the inference variable is supposed to satisfy the relation
+/// *for every value of the placeholder region*. To ensure that doesn't
+/// happen, you can use `leak_check`. This is more clearly explained
+/// by the [rustc dev guide].
+///
+/// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
+/// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
+/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
+pub enum RegionKind<I: Interner> {
+    /// Region bound in a type or fn declaration which will be
+    /// substituted 'early' -- that is, at the same time when type
+    /// parameters are substituted.
+    ReEarlyBound(I::EarlyBoundRegion),
+
+    /// Region bound in a function scope, which will be substituted when the
+    /// function is called.
+    ReLateBound(DebruijnIndex, I::BoundRegion),
+
+    /// When checking a function body, the types of all arguments and so forth
+    /// that refer to bound region parameters are modified to refer to free
+    /// region parameters.
+    ReFree(I::FreeRegion),
+
+    /// Static data that has an "infinite" lifetime. Top in the region lattice.
+    ReStatic,
+
+    /// A region variable. Should not exist outside of type inference.
+    ReVar(I::RegionVid),
+
+    /// A placeholder region -- basically, the higher-ranked version of `ReFree`.
+    /// Should not exist outside of type inference.
+    RePlaceholder(I::PlaceholderRegion),
+
+    /// Empty lifetime is for data that is never accessed.  We tag the
+    /// empty lifetime with a universe -- the idea is that we don't
+    /// want `exists<'a> { forall<'b> { 'b: 'a } }` to be satisfiable.
+    /// Therefore, the `'empty` in a universe `U` is less than all
+    /// regions visible from `U`, but not less than regions not visible
+    /// from `U`.
+    ReEmpty(UniverseIndex),
+
+    /// Erased region, used by trait selection, in MIR and during codegen.
+    ReErased,
+}
+
+// This is manually implemented for `RegionKind` because `std::mem::discriminant`
+// returns an opaque value that is `PartialEq` but not `PartialOrd`
+#[inline]
+const fn regionkind_discriminant<I: Interner>(value: &RegionKind<I>) -> usize {
+    match value {
+        ReEarlyBound(_) => 0,
+        ReLateBound(_, _) => 1,
+        ReFree(_) => 2,
+        ReStatic => 3,
+        ReVar(_) => 4,
+        RePlaceholder(_) => 5,
+        ReEmpty(_) => 6,
+        ReErased => 7,
+    }
+}
+
+// This is manually implemented because a derive would require `I: Copy`
+impl<I: Interner> Copy for RegionKind<I>
+where
+    I::EarlyBoundRegion: Copy,
+    I::BoundRegion: Copy,
+    I::FreeRegion: Copy,
+    I::RegionVid: Copy,
+    I::PlaceholderRegion: Copy,
+{
+}
+
+// This is manually implemented because a derive would require `I: Clone`
+impl<I: Interner> Clone for RegionKind<I> {
+    fn clone(&self) -> Self {
+        match self {
+            ReEarlyBound(a) => ReEarlyBound(a.clone()),
+            ReLateBound(a, b) => ReLateBound(a.clone(), b.clone()),
+            ReFree(a) => ReFree(a.clone()),
+            ReStatic => ReStatic,
+            ReVar(a) => ReVar(a.clone()),
+            RePlaceholder(a) => RePlaceholder(a.clone()),
+            ReEmpty(a) => ReEmpty(a.clone()),
+            ReErased => ReErased,
+        }
+    }
+}
+
+// This is manually implemented because a derive would require `I: PartialEq`
+impl<I: Interner> PartialEq for RegionKind<I> {
+    #[inline]
+    fn eq(&self, other: &RegionKind<I>) -> bool {
+        let __self_vi = regionkind_discriminant(self);
+        let __arg_1_vi = regionkind_discriminant(other);
+        if __self_vi == __arg_1_vi {
+            match (&*self, &*other) {
+                (&ReEarlyBound(ref __self_0), &ReEarlyBound(ref __arg_1_0)) => {
+                    __self_0 == __arg_1_0
+                }
+                (
+                    &ReLateBound(ref __self_0, ref __self_1),
+                    &ReLateBound(ref __arg_1_0, ref __arg_1_1),
+                ) => __self_0 == __arg_1_0 && __self_1 == __arg_1_1,
+                (&ReFree(ref __self_0), &ReFree(ref __arg_1_0)) => __self_0 == __arg_1_0,
+                (&ReStatic, &ReStatic) => true,
+                (&ReVar(ref __self_0), &ReVar(ref __arg_1_0)) => __self_0 == __arg_1_0,
+                (&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
+                    __self_0 == __arg_1_0
+                }
+                (&ReEmpty(ref __self_0), &ReEmpty(ref __arg_1_0)) => __self_0 == __arg_1_0,
+                (&ReErased, &ReErased) => true,
+                _ => true,
+            }
+        } else {
+            false
+        }
+    }
+}
+
+// This is manually implemented because a derive would require `I: Eq`
+impl<I: Interner> Eq for RegionKind<I> {}
+
+// This is manually implemented because a derive would require `I: PartialOrd`
+impl<I: Interner> PartialOrd for RegionKind<I> {
+    #[inline]
+    fn partial_cmp(&self, other: &RegionKind<I>) -> Option<Ordering> {
+        Some(Ord::cmp(self, other))
+    }
+}
+
+// This is manually implemented because a derive would require `I: Ord`
+impl<I: Interner> Ord for RegionKind<I> {
+    #[inline]
+    fn cmp(&self, other: &RegionKind<I>) -> Ordering {
+        let __self_vi = regionkind_discriminant(self);
+        let __arg_1_vi = regionkind_discriminant(other);
+        if __self_vi == __arg_1_vi {
+            match (&*self, &*other) {
+                (&ReEarlyBound(ref __self_0), &ReEarlyBound(ref __arg_1_0)) => {
+                    Ord::cmp(__self_0, __arg_1_0)
+                }
+                (
+                    &ReLateBound(ref __self_0, ref __self_1),
+                    &ReLateBound(ref __arg_1_0, ref __arg_1_1),
+                ) => match Ord::cmp(__self_0, __arg_1_0) {
+                    Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
+                    cmp => cmp,
+                },
+                (&ReFree(ref __self_0), &ReFree(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
+                (&ReStatic, &ReStatic) => Ordering::Equal,
+                (&ReVar(ref __self_0), &ReVar(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
+                (&RePlaceholder(ref __self_0), &RePlaceholder(ref __arg_1_0)) => {
+                    Ord::cmp(__self_0, __arg_1_0)
+                }
+                (&ReEmpty(ref __self_0), &ReEmpty(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
+                (&ReErased, &ReErased) => Ordering::Equal,
+                _ => Ordering::Equal,
+            }
+        } else {
+            Ord::cmp(&__self_vi, &__arg_1_vi)
+        }
+    }
+}
+
+// This is manually implemented because a derive would require `I: Hash`
+impl<I: Interner> hash::Hash for RegionKind<I> {
+    fn hash<__H: hash::Hasher>(&self, state: &mut __H) -> () {
+        match (&*self,) {
+            (&ReEarlyBound(ref __self_0),) => {
+                hash::Hash::hash(&regionkind_discriminant(self), state);
+                hash::Hash::hash(__self_0, state)
+            }
+            (&ReLateBound(ref __self_0, ref __self_1),) => {
+                hash::Hash::hash(&regionkind_discriminant(self), state);
+                hash::Hash::hash(__self_0, state);
+                hash::Hash::hash(__self_1, state)
+            }
+            (&ReFree(ref __self_0),) => {
+                hash::Hash::hash(&regionkind_discriminant(self), state);
+                hash::Hash::hash(__self_0, state)
+            }
+            (&ReStatic,) => {
+                hash::Hash::hash(&regionkind_discriminant(self), state);
+            }
+            (&ReVar(ref __self_0),) => {
+                hash::Hash::hash(&regionkind_discriminant(self), state);
+                hash::Hash::hash(__self_0, state)
+            }
+            (&RePlaceholder(ref __self_0),) => {
+                hash::Hash::hash(&regionkind_discriminant(self), state);
+                hash::Hash::hash(__self_0, state)
+            }
+            (&ReEmpty(ref __self_0),) => {
+                hash::Hash::hash(&regionkind_discriminant(self), state);
+                hash::Hash::hash(__self_0, state)
+            }
+            (&ReErased,) => {
+                hash::Hash::hash(&regionkind_discriminant(self), state);
+            }
+        }
+    }
+}
+
+// This is manually implemented because a derive would require `I: Debug`
+impl<I: Interner> fmt::Debug for RegionKind<I> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            ReEarlyBound(ref data) => write!(f, "ReEarlyBound({:?})", data),
+
+            ReLateBound(binder_id, ref bound_region) => {
+                write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region)
+            }
+
+            ReFree(ref fr) => fr.fmt(f),
+
+            ReStatic => write!(f, "ReStatic"),
+
+            ReVar(ref vid) => vid.fmt(f),
+
+            RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
+
+            ReEmpty(ui) => write!(f, "ReEmpty({:?})", ui),
+
+            ReErased => write!(f, "ReErased"),
+        }
+    }
+}
+
+// This is manually implemented because a derive would require `I: Encodable`
+impl<I: Interner, E: TyEncoder> Encodable<E> for RegionKind<I>
+where
+    I::EarlyBoundRegion: Encodable<E>,
+    I::BoundRegion: Encodable<E>,
+    I::FreeRegion: Encodable<E>,
+    I::RegionVid: Encodable<E>,
+    I::PlaceholderRegion: Encodable<E>,
+{
+    fn encode(&self, e: &mut E) {
+        let disc = regionkind_discriminant(self);
+        match self {
+            ReEarlyBound(a) => e.emit_enum_variant(disc, |e| {
+                a.encode(e);
+            }),
+            ReLateBound(a, b) => e.emit_enum_variant(disc, |e| {
+                a.encode(e);
+                b.encode(e);
+            }),
+            ReFree(a) => e.emit_enum_variant(disc, |e| {
+                a.encode(e);
+            }),
+            ReStatic => e.emit_enum_variant(disc, |_| {}),
+            ReVar(a) => e.emit_enum_variant(disc, |e| {
+                a.encode(e);
+            }),
+            RePlaceholder(a) => e.emit_enum_variant(disc, |e| {
+                a.encode(e);
+            }),
+            ReEmpty(a) => e.emit_enum_variant(disc, |e| {
+                a.encode(e);
+            }),
+            ReErased => e.emit_enum_variant(disc, |_| {}),
+        }
+    }
+}
+
+// This is manually implemented because a derive would require `I: Decodable`
+impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for RegionKind<I>
+where
+    I::EarlyBoundRegion: Decodable<D>,
+    I::BoundRegion: Decodable<D>,
+    I::FreeRegion: Decodable<D>,
+    I::RegionVid: Decodable<D>,
+    I::PlaceholderRegion: Decodable<D>,
+{
+    fn decode(d: &mut D) -> Self {
+        match Decoder::read_usize(d) {
+            0 => ReEarlyBound(Decodable::decode(d)),
+            1 => ReLateBound(Decodable::decode(d), Decodable::decode(d)),
+            2 => ReFree(Decodable::decode(d)),
+            3 => ReStatic,
+            4 => ReVar(Decodable::decode(d)),
+            5 => RePlaceholder(Decodable::decode(d)),
+            6 => ReEmpty(Decodable::decode(d)),
+            7 => ReErased,
+            _ => panic!(
+                "{}",
+                format!(
+                    "invalid enum variant tag while decoding `{}`, expected 0..{}",
+                    "RegionKind", 8,
+                )
+            ),
+        }
+    }
+}
+
+// This is not a derived impl because a derive would require `I: HashStable`
+impl<CTX, I: Interner> HashStable<CTX> for RegionKind<I>
+where
+    I::EarlyBoundRegion: HashStable<CTX>,
+    I::BoundRegion: HashStable<CTX>,
+    I::FreeRegion: HashStable<CTX>,
+    I::RegionVid: HashStable<CTX>,
+    I::PlaceholderRegion: HashStable<CTX>,
+{
+    #[inline]
+    fn hash_stable(
+        &self,
+        hcx: &mut CTX,
+        hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
+    ) {
+        std::mem::discriminant(self).hash_stable(hcx, hasher);
+        match self {
+            ReErased | ReStatic => {
+                // No variant fields to hash for these ...
+            }
+            ReEmpty(universe) => {
+                universe.hash_stable(hcx, hasher);
+            }
+            ReLateBound(db, br) => {
+                db.hash_stable(hcx, hasher);
+                br.hash_stable(hcx, hasher);
+            }
+            ReEarlyBound(eb) => {
+                eb.hash_stable(hcx, hasher);
+            }
+            ReFree(ref free_region) => {
+                free_region.hash_stable(hcx, hasher);
+            }
+            RePlaceholder(p) => {
+                p.hash_stable(hcx, hasher);
+            }
+            ReVar(reg) => {
+                reg.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 32bbfd7e332..4641b36aad1 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -2195,8 +2195,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 "{kind} arguments are not allowed on {this_type}",
             );
             err.span_label(last_span, format!("{kind} argument{s} not allowed"));
-            for (_, span) in types_and_spans {
-                err.span_label(span, "not allowed on this");
+            for (what, span) in types_and_spans {
+                err.span_label(span, format!("not allowed on {what}"));
             }
             extend(&mut err);
             err.emit();
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
index 93ca8e2237f..2326c4069e4 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
@@ -955,8 +955,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         let input_ty = self.resolve_vars_if_possible(expected_ty);
                         if input_ty.is_unit() {
                             "()".to_string()
+                        } else if !input_ty.is_ty_var() {
+                            format!("/* {} */", input_ty)
                         } else {
-                            format!("{{{}}}", input_ty)
+                            "/* value */".to_string()
                         }
                     };
                     suggestion += &suggestion_text;
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index ad85ac71fc8..79312153895 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -490,7 +490,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>(
     // The bounds we that we would require from `to_check`
     let mut bounds = FxHashSet::default();
 
-    let (regions, types) = GATSubstCollector::visit(tcx, gat_def_id.to_def_id(), to_check);
+    let (regions, types) = GATSubstCollector::visit(gat_def_id.to_def_id(), to_check);
 
     // If both regions and types are empty, then this GAT isn't in the
     // set of types we are checking, and we shouldn't try to do clause analysis
@@ -664,7 +664,6 @@ fn resolve_regions_with_wf_tys<'tcx>(
 /// the two vectors, `regions` and `types` (depending on their kind). For each
 /// parameter `Pi` also track the index `i`.
 struct GATSubstCollector<'tcx> {
-    tcx: TyCtxt<'tcx>,
     gat: DefId,
     // Which region appears and which parameter index its substituted for
     regions: FxHashSet<(ty::Region<'tcx>, usize)>,
@@ -674,16 +673,11 @@ struct GATSubstCollector<'tcx> {
 
 impl<'tcx> GATSubstCollector<'tcx> {
     fn visit<T: TypeFoldable<'tcx>>(
-        tcx: TyCtxt<'tcx>,
         gat: DefId,
         t: T,
     ) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) {
-        let mut visitor = GATSubstCollector {
-            tcx,
-            gat,
-            regions: FxHashSet::default(),
-            types: FxHashSet::default(),
-        };
+        let mut visitor =
+            GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() };
         t.visit_with(&mut visitor);
         (visitor.regions, visitor.types)
     }
@@ -692,19 +686,12 @@ impl<'tcx> GATSubstCollector<'tcx> {
 impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> {
     type BreakTy = !;
 
-    fn visit_binder<T: TypeFoldable<'tcx>>(
-        &mut self,
-        t: &ty::Binder<'tcx, T>,
-    ) -> ControlFlow<Self::BreakTy> {
-        self.tcx.liberate_late_bound_regions(self.gat, t.clone()).visit_with(self)
-    }
-
     fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
         match t.kind() {
             ty::Projection(p) if p.item_def_id == self.gat => {
                 for (idx, subst) in p.substs.iter().enumerate() {
                     match subst.unpack() {
-                        GenericArgKind::Lifetime(lt) => {
+                        GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => {
                             self.regions.insert((lt, idx));
                         }
                         GenericArgKind::Type(t) => {
diff --git a/compiler/rustc_typeck/src/hir_wf_check.rs b/compiler/rustc_typeck/src/hir_wf_check.rs
index b4b438a561a..4392b9aada9 100644
--- a/compiler/rustc_typeck/src/hir_wf_check.rs
+++ b/compiler/rustc_typeck/src/hir_wf_check.rs
@@ -1,7 +1,7 @@
 use crate::collect::ItemCtxt;
 use rustc_hir as hir;
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::HirId;
+use rustc_hir::{ForeignItem, ForeignItemKind, HirId};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::TraitEngine;
 use rustc_infer::traits::{ObligationCause, WellFormedLoc};
@@ -141,6 +141,9 @@ fn diagnostic_hir_wf_check<'tcx>(
                 ref item => bug!("Unexpected item {:?}", item),
             },
             hir::Node::Field(field) => Some(field.ty),
+            hir::Node::ForeignItem(ForeignItem {
+                kind: ForeignItemKind::Static(ty, _), ..
+            }) => Some(*ty),
             ref node => bug!("Unexpected node {:?}", node),
         },
         WellFormedLoc::Param { function: _, param_idx } => {
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index e1124a68750..28068a88060 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -1644,11 +1644,11 @@ impl<K, V, A: Allocator + Clone> IntoIter<K, V, A> {
         &mut self,
     ) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>> {
         if self.length == 0 {
-            self.range.deallocating_end(&self.alloc);
+            self.range.deallocating_end(self.alloc.clone());
             None
         } else {
             self.length -= 1;
-            Some(unsafe { self.range.deallocating_next_unchecked(&self.alloc) })
+            Some(unsafe { self.range.deallocating_next_unchecked(self.alloc.clone()) })
         }
     }
 
@@ -1658,11 +1658,11 @@ impl<K, V, A: Allocator + Clone> IntoIter<K, V, A> {
         &mut self,
     ) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>> {
         if self.length == 0 {
-            self.range.deallocating_end(&self.alloc);
+            self.range.deallocating_end(self.alloc.clone());
             None
         } else {
             self.length -= 1;
-            Some(unsafe { self.range.deallocating_next_back_unchecked(&self.alloc) })
+            Some(unsafe { self.range.deallocating_next_back_unchecked(self.alloc.clone()) })
         }
     }
 }
@@ -1849,7 +1849,7 @@ where
     type Item = (K, V);
 
     fn next(&mut self) -> Option<(K, V)> {
-        self.inner.next(&mut self.pred, &self.alloc)
+        self.inner.next(&mut self.pred, self.alloc.clone())
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index bec3b967525..0d3fdc9019e 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -1320,7 +1320,7 @@ where
     fn next(&mut self) -> Option<T> {
         let pred = &mut self.pred;
         let mut mapped_pred = |k: &T, _v: &mut ()| pred(k);
-        self.inner.next(&mut mapped_pred, &self.alloc).map(|(k, _)| k)
+        self.inner.next(&mut mapped_pred, self.alloc.clone()).map(|(k, _)| k)
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 2b3736019ba..a248cd458df 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -1254,8 +1254,6 @@ impl<T: Clone> Rc<T> {
 }
 
 impl Rc<dyn Any> {
-    #[inline]
-    #[stable(feature = "rc_downcast", since = "1.29.0")]
     /// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
     ///
     /// # Examples
@@ -1274,6 +1272,8 @@ impl Rc<dyn Any> {
     /// print_if_string(Rc::new(my_string));
     /// print_if_string(Rc::new(0i8));
     /// ```
+    #[inline]
+    #[stable(feature = "rc_downcast", since = "1.29.0")]
     pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
         if (*self).is::<T>() {
             unsafe {
@@ -1285,6 +1285,42 @@ impl Rc<dyn Any> {
             Err(self)
         }
     }
+
+    /// Downcasts the `Rc<dyn Any>` to a concrete type.
+    ///
+    /// For a safe alternative see [`downcast`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(downcast_unchecked)]
+    ///
+    /// use std::any::Any;
+    /// use std::rc::Rc;
+    ///
+    /// let x: Rc<dyn Any> = Rc::new(1_usize);
+    ///
+    /// unsafe {
+    ///     assert_eq!(*x.downcast_unchecked::<usize>(), 1);
+    /// }
+    /// ```
+    ///
+    /// # Safety
+    ///
+    /// The contained value must be of type `T`. Calling this method
+    /// with the incorrect type is *undefined behavior*.
+    ///
+    ///
+    /// [`downcast`]: Self::downcast
+    #[inline]
+    #[unstable(feature = "downcast_unchecked", issue = "90850")]
+    pub unsafe fn downcast_unchecked<T: Any>(self) -> Rc<T> {
+        unsafe {
+            let ptr = self.ptr.cast::<RcBox<T>>();
+            mem::forget(self);
+            Rc::from_inner(ptr)
+        }
+    }
 }
 
 impl<T: ?Sized> Rc<T> {
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 55d51e0a3c4..2670b15982a 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -1705,8 +1705,6 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc<T> {
 }
 
 impl Arc<dyn Any + Send + Sync> {
-    #[inline]
-    #[stable(feature = "rc_downcast", since = "1.29.0")]
     /// Attempt to downcast the `Arc<dyn Any + Send + Sync>` to a concrete type.
     ///
     /// # Examples
@@ -1725,9 +1723,11 @@ impl Arc<dyn Any + Send + Sync> {
     /// print_if_string(Arc::new(my_string));
     /// print_if_string(Arc::new(0i8));
     /// ```
+    #[inline]
+    #[stable(feature = "rc_downcast", since = "1.29.0")]
     pub fn downcast<T>(self) -> Result<Arc<T>, Self>
     where
-        T: Any + Send + Sync + 'static,
+        T: Any + Send + Sync,
     {
         if (*self).is::<T>() {
             unsafe {
@@ -1739,6 +1739,45 @@ impl Arc<dyn Any + Send + Sync> {
             Err(self)
         }
     }
+
+    /// Downcasts the `Arc<dyn Any + Send + Sync>` to a concrete type.
+    ///
+    /// For a safe alternative see [`downcast`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(downcast_unchecked)]
+    ///
+    /// use std::any::Any;
+    /// use std::sync::Arc;
+    ///
+    /// let x: Arc<dyn Any + Send + Sync> = Arc::new(1_usize);
+    ///
+    /// unsafe {
+    ///     assert_eq!(*x.downcast_unchecked::<usize>(), 1);
+    /// }
+    /// ```
+    ///
+    /// # Safety
+    ///
+    /// The contained value must be of type `T`. Calling this method
+    /// with the incorrect type is *undefined behavior*.
+    ///
+    ///
+    /// [`downcast`]: Self::downcast
+    #[inline]
+    #[unstable(feature = "downcast_unchecked", issue = "90850")]
+    pub unsafe fn downcast_unchecked<T>(self) -> Arc<T>
+    where
+        T: Any + Send + Sync,
+    {
+        unsafe {
+            let ptr = self.ptr.cast::<ArcInner<T>>();
+            mem::forget(self);
+            Arc::from_inner(ptr)
+        }
+    }
 }
 
 impl<T> Weak<T> {
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 1c66089fad6..9e4a574818a 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -320,6 +320,7 @@ macro_rules! arg_new {
     };
 }
 
+#[rustc_diagnostic_item = "ArgumentV1Methods"]
 impl<'a> ArgumentV1<'a> {
     #[doc(hidden)]
     #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
diff --git a/library/core/src/future/into_future.rs b/library/core/src/future/into_future.rs
index d22094130ad..ad9e80e117f 100644
--- a/library/core/src/future/into_future.rs
+++ b/library/core/src/future/into_future.rs
@@ -2,7 +2,7 @@ use crate::future::Future;
 
 /// Conversion into a `Future`.
 ///
-/// By implementing `Intofuture` for a type, you define how it will be
+/// By implementing `IntoFuture` for a type, you define how it will be
 /// converted to a future.
 ///
 /// # `.await` desugaring
@@ -29,7 +29,7 @@ use crate::future::Future;
 /// When implementing futures manually there will often be a choice between
 /// implementing `Future` or `IntoFuture` for a type. Implementing `Future` is a
 /// good choice in most cases. But implementing `IntoFuture` is most useful when
-/// implementing "async builder" types, which allows the type to be modified
+/// implementing "async builder" types, which allow their values to be modified
 /// multiple times before being `.await`ed.
 ///
 /// ```rust
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index ba837ea9a78..2f9afbec91e 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -1144,7 +1144,7 @@ extern "rust-intrinsic" {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
+    #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
     #[rustc_diagnostic_item = "transmute"]
     pub fn transmute<T, U>(e: T) -> U;
 
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 71ea3b4ba85..ecd2b75ae44 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -973,6 +973,28 @@ pub const fn replace<T>(dest: &mut T, src: T) -> T {
 #[cfg_attr(not(test), rustc_diagnostic_item = "mem_drop")]
 pub fn drop<T>(_x: T) {}
 
+/// Bitwise-copies a value.
+///
+/// This function is not magic; it is literally defined as
+/// ```
+/// pub fn copy<T: Copy>(x: &T) -> T { *x }
+/// ```
+///
+/// It is useful when you want to pass a function pointer to a combinator, rather than defining a new closure.
+///
+/// Example:
+/// ```
+/// #![feature(mem_copy_fn)]
+/// use core::mem::copy;
+/// let result_from_ffi_function: Result<(), &i32> = Err(&1);
+/// let result_copied: Result<(), i32> = result_from_ffi_function.map_err(copy);
+/// ```
+#[inline]
+#[unstable(feature = "mem_copy_fn", issue = "98262")]
+pub fn copy<T: Copy>(x: &T) -> T {
+    *x
+}
+
 /// Interprets `src` as having type `&U`, and then reads `src` without moving
 /// the contained value.
 ///
diff --git a/library/core/src/ops/generator.rs b/library/core/src/ops/generator.rs
index 7c3b2a644e8..b651b7b233e 100644
--- a/library/core/src/ops/generator.rs
+++ b/library/core/src/ops/generator.rs
@@ -61,9 +61,10 @@ pub enum GeneratorState<Y, R> {
 /// }
 /// ```
 ///
-/// More documentation of generators can be found in the unstable book.
+/// More documentation of generators can be found in the [unstable book].
 ///
 /// [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
+/// [unstable book]: ../../unstable-book/language-features/generators.html
 #[lang = "generator"]
 #[unstable(feature = "generator_trait", issue = "43122")]
 #[fundamental]
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 720317b05e0..ccef35b4532 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -1006,9 +1006,10 @@ impl<P, U> DispatchFromDyn<Pin<U>> for Pin<P> where P: DispatchFromDyn<U> {}
 ///  // Allow generator to be self-referential (not `Unpin`)
 ///  // vvvvvv        so that locals can cross yield points.
 ///     static || {
-///         let foo = String::from("foo"); // --+
-///         yield 0;                         // | <- crosses yield point!
-///         println!("{}", &foo); // <----------+
+///         let foo = String::from("foo");
+///         let foo_ref = &foo; // ------+
+///         yield 0;                  // | <- crosses yield point!
+///         println!("{foo_ref}"); // <--+
 ///         yield foo.len();
 ///     }
 /// }
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 772a9698d84..35d00b9dda6 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -306,6 +306,47 @@ impl<'a, T> IterMut<'a, T> {
     pub fn as_slice(&self) -> &[T] {
         self.make_slice()
     }
+
+    /// Views the underlying data as a mutable subslice of the original data.
+    ///
+    /// To avoid creating `&mut [T]` references that alias, the returned slice
+    /// borrows its lifetime from the iterator the method is applied on.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(slice_iter_mut_as_mut_slice)]
+    ///
+    /// let mut slice: &mut [usize] = &mut [1, 2, 3];
+    ///
+    /// // First, we get the iterator:
+    /// let mut iter = slice.iter_mut();
+    /// // Then, we get a mutable slice from it:
+    /// let mut_slice = iter.as_mut_slice();
+    /// // So if we check what the `as_mut_slice` method returned, we have "[1, 2, 3]":
+    /// assert_eq!(mut_slice, &mut [1, 2, 3]);
+    ///
+    /// // We can use it to mutate the slice:
+    /// mut_slice[0] = 4;
+    /// mut_slice[2] = 5;
+    ///
+    /// // Next, we can move to the second element of the slice, checking that
+    /// // it yields the value we just wrote:
+    /// assert_eq!(iter.next(), Some(&mut 4));
+    /// // Now `as_mut_slice` returns "[2, 5]":
+    /// assert_eq!(iter.as_mut_slice(), &mut [2, 5]);
+    /// ```
+    #[must_use]
+    // FIXME: Uncomment the `AsMut<[T]>` impl when this gets stabilized.
+    #[unstable(feature = "slice_iter_mut_as_mut_slice", issue = "93079")]
+    pub fn as_mut_slice(&mut self) -> &mut [T] {
+        // SAFETY: the iterator was created from a mutable slice with pointer
+        // `self.ptr` and length `len!(self)`. This guarantees that all the prerequisites
+        // for `from_raw_parts_mut` are fulfilled.
+        unsafe { from_raw_parts_mut(self.ptr.as_ptr(), len!(self)) }
+    }
 }
 
 #[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
@@ -315,6 +356,13 @@ impl<T> AsRef<[T]> for IterMut<'_, T> {
     }
 }
 
+// #[stable(feature = "slice_iter_mut_as_mut_slice", since = "FIXME")]
+// impl<T> AsMut<[T]> for IterMut<'_, T> {
+//     fn as_mut(&mut self) -> &mut [T] {
+//         self.as_mut_slice()
+//     }
+// }
+
 iterator! {struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}}
 
 /// An internal abstraction over the splitting iterators, so that
diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs
index 1f392a07971..6a201834b8e 100644
--- a/library/core/src/slice/sort.rs
+++ b/library/core/src/slice/sort.rs
@@ -188,22 +188,25 @@ where
     // This binary heap respects the invariant `parent >= child`.
     let mut sift_down = |v: &mut [T], mut node| {
         loop {
-            // Children of `node`:
-            let left = 2 * node + 1;
-            let right = 2 * node + 2;
+            // Children of `node`.
+            let mut child = 2 * node + 1;
+            if child >= v.len() {
+                break;
+            }
 
             // Choose the greater child.
-            let greater =
-                if right < v.len() && is_less(&v[left], &v[right]) { right } else { left };
+            if child + 1 < v.len() && is_less(&v[child], &v[child + 1]) {
+                child += 1;
+            }
 
             // Stop if the invariant holds at `node`.
-            if greater >= v.len() || !is_less(&v[node], &v[greater]) {
+            if !is_less(&v[node], &v[child]) {
                 break;
             }
 
             // Swap `node` with the greater child, move one step down, and continue sifting.
-            v.swap(node, greater);
-            node = greater;
+            v.swap(node, child);
+            node = child;
         }
     };
 
diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs
index 068f3e241be..d7cc700495b 100644
--- a/library/proc_macro/src/bridge/client.rs
+++ b/library/proc_macro/src/bridge/client.rs
@@ -29,7 +29,6 @@ macro_rules! define_handles {
         }
 
         // FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`.
-        #[repr(C)]
         #[allow(non_snake_case)]
         pub(super) struct HandleStore<S: server::Types> {
             $($oty: handle::OwnedStore<S::$oty>,)*
@@ -46,7 +45,6 @@ macro_rules! define_handles {
         }
 
         $(
-            #[repr(C)]
             pub(crate) struct $oty {
                 handle: handle::Handle,
                 // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual
@@ -131,7 +129,6 @@ macro_rules! define_handles {
         )*
 
         $(
-            #[repr(C)]
             #[derive(Copy, Clone, PartialEq, Eq, Hash)]
             pub(crate) struct $ity {
                 handle: handle::Handle,
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index d3879273f5b..d554ec59035 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -187,7 +187,7 @@ impl System {
             old_size => unsafe {
                 let new_ptr = self.alloc_impl(new_layout, zeroed)?;
                 ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), old_size);
-                Allocator::deallocate(&self, ptr, old_layout);
+                Allocator::deallocate(self, ptr, old_layout);
                 Ok(new_ptr)
             },
         }
@@ -254,7 +254,7 @@ unsafe impl Allocator for System {
         match new_layout.size() {
             // SAFETY: conditions must be upheld by the caller
             0 => unsafe {
-                Allocator::deallocate(&self, ptr, old_layout);
+                Allocator::deallocate(self, ptr, old_layout);
                 Ok(NonNull::slice_from_raw_parts(new_layout.dangling(), 0))
             },
 
@@ -274,9 +274,9 @@ unsafe impl Allocator for System {
             // `new_ptr`. Thus, the call to `copy_nonoverlapping` is safe. The safety contract
             // for `dealloc` must be upheld by the caller.
             new_size => unsafe {
-                let new_ptr = Allocator::allocate(&self, new_layout)?;
+                let new_ptr = Allocator::allocate(self, new_layout)?;
                 ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), new_size);
-                Allocator::deallocate(&self, ptr, old_layout);
+                Allocator::deallocate(self, ptr, old_layout);
                 Ok(new_ptr)
             },
         }
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 192a21f2ffc..237c5ee7340 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -588,7 +588,7 @@ impl<K, V, S> HashMap<K, V, S> {
     ///
     /// If the returned iterator is dropped before being fully consumed, it
     /// drops the remaining key-value pairs. The returned iterator keeps a
-    /// mutable borrow on the vector to optimize its implementation.
+    /// mutable borrow on the map to optimize its implementation.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 55bd2c59406..f46997b807a 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -2317,10 +2317,14 @@ impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder {
 /// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
 /// denied on some of the parent directories.)
 ///
+/// Note that while this avoids some pitfalls of the `exists()` method, it still can not
+/// prevent time-of-check to time-of-use (TOCTOU) bugs. You should only use it in scenarios
+/// where those bugs are not an issue.
+///
 /// # Examples
 ///
 /// ```no_run
-/// #![feature(path_try_exists)]
+/// #![feature(fs_try_exists)]
 /// use std::fs;
 ///
 /// assert!(!fs::try_exists("does_not_exist.txt").expect("Can't check existence of file does_not_exist.txt"));
@@ -2330,7 +2334,7 @@ impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder {
 /// [`Path::exists`]: crate::path::Path::exists
 // FIXME: stabilization should modify documentation of `exists()` to recommend this method
 // instead.
-#[unstable(feature = "path_try_exists", issue = "83186")]
+#[unstable(feature = "fs_try_exists", issue = "83186")]
 #[inline]
 pub fn try_exists<P: AsRef<Path>>(path: P) -> io::Result<bool> {
     fs_imp::try_exists(path.as_ref())
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 94812e3fe3b..f4f2e3f2434 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -1084,6 +1084,10 @@ impl<'a> IoSliceMut<'a> {
     /// Also see [`IoSliceMut::advance_slices`] to advance the cursors of
     /// multiple buffers.
     ///
+    /// # Panics
+    ///
+    /// Panics when trying to advance beyond the end of the slice.
+    ///
     /// # Examples
     ///
     /// ```
@@ -1105,15 +1109,18 @@ impl<'a> IoSliceMut<'a> {
         self.0.advance(n)
     }
 
-    /// Advance the internal cursor of the slices.
+    /// Advance a slice of slices.
     ///
-    /// # Notes
+    /// Shrinks the slice to remove any `IoSliceMut`s that are fully advanced over.
+    /// If the cursor ends up in the middle of an `IoSliceMut`, it is modified
+    /// to start at that cursor.
     ///
-    /// Elements in the slice may be modified if the cursor is not advanced to
-    /// the end of the slice. For example if we have a slice of buffers with 2
-    /// `IoSliceMut`s, both of length 8, and we advance the cursor by 10 bytes
-    /// the first `IoSliceMut` will be untouched however the second will be
-    /// modified to remove the first 2 bytes (10 - 8).
+    /// For example, if we have a slice of two 8-byte `IoSliceMut`s, and we advance by 10 bytes,
+    /// the result will only include the second `IoSliceMut`, advanced by 2 bytes.
+    ///
+    /// # Panics
+    ///
+    /// Panics when trying to advance beyond the end of the slices.
     ///
     /// # Examples
     ///
@@ -1154,7 +1161,9 @@ impl<'a> IoSliceMut<'a> {
         }
 
         *bufs = &mut replace(bufs, &mut [])[remove..];
-        if !bufs.is_empty() {
+        if bufs.is_empty() {
+            assert!(n == accumulated_len, "advancing io slices beyond their length");
+        } else {
             bufs[0].advance(n - accumulated_len)
         }
     }
@@ -1219,6 +1228,10 @@ impl<'a> IoSlice<'a> {
     /// Also see [`IoSlice::advance_slices`] to advance the cursors of multiple
     /// buffers.
     ///
+    /// # Panics
+    ///
+    /// Panics when trying to advance beyond the end of the slice.
+    ///
     /// # Examples
     ///
     /// ```
@@ -1227,8 +1240,8 @@ impl<'a> IoSlice<'a> {
     /// use std::io::IoSlice;
     /// use std::ops::Deref;
     ///
-    /// let mut data = [1; 8];
-    /// let mut buf = IoSlice::new(&mut data);
+    /// let data = [1; 8];
+    /// let mut buf = IoSlice::new(&data);
     ///
     /// // Mark 3 bytes as read.
     /// buf.advance(3);
@@ -1240,15 +1253,18 @@ impl<'a> IoSlice<'a> {
         self.0.advance(n)
     }
 
-    /// Advance the internal cursor of the slices.
+    /// Advance a slice of slices.
     ///
-    /// # Notes
+    /// Shrinks the slice to remove any `IoSlice`s that are fully advanced over.
+    /// If the cursor ends up in the middle of an `IoSlice`, it is modified
+    /// to start at that cursor.
     ///
-    /// Elements in the slice may be modified if the cursor is not advanced to
-    /// the end of the slice. For example if we have a slice of buffers with 2
-    /// `IoSlice`s, both of length 8, and we advance the cursor by 10 bytes the
-    /// first `IoSlice` will be untouched however the second will be modified to
-    /// remove the first 2 bytes (10 - 8).
+    /// For example, if we have a slice of two 8-byte `IoSlice`s, and we advance by 10 bytes,
+    /// the result will only include the second `IoSlice`, advanced by 2 bytes.
+    ///
+    /// # Panics
+    ///
+    /// Panics when trying to advance beyond the end of the slices.
     ///
     /// # Examples
     ///
@@ -1288,7 +1304,9 @@ impl<'a> IoSlice<'a> {
         }
 
         *bufs = &mut replace(bufs, &mut [])[remove..];
-        if !bufs.is_empty() {
+        if bufs.is_empty() {
+            assert!(n == accumulated_len, "advancing io slices beyond their length");
+        } else {
             bufs[0].advance(n - accumulated_len)
         }
     }
@@ -1417,10 +1435,10 @@ pub trait Write {
     /// use std::fs::File;
     ///
     /// fn main() -> std::io::Result<()> {
-    ///     let mut data1 = [1; 8];
-    ///     let mut data2 = [15; 8];
-    ///     let io_slice1 = IoSlice::new(&mut data1);
-    ///     let io_slice2 = IoSlice::new(&mut data2);
+    ///     let data1 = [1; 8];
+    ///     let data2 = [15; 8];
+    ///     let io_slice1 = IoSlice::new(&data1);
+    ///     let io_slice2 = IoSlice::new(&data2);
     ///
     ///     let mut buffer = File::create("foo.txt")?;
     ///
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index eb626348564..d5a8c93b0ce 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -423,18 +423,18 @@ fn io_slice_mut_advance_slices() {
 }
 
 #[test]
+#[should_panic]
 fn io_slice_mut_advance_slices_empty_slice() {
     let mut empty_bufs = &mut [][..];
-    // Shouldn't panic.
     IoSliceMut::advance_slices(&mut empty_bufs, 1);
 }
 
 #[test]
+#[should_panic]
 fn io_slice_mut_advance_slices_beyond_total_length() {
     let mut buf1 = [1; 8];
     let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..];
 
-    // Going beyond the total length should be ok.
     IoSliceMut::advance_slices(&mut bufs, 9);
     assert!(bufs.is_empty());
 }
@@ -463,18 +463,18 @@ fn io_slice_advance_slices() {
 }
 
 #[test]
+#[should_panic]
 fn io_slice_advance_slices_empty_slice() {
     let mut empty_bufs = &mut [][..];
-    // Shouldn't panic.
     IoSlice::advance_slices(&mut empty_bufs, 1);
 }
 
 #[test]
+#[should_panic]
 fn io_slice_advance_slices_beyond_total_length() {
     let buf1 = [1; 8];
     let mut bufs = &mut [IoSlice::new(&buf1)][..];
 
-    // Going beyond the total length should be ok.
     IoSlice::advance_slices(&mut bufs, 9);
     assert!(bufs.is_empty());
 }
diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs
index 7556d3ad0b2..3ab5606f889 100644
--- a/library/std/src/os/unix/io/mod.rs
+++ b/library/std/src/os/unix/io/mod.rs
@@ -54,6 +54,25 @@
 //! Like boxes, `OwnedFd` values conceptually own the resource they point to,
 //! and free (close) it when they are dropped.
 //!
+//! ## `/proc/self/mem` and similar OS features
+//!
+//! Some platforms have special files, such as `/proc/self/mem`, which
+//! provide read and write access to the process's memory. Such reads
+//! and writes happen outside the control of the Rust compiler, so they do not
+//! uphold Rust's memory safety guarantees.
+//!
+//! This does not mean that all APIs that might allow `/proc/self/mem`
+//! to be opened and read from or written must be `unsafe`. Rust's safety guarantees
+//! only cover what the program itself can do, and not what entities outside
+//! the program can do to it. `/proc/self/mem` is considered to be such an
+//! external entity, along with debugging interfaces, and people with physical access to
+//! the hardware. This is true even in cases where the program is controlling
+//! the external entity.
+//!
+//! If you desire to comprehensively prevent programs from reaching out and
+//! causing external entities to reach back in and violate memory safety, it's
+//! necessary to use *sandboxing*, which is outside the scope of `std`.
+//!
 //! [`BorrowedFd<'a>`]: crate::os::unix::io::BorrowedFd
 
 #![stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs
index ecee123a9b6..7cc901a7944 100644
--- a/library/std/src/os/unix/net/ancillary.rs
+++ b/library/std/src/os/unix/net/ancillary.rs
@@ -583,8 +583,8 @@ impl<'a> SocketAncillary<'a> {
     ///     let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
     ///     ancillary.add_fds(&[sock.as_raw_fd()][..]);
     ///
-    ///     let mut buf = [1; 8];
-    ///     let mut bufs = &mut [IoSlice::new(&mut buf[..])][..];
+    ///     let buf = [1; 8];
+    ///     let mut bufs = &mut [IoSlice::new(&buf[..])][..];
     ///     sock.send_vectored_with_ancillary(bufs, &mut ancillary)?;
     ///     Ok(())
     /// }
diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs
index 24b0888b112..a6b75493e6e 100644
--- a/library/std/src/os/windows/process.rs
+++ b/library/std/src/os/windows/process.rs
@@ -161,6 +161,37 @@ pub trait CommandExt: Sealed {
     /// `CommandLineToArgvW` escaping rules.
     #[stable(feature = "windows_process_extensions_raw_arg", since = "1.62.0")]
     fn raw_arg<S: AsRef<OsStr>>(&mut self, text_to_append_as_is: S) -> &mut process::Command;
+
+    /// When [`process::Command`] creates pipes, request that our side is always async.
+    ///
+    /// By default [`process::Command`] may choose to use pipes where both ends
+    /// are opened for synchronous read or write operations. By using
+    /// `async_pipes(true)`, this behavior is overridden so that our side is
+    /// always async.
+    ///
+    /// This is important because if doing async I/O a pipe or a file has to be
+    /// opened for async access.
+    ///
+    /// The end of the pipe sent to the child process will always be synchronous
+    /// regardless of this option.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// #![feature(windows_process_extensions_async_pipes)]
+    /// use std::os::windows::process::CommandExt;
+    /// use std::process::{Command, Stdio};
+    ///
+    /// # let program = "";
+    ///
+    /// Command::new(program)
+    ///     .async_pipes(true)
+    ///     .stdin(Stdio::piped())
+    ///     .stdout(Stdio::piped())
+    ///     .stderr(Stdio::piped());
+    /// ```
+    #[unstable(feature = "windows_process_extensions_async_pipes", issue = "98289")]
+    fn async_pipes(&mut self, always_async: bool) -> &mut process::Command;
 }
 
 #[stable(feature = "windows_process_extensions", since = "1.16.0")]
@@ -179,6 +210,15 @@ impl CommandExt for process::Command {
         self.as_inner_mut().raw_arg(raw_text.as_ref());
         self
     }
+
+    fn async_pipes(&mut self, always_async: bool) -> &mut process::Command {
+        // FIXME: This currently has an intentional no-op implementation.
+        // For the time being our side of the pipes will always be async.
+        // Once the ecosystem has adjusted, we may then be able to start making
+        // use of synchronous pipes within the standard library.
+        let _ = always_async;
+        self
+    }
 }
 
 #[unstable(feature = "windows_process_extensions_main_thread_handle", issue = "96723")]
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 6bbc8f55ace..5dfeb517a19 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -2705,6 +2705,9 @@ impl Path {
 
     /// Returns `true` if the path points at an existing entity.
     ///
+    /// Warning: this method may be error-prone, consider using [`try_exists()`] instead!
+    /// It also has a risk of introducing time-of-check to time-of-use (TOCTOU) bugs.
+    ///
     /// This function will traverse symbolic links to query information about the
     /// destination file.
     ///
@@ -2721,7 +2724,9 @@ impl Path {
     /// # See Also
     ///
     /// This is a convenience function that coerces errors to false. If you want to
-    /// check errors, call [`fs::metadata`].
+    /// check errors, call [`Path::try_exists`].
+    ///
+    /// [`try_exists()`]: Self::try_exists
     #[stable(feature = "path_ext", since = "1.5.0")]
     #[must_use]
     #[inline]
@@ -2738,20 +2743,20 @@ impl Path {
     /// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
     /// denied on some of the parent directories.)
     ///
+    /// Note that while this avoids some pitfalls of the `exists()` method, it still can not
+    /// prevent time-of-check to time-of-use (TOCTOU) bugs. You should only use it in scenarios
+    /// where those bugs are not an issue.
+    ///
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(path_try_exists)]
-    ///
     /// use std::path::Path;
     /// assert!(!Path::new("does_not_exist.txt").try_exists().expect("Can't check existence of file does_not_exist.txt"));
     /// assert!(Path::new("/root/secret_file.txt").try_exists().is_err());
     /// ```
     ///
     /// [`exists()`]: Self::exists
-    // FIXME: stabilization should modify documentation of `exists()` to recommend this method
-    // instead.
-    #[unstable(feature = "path_try_exists", issue = "83186")]
+    #[stable(feature = "path_try_exists", since = "1.63.0")]
     #[inline]
     pub fn try_exists(&self) -> io::Result<bool> {
         fs::try_exists(self)
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index da8eee9030b..ab1a1e6c76f 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1273,6 +1273,22 @@ impl Stdio {
     pub fn null() -> Stdio {
         Stdio(imp::Stdio::Null)
     }
+
+    /// Returns `true` if this requires [`Command`] to create a new pipe.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// #![feature(stdio_makes_pipe)]
+    /// use std::process::Stdio;
+    ///
+    /// let io = Stdio::piped();
+    /// assert_eq!(io.makes_pipe(), true);
+    /// ```
+    #[unstable(feature = "stdio_makes_pipe", issue = "98288")]
+    pub fn makes_pipe(&self) -> bool {
+        matches!(self.0, imp::Stdio::MakePipe)
+    }
 }
 
 impl FromInner<imp::Stdio> for Stdio {
diff --git a/library/std/src/sync/condvar.rs b/library/std/src/sync/condvar.rs
index 7ff2f330f8a..eb1e7135a6e 100644
--- a/library/std/src/sync/condvar.rs
+++ b/library/std/src/sync/condvar.rs
@@ -122,8 +122,10 @@ impl Condvar {
     /// let condvar = Condvar::new();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
     #[must_use]
-    pub fn new() -> Condvar {
+    #[inline]
+    pub const fn new() -> Condvar {
         Condvar { inner: sys::Condvar::new() }
     }
 
diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs
index 31342a89054..e0d13cd648c 100644
--- a/library/std/src/sync/mutex.rs
+++ b/library/std/src/sync/mutex.rs
@@ -213,7 +213,9 @@ impl<T> Mutex<T> {
     /// let mutex = Mutex::new(0);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new(t: T) -> Mutex<T> {
+    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
+    #[inline]
+    pub const fn new(t: T) -> Mutex<T> {
         Mutex {
             inner: sys::MovableMutex::new(),
             poison: poison::Flag::new(),
diff --git a/library/std/src/sync/poison.rs b/library/std/src/sync/poison.rs
index 9c918be3387..741312d5537 100644
--- a/library/std/src/sync/poison.rs
+++ b/library/std/src/sync/poison.rs
@@ -19,6 +19,7 @@ pub struct Flag {
 // all cases.
 
 impl Flag {
+    #[inline]
     pub const fn new() -> Flag {
         Flag { failed: AtomicBool::new(false) }
     }
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index 9517e7e1f03..1192c08cb1a 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -146,7 +146,9 @@ impl<T> RwLock<T> {
     /// let lock = RwLock::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new(t: T) -> RwLock<T> {
+    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
+    #[inline]
+    pub const fn new(t: T) -> RwLock<T> {
         RwLock {
             inner: sys::MovableRwLock::new(),
             poison: poison::Flag::new(),
diff --git a/library/std/src/sys/itron/mutex.rs b/library/std/src/sys/itron/mutex.rs
index 2ba8454ff92..715e94c3b3d 100644
--- a/library/std/src/sys/itron/mutex.rs
+++ b/library/std/src/sys/itron/mutex.rs
@@ -26,6 +26,7 @@ fn new_mtx() -> Result<abi::ID, ItronError> {
 }
 
 impl Mutex {
+    #[inline]
     pub const fn new() -> Mutex {
         Mutex { mtx: SpinIdOnceCell::new() }
     }
diff --git a/library/std/src/sys/solid/rwlock.rs b/library/std/src/sys/solid/rwlock.rs
index 433abc895f5..0a770cf03f2 100644
--- a/library/std/src/sys/solid/rwlock.rs
+++ b/library/std/src/sys/solid/rwlock.rs
@@ -23,6 +23,7 @@ fn new_rwl() -> Result<abi::ID, ItronError> {
 }
 
 impl RwLock {
+    #[inline]
     pub const fn new() -> RwLock {
         RwLock { rwl: SpinIdOnceCell::new() }
     }
diff --git a/library/std/src/sys/unsupported/locks/condvar.rs b/library/std/src/sys/unsupported/locks/condvar.rs
index f27bf2b26bd..e703fd0d269 100644
--- a/library/std/src/sys/unsupported/locks/condvar.rs
+++ b/library/std/src/sys/unsupported/locks/condvar.rs
@@ -6,6 +6,7 @@ pub struct Condvar {}
 pub type MovableCondvar = Condvar;
 
 impl Condvar {
+    #[inline]
     pub const fn new() -> Condvar {
         Condvar {}
     }
diff --git a/library/std/src/sys/unsupported/locks/mutex.rs b/library/std/src/sys/unsupported/locks/mutex.rs
index 56bad71b189..d7cb12e0cf9 100644
--- a/library/std/src/sys/unsupported/locks/mutex.rs
+++ b/library/std/src/sys/unsupported/locks/mutex.rs
@@ -11,6 +11,7 @@ unsafe impl Send for Mutex {}
 unsafe impl Sync for Mutex {} // no threads on this platform
 
 impl Mutex {
+    #[inline]
     pub const fn new() -> Mutex {
         Mutex { locked: Cell::new(false) }
     }
diff --git a/library/std/src/sys/unsupported/locks/rwlock.rs b/library/std/src/sys/unsupported/locks/rwlock.rs
index bf6e2d3d080..aca5fb7152c 100644
--- a/library/std/src/sys/unsupported/locks/rwlock.rs
+++ b/library/std/src/sys/unsupported/locks/rwlock.rs
@@ -11,6 +11,7 @@ unsafe impl Send for RwLock {}
 unsafe impl Sync for RwLock {} // no threads on this platform
 
 impl RwLock {
+    #[inline]
     pub const fn new() -> RwLock {
         RwLock { mode: Cell::new(0) }
     }
diff --git a/library/std/src/sys/windows/locks/condvar.rs b/library/std/src/sys/windows/locks/condvar.rs
index 59e2c1be0f0..be9a2abbe35 100644
--- a/library/std/src/sys/windows/locks/condvar.rs
+++ b/library/std/src/sys/windows/locks/condvar.rs
@@ -14,6 +14,7 @@ unsafe impl Send for Condvar {}
 unsafe impl Sync for Condvar {}
 
 impl Condvar {
+    #[inline]
     pub const fn new() -> Condvar {
         Condvar { inner: UnsafeCell::new(c::CONDITION_VARIABLE_INIT) }
     }
diff --git a/library/std/src/sys/windows/locks/mutex.rs b/library/std/src/sys/windows/locks/mutex.rs
index 08f55844a0e..f91e8f9f59a 100644
--- a/library/std/src/sys/windows/locks/mutex.rs
+++ b/library/std/src/sys/windows/locks/mutex.rs
@@ -33,6 +33,7 @@ pub unsafe fn raw(m: &Mutex) -> c::PSRWLOCK {
 }
 
 impl Mutex {
+    #[inline]
     pub const fn new() -> Mutex {
         Mutex { srwlock: UnsafeCell::new(c::SRWLOCK_INIT) }
     }
diff --git a/library/std/src/sys/windows/locks/rwlock.rs b/library/std/src/sys/windows/locks/rwlock.rs
index a32df85e2f6..fa5ffe5749f 100644
--- a/library/std/src/sys/windows/locks/rwlock.rs
+++ b/library/std/src/sys/windows/locks/rwlock.rs
@@ -11,6 +11,7 @@ unsafe impl Send for RwLock {}
 unsafe impl Sync for RwLock {}
 
 impl RwLock {
+    #[inline]
     pub const fn new() -> RwLock {
         RwLock { inner: UnsafeCell::new(c::SRWLOCK_INIT) }
     }
diff --git a/library/std/src/sys_common/condvar.rs b/library/std/src/sys_common/condvar.rs
index 1def0518e0a..f3ac1061b89 100644
--- a/library/std/src/sys_common/condvar.rs
+++ b/library/std/src/sys_common/condvar.rs
@@ -14,7 +14,8 @@ pub struct Condvar {
 
 impl Condvar {
     /// Creates a new condition variable for use.
-    pub fn new() -> Self {
+    #[inline]
+    pub const fn new() -> Self {
         Self { inner: imp::MovableCondvar::new(), check: CondvarCheck::new() }
     }
 
diff --git a/library/std/src/sys_common/mutex.rs b/library/std/src/sys_common/mutex.rs
index 36ea888d8de..48479f5bdb3 100644
--- a/library/std/src/sys_common/mutex.rs
+++ b/library/std/src/sys_common/mutex.rs
@@ -15,6 +15,7 @@ unsafe impl Sync for StaticMutex {}
 
 impl StaticMutex {
     /// Creates a new mutex for use.
+    #[inline]
     pub const fn new() -> Self {
         Self(imp::Mutex::new())
     }
@@ -45,13 +46,12 @@ impl Drop for StaticMutexGuard {
 
 /// An OS-based mutual exclusion lock.
 ///
-/// This mutex does *not* have a const constructor, cleans up its resources in
-/// its `Drop` implementation, may safely be moved (when not borrowed), and
-/// does not cause UB when used reentrantly.
+/// This mutex cleans up its resources in its `Drop` implementation, may safely
+/// be moved (when not borrowed), and does not cause UB when used reentrantly.
 ///
 /// This mutex does not implement poisoning.
 ///
-/// This is either a wrapper around `Box<imp::Mutex>` or `imp::Mutex`,
+/// This is either a wrapper around `LazyBox<imp::Mutex>` or `imp::Mutex`,
 /// depending on the platform. It is boxed on platforms where `imp::Mutex` may
 /// not be moved.
 pub struct MovableMutex(imp::MovableMutex);
@@ -60,7 +60,8 @@ unsafe impl Sync for MovableMutex {}
 
 impl MovableMutex {
     /// Creates a new mutex.
-    pub fn new() -> Self {
+    #[inline]
+    pub const fn new() -> Self {
         Self(imp::MovableMutex::new())
     }
 
diff --git a/library/std/src/sys_common/rwlock.rs b/library/std/src/sys_common/rwlock.rs
index abc9fd561f1..ba56f3a8f1b 100644
--- a/library/std/src/sys_common/rwlock.rs
+++ b/library/std/src/sys_common/rwlock.rs
@@ -10,6 +10,7 @@ pub struct StaticRwLock(imp::RwLock);
 
 impl StaticRwLock {
     /// Creates a new rwlock for use.
+    #[inline]
     pub const fn new() -> Self {
         Self(imp::RwLock::new())
     }
@@ -61,19 +62,20 @@ impl Drop for StaticRwLockWriteGuard {
 
 /// An OS-based reader-writer lock.
 ///
-/// This rwlock does *not* have a const constructor, cleans up its resources in
-/// its `Drop` implementation and may safely be moved (when not borrowed).
+/// This rwlock cleans up its resources in its `Drop` implementation and may
+/// safely be moved (when not borrowed).
 ///
 /// This rwlock does not implement poisoning.
 ///
-/// This is either a wrapper around `Box<imp::RwLock>` or `imp::RwLock`,
+/// This is either a wrapper around `LazyBox<imp::RwLock>` or `imp::RwLock`,
 /// depending on the platform. It is boxed on platforms where `imp::RwLock` may
 /// not be moved.
 pub struct MovableRwLock(imp::MovableRwLock);
 
 impl MovableRwLock {
     /// Creates a new reader-writer lock for use.
-    pub fn new() -> Self {
+    #[inline]
+    pub const fn new() -> Self {
         Self(imp::MovableRwLock::new())
     }
 
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index f7af66ae5b5..0a6a7cfe976 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -1487,13 +1487,14 @@ impl<T> JoinHandle<T> {
 
     /// Checks if the associated thread has finished running its main function.
     ///
+    /// `is_finished` supports implementing a non-blocking join operation, by checking
+    /// `is_finished`, and calling `join` if it returns `true`. This function does not block. To
+    /// block while waiting on the thread to finish, use [`join`][Self::join].
+    ///
     /// This might return `true` for a brief moment after the thread's main
     /// function has returned, but before the thread itself has stopped running.
     /// However, once this returns `true`, [`join`][Self::join] can be expected
     /// to return quickly, without blocking for any significant amount of time.
-    ///
-    /// This function does not block. To block while waiting on the thread to finish,
-    /// use [`join`][Self::join].
     #[stable(feature = "thread_is_running", since = "1.61.0")]
     pub fn is_finished(&self) -> bool {
         Arc::strong_count(&self.0.packet) == 1
diff --git a/library/std/src/thread/scoped.rs b/library/std/src/thread/scoped.rs
index 4fd076e4a2d..a387a09dc8b 100644
--- a/library/std/src/thread/scoped.rs
+++ b/library/std/src/thread/scoped.rs
@@ -308,13 +308,14 @@ impl<'scope, T> ScopedJoinHandle<'scope, T> {
 
     /// Checks if the associated thread has finished running its main function.
     ///
+    /// `is_finished` supports implementing a non-blocking join operation, by checking
+    /// `is_finished`, and calling `join` if it returns `false`. This function does not block. To
+    /// block while waiting on the thread to finish, use [`join`][Self::join].
+    ///
     /// This might return `true` for a brief moment after the thread's main
     /// function has returned, but before the thread itself has stopped running.
     /// However, once this returns `true`, [`join`][Self::join] can be expected
     /// to return quickly, without blocking for any significant amount of time.
-    ///
-    /// This function does not block. To block while waiting on the thread to finish,
-    /// use [`join`][Self::join].
     #[stable(feature = "scoped_threads", since = "1.63.0")]
     pub fn is_finished(&self) -> bool {
         Arc::strong_count(&self.0.packet) == 1
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index f5d9e46f9e2..ed5c59a2595 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -51,6 +51,7 @@ ignore = "0.4.10"
 opener = "0.5"
 once_cell = "1.7.2"
 xz2 = "0.1"
+walkdir = "2"
 
 # Dependencies needed by the build-metrics feature
 sysinfo = { version = "0.24.1", optional = true }
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index b5901ce6f74..b1fae356d89 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -845,7 +845,12 @@ impl Step for PlainSourceTarball {
 
     /// Creates the plain source tarball
     fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
-        let tarball = Tarball::new(builder, "rustc", "src");
+        // NOTE: This is a strange component in a lot of ways. It uses `src` as the target, which
+        // means neither rustup nor rustup-toolchain-install-master know how to download it.
+        // It also contains symbolic links, unlike other any other dist tarball.
+        // It's used for distros building rustc from source in a pre-vendored environment.
+        let mut tarball = Tarball::new(builder, "rustc", "src");
+        tarball.permit_symlinks(true);
         let plain_dst_src = tarball.image_dir();
 
         // This is the set of root paths which will become part of the source package
@@ -1847,7 +1852,6 @@ fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) {
 
 /// Maybe add LLVM object files to the given destination lib-dir. Allows either static or dynamic linking.
 ///
-
 /// Returns whether the files were actually copied.
 fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir: &Path) -> bool {
     if let Some(config) = builder.config.target_config.get(&target) {
@@ -1957,6 +1961,8 @@ impl Step for LlvmTools {
             }
         }
 
+        builder.ensure(crate::native::Llvm { target });
+
         let mut tarball = Tarball::new(builder, "llvm-tools", &target.triple);
         tarball.set_overlay(OverlayKind::LLVM);
         tarball.is_preview(true);
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index b3ebc991653..4ac857b470e 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -1427,6 +1427,10 @@ impl Build {
 
     /// Copies a file from `src` to `dst`
     pub fn copy(&self, src: &Path, dst: &Path) {
+        self.copy_internal(src, dst, false);
+    }
+
+    fn copy_internal(&self, src: &Path, dst: &Path, dereference_symlinks: bool) {
         if self.config.dry_run {
             return;
         }
@@ -1436,15 +1440,22 @@ impl Build {
         }
         let _ = fs::remove_file(&dst);
         let metadata = t!(src.symlink_metadata());
+        let mut src = src.to_path_buf();
         if metadata.file_type().is_symlink() {
-            let link = t!(fs::read_link(src));
-            t!(symlink_file(link, dst));
-        } else if let Ok(()) = fs::hard_link(src, dst) {
+            if dereference_symlinks {
+                src = t!(fs::canonicalize(src));
+            } else {
+                let link = t!(fs::read_link(src));
+                t!(symlink_file(link, dst));
+                return;
+            }
+        }
+        if let Ok(()) = fs::hard_link(&src, dst) {
             // Attempt to "easy copy" by creating a hard link
             // (symlinks don't work on windows), but if that fails
             // just fall back to a slow `copy` operation.
         } else {
-            if let Err(e) = fs::copy(src, dst) {
+            if let Err(e) = fs::copy(&src, dst) {
                 panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e)
             }
             t!(fs::set_permissions(dst, metadata.permissions()));
@@ -1516,20 +1527,10 @@ impl Build {
         let dst = dstdir.join(src.file_name().unwrap());
         self.verbose_than(1, &format!("Install {:?} to {:?}", src, dst));
         t!(fs::create_dir_all(dstdir));
-        drop(fs::remove_file(&dst));
-        {
-            if !src.exists() {
-                panic!("Error: File \"{}\" not found!", src.display());
-            }
-            let metadata = t!(src.symlink_metadata());
-            if let Err(e) = fs::copy(&src, &dst) {
-                panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e)
-            }
-            t!(fs::set_permissions(&dst, metadata.permissions()));
-            let atime = FileTime::from_last_access_time(&metadata);
-            let mtime = FileTime::from_last_modification_time(&metadata);
-            t!(filetime::set_file_times(&dst, atime, mtime));
+        if !src.exists() {
+            panic!("Error: File \"{}\" not found!", src.display());
         }
+        self.copy_internal(src, &dst, true);
         chmod(&dst, perms);
     }
 
diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs
index 689b4819cdd..7b0c029c191 100644
--- a/src/bootstrap/tarball.rs
+++ b/src/bootstrap/tarball.rs
@@ -102,6 +102,7 @@ pub(crate) struct Tarball<'a> {
 
     include_target_in_component_name: bool,
     is_preview: bool,
+    permit_symlinks: bool,
 }
 
 impl<'a> Tarball<'a> {
@@ -141,6 +142,7 @@ impl<'a> Tarball<'a> {
 
             include_target_in_component_name: false,
             is_preview: false,
+            permit_symlinks: false,
         }
     }
 
@@ -160,6 +162,10 @@ impl<'a> Tarball<'a> {
         self.is_preview = is;
     }
 
+    pub(crate) fn permit_symlinks(&mut self, flag: bool) {
+        self.permit_symlinks = flag;
+    }
+
     pub(crate) fn image_dir(&self) -> &Path {
         t!(std::fs::create_dir_all(&self.image_dir));
         &self.image_dir
@@ -316,6 +322,18 @@ impl<'a> Tarball<'a> {
         }
         self.builder.run(&mut cmd);
 
+        // Ensure there are no symbolic links in the tarball. In particular,
+        // rustup-toolchain-install-master and most versions of Windows can't handle symbolic links.
+        let decompressed_output = self.temp_dir.join(&package_name);
+        if !self.builder.config.dry_run && !self.permit_symlinks {
+            for entry in walkdir::WalkDir::new(&decompressed_output) {
+                let entry = t!(entry);
+                if entry.path_is_symlink() {
+                    panic!("generated a symlink in a tarball: {}", entry.path().display());
+                }
+            }
+        }
+
         // Use either the first compression format defined, or "gz" as the default.
         let ext = self
             .builder
@@ -328,7 +346,7 @@ impl<'a> Tarball<'a> {
 
         GeneratedTarball {
             path: crate::dist::distdir(self.builder).join(format!("{}.tar.{}", package_name, ext)),
-            decompressed_output: self.temp_dir.join(package_name),
+            decompressed_output,
             work: self.temp_dir,
         }
     }
diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md
index 86bedb51538..39238dffa10 100644
--- a/src/doc/unstable-book/src/language-features/lang-items.md
+++ b/src/doc/unstable-book/src/language-features/lang-items.md
@@ -23,8 +23,10 @@ use core::panic::PanicInfo;
 
 extern crate libc;
 
+struct Unique<T>(*mut T);
+
 #[lang = "owned_box"]
-pub struct Box<T>(*mut T);
+pub struct Box<T>(Unique<T>);
 
 #[lang = "exchange_malloc"]
 unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py
index f762e389005..70b6af717cd 100644
--- a/src/etc/htmldocck.py
+++ b/src/etc/htmldocck.py
@@ -417,7 +417,7 @@ def check_snapshot(snapshot_name, actual_tree, normalize_to_text):
     snapshot_path = '{}.{}.{}'.format(rust_test_path[:-3], snapshot_name, 'html')
     try:
         with open(snapshot_path, 'r') as snapshot_file:
-            expected_str = snapshot_file.read()
+            expected_str = snapshot_file.read().replace("{{channel}}", channel)
     except FileNotFoundError:
         if bless:
             expected_str = None
@@ -429,8 +429,6 @@ def check_snapshot(snapshot_name, actual_tree, normalize_to_text):
     else:
         actual_str = flatten(actual_tree)
 
-    expected_str = expected_str.replace("{{channel}}", channel)
-
     # Conditions:
     #  1. Is --bless
     #  2. Are actual and expected tree different
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 86c58cd79dc..ab72f4a3f50 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -365,8 +365,8 @@ fn run_test(
     }
     compiler.arg("--target").arg(match target {
         TargetTriple::TargetTriple(s) => s,
-        TargetTriple::TargetPath(path) => {
-            path.to_str().expect("target path must be valid unicode").to_string()
+        TargetTriple::TargetJson { path_for_rustdoc, .. } => {
+            path_for_rustdoc.to_str().expect("target path must be valid unicode").to_string()
         }
     });
     if let ErrorOutputType::HumanReadable(kind) = rustdoc_options.error_format {
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 0c0920ae63e..5baa53d5554 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -23,6 +23,8 @@ use rustc_span::symbol::kw;
 use rustc_span::{sym, Symbol};
 use rustc_target::spec::abi::Abi;
 
+use itertools::Itertools;
+
 use crate::clean::{
     self, types::ExternalLocation, utils::find_nearest_parent_module, ExternalCrate, ItemId,
     PrimitiveType,
@@ -874,20 +876,42 @@ fn fmt_type<'cx>(
             match &typs[..] {
                 &[] => primitive_link(f, PrimitiveType::Unit, "()", cx),
                 &[ref one] => {
-                    primitive_link(f, PrimitiveType::Tuple, "(", cx)?;
-                    // Carry `f.alternate()` into this display w/o branching manually.
-                    fmt::Display::fmt(&one.print(cx), f)?;
-                    primitive_link(f, PrimitiveType::Tuple, ",)", cx)
+                    if let clean::Generic(name) = one {
+                        primitive_link(f, PrimitiveType::Tuple, &format!("({name},)"), cx)
+                    } else {
+                        write!(f, "(")?;
+                        // Carry `f.alternate()` into this display w/o branching manually.
+                        fmt::Display::fmt(&one.print(cx), f)?;
+                        write!(f, ",)")
+                    }
                 }
                 many => {
-                    primitive_link(f, PrimitiveType::Tuple, "(", cx)?;
-                    for (i, item) in many.iter().enumerate() {
-                        if i != 0 {
-                            write!(f, ", ")?;
+                    let generic_names: Vec<Symbol> = many
+                        .iter()
+                        .filter_map(|t| match t {
+                            clean::Generic(name) => Some(*name),
+                            _ => None,
+                        })
+                        .collect();
+                    let is_generic = generic_names.len() == many.len();
+                    if is_generic {
+                        primitive_link(
+                            f,
+                            PrimitiveType::Tuple,
+                            &format!("({})", generic_names.iter().map(|s| s.as_str()).join(", ")),
+                            cx,
+                        )
+                    } else {
+                        write!(f, "(")?;
+                        for (i, item) in many.iter().enumerate() {
+                            if i != 0 {
+                                write!(f, ", ")?;
+                            }
+                            // Carry `f.alternate()` into this display w/o branching manually.
+                            fmt::Display::fmt(&item.print(cx), f)?;
                         }
-                        fmt::Display::fmt(&item.print(cx), f)?;
+                        write!(f, ")")
                     }
-                    primitive_link(f, PrimitiveType::Tuple, ")", cx)
                 }
             }
         }
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index de54347a0f7..7d6d4b71e2e 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -31,8 +31,6 @@ pub(crate) struct Page<'a> {
     pub(crate) description: &'a str,
     pub(crate) keywords: &'a str,
     pub(crate) resource_suffix: &'a str,
-    pub(crate) extra_scripts: &'a [&'a str],
-    pub(crate) static_extra_scripts: &'a [&'a str],
 }
 
 impl<'a> Page<'a> {
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 68e2f0cf9c0..bfdc44c7e45 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -211,8 +211,6 @@ impl<'tcx> Context<'tcx> {
                 description: &desc,
                 keywords: &keywords,
                 resource_suffix: &clone_shared.resource_suffix,
-                extra_scripts: &[],
-                static_extra_scripts: &[],
             };
             let mut page_buffer = Buffer::html();
             print_item(self, it, &mut page_buffer, &page);
@@ -568,8 +566,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             description: "List of all items in this crate",
             keywords: BASIC_KEYWORDS,
             resource_suffix: &shared.resource_suffix,
-            extra_scripts: &[],
-            static_extra_scripts: &[],
         };
         let sidebar = if shared.cache.crate_version.is_some() {
             format!("<h2 class=\"location\">Crate {}</h2>", crate_name)
@@ -693,7 +689,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             else { unreachable!() };
             let items = self.build_sidebar_items(module);
             let js_dst = self.dst.join(&format!("sidebar-items{}.js", self.shared.resource_suffix));
-            let v = format!("initSidebarItems({});", serde_json::to_string(&items).unwrap());
+            let v = format!("window.SIDEBAR_ITEMS = {};", serde_json::to_string(&items).unwrap());
             self.shared.fs.write(js_dst, v)?;
         }
         Ok(())
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index cb887d16906..3f426ee93e7 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -56,7 +56,7 @@ use rustc_middle::middle::stability;
 use rustc_middle::ty;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::{
-    symbol::{kw, sym, Symbol},
+    symbol::{sym, Symbol},
     BytePos, FileName, RealFileName,
 };
 use serde::ser::SerializeSeq;
@@ -1738,8 +1738,6 @@ pub(crate) fn render_impl_summary(
 }
 
 fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) {
-    let parentlen = cx.current.len() - if it.is_mod() { 1 } else { 0 };
-
     if it.is_struct()
         || it.is_trait()
         || it.is_primitive()
@@ -1800,21 +1798,6 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) {
         write!(buffer, "<h2 class=\"location\"><a href=\"index.html\">In {}</a></h2>", path);
     }
 
-    // Sidebar refers to the enclosing module, not this module.
-    let relpath = if it.is_mod() && parentlen != 0 { "./" } else { "" };
-    write!(
-        buffer,
-        "<div id=\"sidebar-vars\" data-name=\"{name}\" data-ty=\"{ty}\" data-relpath=\"{path}\">\
-        </div>",
-        name = it.name.unwrap_or(kw::Empty),
-        ty = it.type_(),
-        path = relpath
-    );
-    write!(
-        buffer,
-        "<script defer src=\"{}sidebar-items{}.js\"></script>",
-        relpath, cx.shared.resource_suffix
-    );
     // Closes sidebar-elems div.
     buffer.write_str("</div>");
 }
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 9bddee199c7..27ad91d09e0 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -475,8 +475,6 @@ if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
                 description: "List of crates",
                 keywords: BASIC_KEYWORDS,
                 resource_suffix: &shared.resource_suffix,
-                extra_scripts: &[],
-                static_extra_scripts: &[],
             };
 
             let content = format!(
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 524c90e1f4d..1971d08e5be 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -203,8 +203,6 @@ impl SourceCollector<'_, '_> {
             description: &desc,
             keywords: BASIC_KEYWORDS,
             resource_suffix: &shared.resource_suffix,
-            extra_scripts: &[&format!("source-files{}", shared.resource_suffix)],
-            static_extra_scripts: &[&format!("source-script{}", shared.resource_suffix)],
         };
         let v = layout::render(
             &shared.layout,
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 414bca850e3..b320db91046 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -66,26 +66,18 @@ function showMain() {
 (function() {
     window.rootPath = getVar("root-path");
     window.currentCrate = getVar("current-crate");
-    window.searchJS =  resourcePath("search", ".js");
-    window.searchIndexJS = resourcePath("search-index", ".js");
-    window.settingsJS = resourcePath("settings", ".js");
-    const sidebarVars = document.getElementById("sidebar-vars");
-    if (sidebarVars) {
-        window.sidebarCurrent = {
-            name: sidebarVars.attributes["data-name"].value,
-            ty: sidebarVars.attributes["data-ty"].value,
-            relpath: sidebarVars.attributes["data-relpath"].value,
-        };
-        // FIXME: It would be nicer to generate this text content directly in HTML,
-        // but with the current code it's hard to get the right information in the right place.
-        const mobileLocationTitle = document.querySelector(".mobile-topbar h2.location");
-        const locationTitle = document.querySelector(".sidebar h2.location");
-        if (mobileLocationTitle && locationTitle) {
-            mobileLocationTitle.innerHTML = locationTitle.innerHTML;
-        }
-    }
 }());
 
+function setMobileTopbar() {
+    // FIXME: It would be nicer to generate this text content directly in HTML,
+    // but with the current code it's hard to get the right information in the right place.
+    const mobileLocationTitle = document.querySelector(".mobile-topbar h2.location");
+    const locationTitle = document.querySelector(".sidebar h2.location");
+    if (mobileLocationTitle && locationTitle) {
+        mobileLocationTitle.innerHTML = locationTitle.innerHTML;
+    }
+}
+
 // Gets the human-readable string for the virtual-key code of the
 // given KeyboardEvent, ev.
 //
@@ -227,7 +219,7 @@ function loadCss(cssFileName) {
         // Sending request for the CSS and the JS files at the same time so it will
         // hopefully be loaded when the JS will generate the settings content.
         loadCss("settings");
-        loadScript(window.settingsJS);
+        loadScript(resourcePath("settings", ".js"));
     };
 
     window.searchState = {
@@ -304,8 +296,8 @@ function loadCss(cssFileName) {
             function loadSearch() {
                 if (!searchLoaded) {
                     searchLoaded = true;
-                    loadScript(window.searchJS);
-                    loadScript(window.searchIndexJS);
+                    loadScript(resourcePath("search", ".js"));
+                    loadScript(resourcePath("search-index", ".js"));
                 }
             }
 
@@ -485,40 +477,11 @@ function loadCss(cssFileName) {
     document.addEventListener("keypress", handleShortcut);
     document.addEventListener("keydown", handleShortcut);
 
-    // delayed sidebar rendering.
-    window.initSidebarItems = items => {
-        const sidebar = document.getElementsByClassName("sidebar-elems")[0];
-        let others;
-        const current = window.sidebarCurrent;
-
-        function addSidebarCrates(crates) {
-            if (!hasClass(document.body, "crate")) {
-                // We only want to list crates on the crate page.
-                return;
-            }
-            // Draw a convenient sidebar of known crates if we have a listing
-            const div = document.createElement("div");
-            div.className = "block crate";
-            div.innerHTML = "<h3>Crates</h3>";
-            const ul = document.createElement("ul");
-            div.appendChild(ul);
-
-            for (const crate of crates) {
-                let klass = "crate";
-                if (window.rootPath !== "./" && crate === window.currentCrate) {
-                    klass += " current";
-                }
-                const link = document.createElement("a");
-                link.href = window.rootPath + crate + "/index.html";
-                link.className = klass;
-                link.textContent = crate;
-
-                const li = document.createElement("li");
-                li.appendChild(link);
-                ul.appendChild(li);
-            }
-            others.appendChild(div);
+    function addSidebarItems() {
+        if (!window.SIDEBAR_ITEMS) {
+            return;
         }
+        const sidebar = document.getElementsByClassName("sidebar-elems")[0];
 
         /**
          * Append to the sidebar a "block" of links - a heading along with a list (`<ul>`) of items.
@@ -529,7 +492,7 @@ function loadCss(cssFileName) {
          *                          "Modules", or "Macros".
          */
         function block(shortty, id, longty) {
-            const filtered = items[shortty];
+            const filtered = window.SIDEBAR_ITEMS[shortty];
             if (!filtered) {
                 return;
             }
@@ -546,17 +509,18 @@ function loadCss(cssFileName) {
                 const desc = item[1]; // can be null
 
                 let klass = shortty;
-                if (name === current.name && shortty === current.ty) {
-                    klass += " current";
-                }
                 let path;
                 if (shortty === "mod") {
                     path = name + "/index.html";
                 } else {
                     path = shortty + "." + name + ".html";
                 }
+                const current_page = document.location.href.split("/").pop();
+                if (path === current_page) {
+                    klass += " current";
+                }
                 const link = document.createElement("a");
-                link.href = current.relpath + path;
+                link.href = path;
                 link.title = desc;
                 link.className = klass;
                 link.textContent = name;
@@ -565,14 +529,10 @@ function loadCss(cssFileName) {
                 ul.appendChild(li);
             }
             div.appendChild(ul);
-            others.appendChild(div);
+            sidebar.appendChild(div);
         }
 
         if (sidebar) {
-            others = document.createElement("div");
-            others.className = "others";
-            sidebar.appendChild(others);
-
             const isModule = hasClass(document.body, "mod");
             if (!isModule) {
                 block("primitive", "primitives", "Primitive Types");
@@ -590,12 +550,8 @@ function loadCss(cssFileName) {
                 block("keyword", "keywords", "Keywords");
                 block("traitalias", "trait-aliases", "Trait Aliases");
             }
-
-            // `crates{version}.js` should always be loaded before this script, so we can use
-            // it safely.
-            addSidebarCrates(window.ALL_CRATES);
         }
-    };
+    }
 
     window.register_implementors = imp => {
         const implementors = document.getElementById("implementors-list");
@@ -680,6 +636,39 @@ function loadCss(cssFileName) {
         window.register_implementors(window.pending_implementors);
     }
 
+    function addSidebarCrates() {
+        if (!window.ALL_CRATES) {
+            return;
+        }
+        const sidebarElems = document.getElementsByClassName("sidebar-elems")[0];
+        if (!sidebarElems) {
+            return;
+        }
+        // Draw a convenient sidebar of known crates if we have a listing
+        const div = document.createElement("div");
+        div.className = "block crate";
+        div.innerHTML = "<h3>Crates</h3>";
+        const ul = document.createElement("ul");
+        div.appendChild(ul);
+
+        for (const crate of window.ALL_CRATES) {
+            let klass = "crate";
+            if (window.rootPath !== "./" && crate === window.currentCrate) {
+                klass += " current";
+            }
+            const link = document.createElement("a");
+            link.href = window.rootPath + crate + "/index.html";
+            link.className = klass;
+            link.textContent = crate;
+
+            const li = document.createElement("li");
+            li.appendChild(link);
+            ul.appendChild(li);
+        }
+        sidebarElems.appendChild(div);
+    }
+
+
     function labelForToggleButton(sectionIsCollapsed) {
         if (sectionIsCollapsed) {
             // button will expand the section
@@ -924,6 +913,9 @@ function loadCss(cssFileName) {
         buildHelperPopup = () => {};
     };
 
+    setMobileTopbar();
+    addSidebarItems();
+    addSidebarCrates();
     onHashChange(null);
     window.addEventListener("hashchange", onHashChange);
     searchState.setup();
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index c0b274c0a3f..cb1609d4983 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -1719,10 +1719,11 @@ function initSearch(rawSearchIndex) {
         }
 
         let crates = "";
-        if (window.ALL_CRATES.length > 1) {
+        const crates_list = Object.keys(rawSearchIndex);
+        if (crates_list.length > 1) {
             crates = " in <select id=\"crate-search\"><option value=\"All crates\">" +
                 "All crates</option>";
-            for (const c of window.ALL_CRATES) {
+            for (const c of crates_list) {
                 crates += `<option value="${c}" ${c === filterCrates && "selected"}>${c}</option>`;
             }
             crates += "</select>";
diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js
index 14d8a942977..10f93a1c058 100644
--- a/src/librustdoc/html/static/js/source-script.js
+++ b/src/librustdoc/html/static/js/source-script.js
@@ -9,33 +9,19 @@
 
 (function() {
 
-function getCurrentFilePath() {
-    const parts = window.location.pathname.split("/");
-    const rootPathParts = window.rootPath.split("/");
+const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value;
 
-    for (const rootPathPart of rootPathParts) {
-        if (rootPathPart === "..") {
-            parts.pop();
-        }
-    }
-    let file = window.location.pathname.substring(parts.join("/").length);
-    if (file.startsWith("/")) {
-        file = file.substring(1);
-    }
-    return file.substring(0, file.length - 5);
-}
-
-function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) {
+function createDirEntry(elem, parent, fullPath, hasFoundFile) {
     const name = document.createElement("div");
     name.className = "name";
 
     fullPath += elem["name"] + "/";
 
-    name.onclick = () => {
-        if (hasClass(name, "expand")) {
-            removeClass(name, "expand");
+    name.onclick = ev => {
+        if (hasClass(ev.target, "expand")) {
+            removeClass(ev.target, "expand");
         } else {
-            addClass(name, "expand");
+            addClass(ev.target, "expand");
         }
     };
     name.innerText = elem["name"];
@@ -46,7 +32,7 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) {
     folders.className = "folders";
     if (elem.dirs) {
         for (const dir of elem.dirs) {
-            if (createDirEntry(dir, folders, fullPath, currentFile, hasFoundFile)) {
+            if (createDirEntry(dir, folders, fullPath, hasFoundFile)) {
                 addClass(name, "expand");
                 hasFoundFile = true;
             }
@@ -60,8 +46,9 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) {
         for (const file_text of elem.files) {
             const file = document.createElement("a");
             file.innerText = file_text;
-            file.href = window.rootPath + "src/" + fullPath + file_text + ".html";
-            if (!hasFoundFile && currentFile === fullPath + file_text) {
+            file.href = rootPath + "src/" + fullPath + file_text + ".html";
+            const w = window.location.href.split("#")[0];
+            if (!hasFoundFile && w === file.href) {
                 file.className = "selected";
                 addClass(name, "expand");
                 hasFoundFile = true;
@@ -72,7 +59,7 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) {
     children.appendChild(files);
     parent.appendChild(name);
     parent.appendChild(children);
-    return hasFoundFile && currentFile.startsWith(fullPath);
+    return hasFoundFile;
 }
 
 function toggleSidebar() {
@@ -109,9 +96,6 @@ function createSidebarToggle() {
 // This function is called from "source-files.js", generated in `html/render/mod.rs`.
 // eslint-disable-next-line no-unused-vars
 function createSourceSidebar() {
-    if (!window.rootPath.endsWith("/")) {
-        window.rootPath += "/";
-    }
     const container = document.querySelector("nav.sidebar");
 
     const sidebarToggle = createSidebarToggle();
@@ -125,7 +109,6 @@ function createSourceSidebar() {
         container.classList.add("expanded");
     }
 
-    const currentFile = getCurrentFilePath();
     let hasFoundFile = false;
 
     const title = document.createElement("div");
@@ -135,7 +118,7 @@ function createSourceSidebar() {
     Object.keys(sourcesIndex).forEach(key => {
         sourcesIndex[key].name = key;
         hasFoundFile = createDirEntry(sourcesIndex[key], sidebar, "",
-                                      currentFile, hasFoundFile);
+            hasFoundFile);
     });
 
     container.appendChild(sidebar);
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index cd672aadd7e..c4999e2c74f 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -34,17 +34,18 @@
       {%- endfor -%}
     ></script> {#- -#}
     <script src="{{static_root_path|safe}}storage{{page.resource_suffix}}.js"></script> {#- -#}
-    <script src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {#- -#}
+    {%- if page.css_class.contains("crate") -%}
+    <script defer src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {#- -#}
+    {%- else if page.css_class == "source" -%}
+    <script defer src="{{static_root_path|safe}}source-script{{page.resource_suffix}}.js"></script> {#- -#}
+    <script defer src="{{page.root_path|safe}}source-files{{page.resource_suffix}}.js"></script> {#- -#}
+    {%- else -%}
+    <script defer src="sidebar-items{{page.resource_suffix}}.js"></script> {#- -#}
+    {%- endif -%}
     <script defer src="{{static_root_path|safe}}main{{page.resource_suffix}}.js"></script> {#- -#}
-    {%- for script in page.static_extra_scripts -%}
-    <script defer src="{{static_root_path|safe}}{{script}}.js"></script> {#- -#}
-    {% endfor %}
     {%- if layout.scrape_examples_extension -%}
     <script defer src="{{page.root_path|safe}}scrape-examples{{page.resource_suffix}}.js"></script> {#- -#}
     {%- endif -%}
-    {%- for script in page.extra_scripts -%}
-    <script defer src="{{page.root_path|safe}}{{script}}.js"></script> {#- -#}
-    {% endfor %}
     <noscript> {#- -#}
         <link rel="stylesheet" {# -#}
            href="{{static_root_path|safe}}noscript{{page.resource_suffix}}.css"> {#- -#}
diff --git a/src/test/codegen/loads.rs b/src/test/codegen/loads.rs
index 07de385193f..f448306ba1b 100644
--- a/src/test/codegen/loads.rs
+++ b/src/test/codegen/loads.rs
@@ -28,93 +28,93 @@ pub fn ptr_alignment_helper(x: &&()) {}
 // CHECK-LABEL: @load_ref
 #[no_mangle]
 pub fn load_ref<'a>(x: &&'a i32) -> &'a i32 {
-// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META:[0-9]+]], !noundef !{{[0-9]+}}
+    // CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META:[0-9]+]], !noundef !{{[0-9]+}}
     *x
 }
 
 // CHECK-LABEL: @load_ref_higher_alignment
 #[no_mangle]
 pub fn load_ref_higher_alignment<'a>(x: &&'a Align16) -> &'a Align16 {
-// CHECK: load {{%Align16\*|i128\*|ptr}}, {{%Align16\*\*|i128\*\*|ptr}} %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META:[0-9]+]], !noundef !{{[0-9]+}}
+    // CHECK: load {{%Align16\*|i128\*|ptr}}, {{%Align16\*\*|i128\*\*|ptr}} %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META:[0-9]+]], !noundef !{{[0-9]+}}
     *x
 }
 
 // CHECK-LABEL: @load_scalar_pair
 #[no_mangle]
 pub fn load_scalar_pair<'a>(x: &(&'a i32, &'a Align16)) -> (&'a i32, &'a Align16) {
-// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}}
-// CHECK: load {{i64\*|ptr}}, {{i64\*\*|ptr}} %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META]], !noundef !{{[0-9]+}}
+    // CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}}
+    // CHECK: load {{i64\*|ptr}}, {{i64\*\*|ptr}} %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META]], !noundef !{{[0-9]+}}
     *x
 }
 
 // CHECK-LABEL: @load_raw_pointer
 #[no_mangle]
 pub fn load_raw_pointer<'a>(x: &*const i32) -> *const i32 {
-// loaded raw pointer should not have !nonnull, !align, or !noundef metadata
-// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x, align [[PTR_ALIGNMENT]]{{$}}
+    // loaded raw pointer should not have !nonnull, !align, or !noundef metadata
+    // CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x, align [[PTR_ALIGNMENT]]{{$}}
     *x
 }
 
 // CHECK-LABEL: @load_box
 #[no_mangle]
 pub fn load_box<'a>(x: Box<Box<i32>>) -> Box<i32> {
-// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}}
+    // CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %{{.*}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}}
     *x
 }
 
 // CHECK-LABEL: @load_bool
 #[no_mangle]
 pub fn load_bool(x: &bool) -> bool {
-// CHECK: load i8, {{i8\*|ptr}} %x, align 1, !range ![[BOOL_RANGE:[0-9]+]], !noundef !{{[0-9]+}}
+    // CHECK: load i8, {{i8\*|ptr}} %x, align 1, !range ![[BOOL_RANGE:[0-9]+]], !noundef !{{[0-9]+}}
     *x
 }
 
 // CHECK-LABEL: @load_maybeuninit_bool
 #[no_mangle]
 pub fn load_maybeuninit_bool(x: &MaybeUninit<bool>) -> MaybeUninit<bool> {
-// CHECK: load i8, {{i8\*|ptr}} %x, align 1{{$}}
+    // CHECK: load i8, {{i8\*|ptr}} %x, align 1{{$}}
     *x
 }
 
 // CHECK-LABEL: @load_enum_bool
 #[no_mangle]
 pub fn load_enum_bool(x: &MyBool) -> MyBool {
-// CHECK: load i8, {{i8\*|ptr}} %x, align 1, !range ![[BOOL_RANGE]], !noundef !{{[0-9]+}}
+    // CHECK: load i8, {{i8\*|ptr}} %x, align 1, !range ![[BOOL_RANGE]], !noundef !{{[0-9]+}}
     *x
 }
 
 // CHECK-LABEL: @load_maybeuninit_enum_bool
 #[no_mangle]
 pub fn load_maybeuninit_enum_bool(x: &MaybeUninit<MyBool>) -> MaybeUninit<MyBool> {
-// CHECK: load i8, {{i8\*|ptr}} %x, align 1{{$}}
+    // CHECK: load i8, {{i8\*|ptr}} %x, align 1{{$}}
     *x
 }
 
 // CHECK-LABEL: @load_int
 #[no_mangle]
 pub fn load_int(x: &u16) -> u16 {
-// CHECK: load i16, {{i16\*|ptr}} %x, align 2{{$}}
+    // CHECK: load i16, {{i16\*|ptr}} %x, align 2{{$}}
     *x
 }
 
 // CHECK-LABEL: @load_nonzero_int
 #[no_mangle]
 pub fn load_nonzero_int(x: &NonZeroU16) -> NonZeroU16 {
-// CHECK: load i16, {{i16\*|ptr}} %x, align 2, !range ![[NONZEROU16_RANGE:[0-9]+]], !noundef !{{[0-9]+}}
+    // CHECK: load i16, {{i16\*|ptr}} %x, align 2, !range ![[NONZEROU16_RANGE:[0-9]+]], !noundef !{{[0-9]+}}
     *x
 }
 
 // CHECK-LABEL: @load_option_nonzero_int
 #[no_mangle]
 pub fn load_option_nonzero_int(x: &Option<NonZeroU16>) -> Option<NonZeroU16> {
-// CHECK: load i16, {{i16\*|ptr}} %x, align 2{{$}}
+    // CHECK: load i16, {{i16\*|ptr}} %x, align 2{{$}}
     *x
 }
 
 // CHECK-LABEL: @borrow
 #[no_mangle]
 pub fn borrow(x: &i32) -> &i32 {
-// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x{{.*}}, !nonnull
+    // CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x{{.*}}, !nonnull
     &x; // keep variable in an alloca
     x
 }
@@ -122,7 +122,7 @@ pub fn borrow(x: &i32) -> &i32 {
 // CHECK-LABEL: @_box
 #[no_mangle]
 pub fn _box(x: Box<i32>) -> i32 {
-// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x{{.*}}, !nonnull
+    // CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x{{.*}}, align [[PTR_ALIGNMENT]]
     *x
 }
 
@@ -131,8 +131,8 @@ pub fn _box(x: Box<i32>) -> i32 {
 // dependent alignment
 #[no_mangle]
 pub fn small_array_alignment(x: [i8; 4]) -> [i8; 4] {
-// CHECK: [[VAR:%[0-9]+]] = load i32, {{i32\*|ptr}} %{{.*}}, align 1
-// CHECK: ret i32 [[VAR]]
+    // CHECK: [[VAR:%[0-9]+]] = load i32, {{i32\*|ptr}} %{{.*}}, align 1
+    // CHECK: ret i32 [[VAR]]
     x
 }
 
@@ -141,8 +141,8 @@ pub fn small_array_alignment(x: [i8; 4]) -> [i8; 4] {
 // dependent alignment
 #[no_mangle]
 pub fn small_struct_alignment(x: Bytes) -> Bytes {
-// CHECK: [[VAR:%[0-9]+]] = load i32, {{i32\*|ptr}} %{{.*}}, align 1
-// CHECK: ret i32 [[VAR]]
+    // CHECK: [[VAR:%[0-9]+]] = load i32, {{i32\*|ptr}} %{{.*}}, align 1
+    // CHECK: ret i32 [[VAR]]
     x
 }
 
diff --git a/src/test/debuginfo/lexical-scope-in-if-let.rs b/src/test/debuginfo/lexical-scope-in-if-let.rs
new file mode 100644
index 00000000000..cdc37ce48fb
--- /dev/null
+++ b/src/test/debuginfo/lexical-scope-in-if-let.rs
@@ -0,0 +1,100 @@
+// compile-flags:-g
+
+// === GDB TESTS ==================================================================================
+
+// gdb-command:run
+// gdb-command:info locals
+// gdb-check:a = 123
+
+// gdb-command:continue
+// gdb-command:info locals
+// gdb-check:x = 42
+// gdb-check:a = 123
+
+// gdb-command:continue
+// gdb-command:info locals
+// gdb-check:y = true
+// gdb-check:b = 456
+// gdb-check:x = 42
+// gdb-check:a = 123
+
+// gdb-command:continue
+// gdb-command:info locals
+// gdb-check:z = 10
+// gdb-check:c = 789
+// gdb-check:y = true
+// gdb-check:b = 456
+// gdb-check:x = 42
+// gdb-check:a = 123
+
+// === LLDB TESTS =================================================================================
+
+// lldb-command:run
+// lldb-command:frame variable
+// lldb-check:(int) a = 123
+
+// lldb-command:continue
+// lldb-command:frame variable
+// lldb-check:(int) a = 123 (int) x = 42
+
+// lldb-command:continue
+// lldb-command:frame variable
+// lldb-check:(int) a = 123 (int) x = 42 (int) b = 456 (bool) y = true
+
+// lldb-command:continue
+// lldb-command:frame variable
+// lldb-check:(int) a = 123 (int) x = 42 (int) b = 456 (bool) y = true (int) c = 789 (int) z = 10
+
+// === CDB TESTS ==================================================================================
+
+// cdb-command: g
+// cdb-command: dv
+// cdb-check:[...]a = 0n123
+
+// cdb-command: g
+// cdb-command: dv
+// cdb-check:[...]a = 0n123
+// cdb-check:[...]x = 0n42
+
+// cdb-command: g
+// cdb-command: dv
+// cdb-check:[...]y = true
+// cdb-check:[...]b = 0n456
+// cdb-check:[...]a = 0n123
+// cdb-check:[...]x = 0n42
+
+// cdb-command: g
+// cdb-command: dv
+// cdb-check:[...]z = 0n10
+// cdb-check:[...]c = 0n789
+// cdb-check:[...]y = true
+// cdb-check:[...]b = 0n456
+// cdb-check:[...]a = 0n123
+// cdb-check:[...]x = 0n42
+
+fn main() {
+    let a = id(123);
+
+    zzz(); // #break
+
+    if let Some(x) = id(Some(42)) {
+        zzz(); // #break
+
+        let b = id(456);
+
+        if let Ok(y) = id::<Result<bool, ()>>(Ok(true)) {
+            zzz(); // #break
+
+            let c = id(789);
+
+            if let (z, 42) = id((10, 42)) {
+                zzz(); // #break
+            }
+        }
+    }
+}
+
+#[inline(never)]
+fn id<T>(value: T) -> T { value }
+
+fn zzz() { }
diff --git a/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff
index 342c987343e..87302424914 100644
--- a/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/boxes.main.ConstProp.diff
@@ -10,6 +10,10 @@
       let mut _5: usize;                   // in scope 0 at $DIR/boxes.rs:12:14: 12:22
       let mut _6: *mut u8;                 // in scope 0 at $DIR/boxes.rs:12:14: 12:22
       let mut _7: std::boxed::Box<i32>;    // in scope 0 at $DIR/boxes.rs:12:14: 12:22
+      let mut _8: *const i32;              // in scope 0 at $DIR/boxes.rs:12:14: 12:22
+      let mut _9: *const i32;              // in scope 0 at $DIR/boxes.rs:12:14: 12:22
+      let mut _10: *const i32;             // in scope 0 at $DIR/boxes.rs:12:14: 12:22
+      let mut _11: *const i32;             // in scope 0 at $DIR/boxes.rs:12:14: 12:22
       scope 1 {
           debug x => _1;                   // in scope 1 at $DIR/boxes.rs:12:9: 12:10
       }
@@ -34,10 +38,16 @@
       bb1: {
           StorageLive(_7);                 // scope 0 at $DIR/boxes.rs:12:14: 12:22
           _7 = ShallowInitBox(move _6, i32); // scope 0 at $DIR/boxes.rs:12:14: 12:22
-          (*_7) = const 42_i32;            // scope 0 at $DIR/boxes.rs:12:19: 12:21
+          StorageLive(_8);                 // scope 0 at $DIR/boxes.rs:12:19: 12:21
+          _8 = (((_7.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>).0: *const i32); // scope 0 at $DIR/boxes.rs:12:19: 12:21
+          (*_8) = const 42_i32;            // scope 0 at $DIR/boxes.rs:12:19: 12:21
+          StorageDead(_8);                 // scope 0 at $DIR/boxes.rs:12:14: 12:22
           _3 = move _7;                    // scope 0 at $DIR/boxes.rs:12:14: 12:22
           StorageDead(_7);                 // scope 0 at $DIR/boxes.rs:12:21: 12:22
-          _2 = (*_3);                      // scope 0 at $DIR/boxes.rs:12:13: 12:22
+          StorageLive(_9);                 // scope 0 at $DIR/boxes.rs:12:13: 12:22
+          _9 = (((_3.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>).0: *const i32); // scope 0 at $DIR/boxes.rs:12:13: 12:22
+          _2 = (*_9);                      // scope 0 at $DIR/boxes.rs:12:13: 12:22
+          StorageDead(_9);                 // scope 0 at $DIR/boxes.rs:12:13: 12:26
           _1 = Add(move _2, const 0_i32);  // scope 0 at $DIR/boxes.rs:12:13: 12:26
           StorageDead(_2);                 // scope 0 at $DIR/boxes.rs:12:25: 12:26
           drop(_3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/boxes.rs:12:26: 12:27
diff --git a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff
index 445732f7022..047853696f2 100644
--- a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff
+++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.32bit.diff
@@ -10,26 +10,28 @@
       scope 1 {
           debug x => _1;                   // in scope 1 at $DIR/discriminant.rs:11:9: 11:10
       }
+      scope 2 {
+      }
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/discriminant.rs:11:9: 11:10
           StorageLive(_2);                 // scope 0 at $DIR/discriminant.rs:11:13: 11:64
-          StorageLive(_3);                 // scope 0 at $DIR/discriminant.rs:11:34: 11:44
-          Deinit(_3);                      // scope 0 at $DIR/discriminant.rs:11:34: 11:44
-          ((_3 as Some).0: bool) = const true; // scope 0 at $DIR/discriminant.rs:11:34: 11:44
-          discriminant(_3) = 1;            // scope 0 at $DIR/discriminant.rs:11:34: 11:44
--         _4 = discriminant(_3);           // scope 0 at $DIR/discriminant.rs:11:21: 11:31
--         switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/discriminant.rs:11:21: 11:31
-+         _4 = const 1_isize;              // scope 0 at $DIR/discriminant.rs:11:21: 11:31
-+         switchInt(const 1_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/discriminant.rs:11:21: 11:31
+          StorageLive(_3);                 // scope 2 at $DIR/discriminant.rs:11:34: 11:44
+          Deinit(_3);                      // scope 2 at $DIR/discriminant.rs:11:34: 11:44
+          ((_3 as Some).0: bool) = const true; // scope 2 at $DIR/discriminant.rs:11:34: 11:44
+          discriminant(_3) = 1;            // scope 2 at $DIR/discriminant.rs:11:34: 11:44
+-         _4 = discriminant(_3);           // scope 2 at $DIR/discriminant.rs:11:21: 11:31
+-         switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:11:21: 11:31
++         _4 = const 1_isize;              // scope 2 at $DIR/discriminant.rs:11:21: 11:31
++         switchInt(const 1_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:11:21: 11:31
       }
   
       bb1: {
-          switchInt(((_3 as Some).0: bool)) -> [false: bb3, otherwise: bb2]; // scope 0 at $DIR/discriminant.rs:11:21: 11:31
+          switchInt(((_3 as Some).0: bool)) -> [false: bb3, otherwise: bb2]; // scope 2 at $DIR/discriminant.rs:11:21: 11:31
       }
   
       bb2: {
-          _2 = const 42_i32;               // scope 0 at $DIR/discriminant.rs:11:47: 11:49
+          _2 = const 42_i32;               // scope 2 at $DIR/discriminant.rs:11:47: 11:49
           goto -> bb4;                     // scope 0 at $DIR/discriminant.rs:11:13: 11:64
       }
   
diff --git a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff
index 445732f7022..047853696f2 100644
--- a/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff
+++ b/src/test/mir-opt/const_prop/discriminant.main.ConstProp.64bit.diff
@@ -10,26 +10,28 @@
       scope 1 {
           debug x => _1;                   // in scope 1 at $DIR/discriminant.rs:11:9: 11:10
       }
+      scope 2 {
+      }
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/discriminant.rs:11:9: 11:10
           StorageLive(_2);                 // scope 0 at $DIR/discriminant.rs:11:13: 11:64
-          StorageLive(_3);                 // scope 0 at $DIR/discriminant.rs:11:34: 11:44
-          Deinit(_3);                      // scope 0 at $DIR/discriminant.rs:11:34: 11:44
-          ((_3 as Some).0: bool) = const true; // scope 0 at $DIR/discriminant.rs:11:34: 11:44
-          discriminant(_3) = 1;            // scope 0 at $DIR/discriminant.rs:11:34: 11:44
--         _4 = discriminant(_3);           // scope 0 at $DIR/discriminant.rs:11:21: 11:31
--         switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/discriminant.rs:11:21: 11:31
-+         _4 = const 1_isize;              // scope 0 at $DIR/discriminant.rs:11:21: 11:31
-+         switchInt(const 1_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/discriminant.rs:11:21: 11:31
+          StorageLive(_3);                 // scope 2 at $DIR/discriminant.rs:11:34: 11:44
+          Deinit(_3);                      // scope 2 at $DIR/discriminant.rs:11:34: 11:44
+          ((_3 as Some).0: bool) = const true; // scope 2 at $DIR/discriminant.rs:11:34: 11:44
+          discriminant(_3) = 1;            // scope 2 at $DIR/discriminant.rs:11:34: 11:44
+-         _4 = discriminant(_3);           // scope 2 at $DIR/discriminant.rs:11:21: 11:31
+-         switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:11:21: 11:31
++         _4 = const 1_isize;              // scope 2 at $DIR/discriminant.rs:11:21: 11:31
++         switchInt(const 1_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/discriminant.rs:11:21: 11:31
       }
   
       bb1: {
-          switchInt(((_3 as Some).0: bool)) -> [false: bb3, otherwise: bb2]; // scope 0 at $DIR/discriminant.rs:11:21: 11:31
+          switchInt(((_3 as Some).0: bool)) -> [false: bb3, otherwise: bb2]; // scope 2 at $DIR/discriminant.rs:11:21: 11:31
       }
   
       bb2: {
-          _2 = const 42_i32;               // scope 0 at $DIR/discriminant.rs:11:47: 11:49
+          _2 = const 42_i32;               // scope 2 at $DIR/discriminant.rs:11:47: 11:49
           goto -> bb4;                     // scope 0 at $DIR/discriminant.rs:11:13: 11:64
       }
   
diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
index 1efaba044ec..982dd7a27bc 100644
--- a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
+++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
@@ -7,22 +7,24 @@
       let mut _2: isize;                   // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:20: 13:30
       let mut _3: isize;                   // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
       let mut _4: &E;                      // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:12:16: 12:17
+      scope 1 {
+      }
   
       bb0: {
-          _3 = discriminant((*_1));        // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
-          switchInt(move _3) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
+          _3 = discriminant((*_1));        // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
+          switchInt(move _3) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
       }
   
       bb1: {
-          StorageLive(_4);                 // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
-          _4 = move (((*_1) as Some).0: &E); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
-          _2 = discriminant((*_4));        // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
-          StorageDead(_4);                 // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
-          switchInt(move _2) -> [1_isize: bb2, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
+          StorageLive(_4);                 // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
+          _4 = move (((*_1) as Some).0: &E); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
+          _2 = discriminant((*_4));        // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
+          StorageDead(_4);                 // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
+          switchInt(move _2) -> [1_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
       }
   
       bb2: {
-          _0 = const 1_u32;                // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:38: 13:39
+          _0 = const 1_u32;                // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:38: 13:39
           goto -> bb4;                     // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:5: 13:52
       }
   
diff --git a/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff b/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff
index f22fbec03d0..15409fa0dd2 100644
--- a/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff
+++ b/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff
@@ -27,9 +27,9 @@
           let _6: core::num::flt2dec::Sign; // in scope 1 at $DIR/funky_arms.rs:19:9: 19:13
           scope 2 {
               debug sign => _6;            // in scope 2 at $DIR/funky_arms.rs:19:9: 19:13
-              let _10: usize;              // in scope 2 at $DIR/funky_arms.rs:24:17: 24:26
               scope 3 {
                   debug precision => _10;  // in scope 3 at $DIR/funky_arms.rs:24:17: 24:26
+                  let _10: usize;          // in scope 3 at $DIR/funky_arms.rs:24:17: 24:26
               }
           }
       }
@@ -63,52 +63,52 @@
       }
   
       bb4: {
-          StorageLive(_7);                 // scope 2 at $DIR/funky_arms.rs:24:30: 24:45
-          StorageLive(_8);                 // scope 2 at $DIR/funky_arms.rs:24:30: 24:45
-          _8 = &(*_1);                     // scope 2 at $DIR/funky_arms.rs:24:30: 24:45
-          _7 = Formatter::precision(move _8) -> bb5; // scope 2 at $DIR/funky_arms.rs:24:30: 24:45
+          StorageLive(_7);                 // scope 3 at $DIR/funky_arms.rs:24:30: 24:45
+          StorageLive(_8);                 // scope 3 at $DIR/funky_arms.rs:24:30: 24:45
+          _8 = &(*_1);                     // scope 3 at $DIR/funky_arms.rs:24:30: 24:45
+          _7 = Formatter::precision(move _8) -> bb5; // scope 3 at $DIR/funky_arms.rs:24:30: 24:45
                                            // mir::Constant
                                            // + span: $DIR/funky_arms.rs:24:34: 24:43
                                            // + literal: Const { ty: for<'r> fn(&'r Formatter) -> Option<usize> {Formatter::precision}, val: Value(Scalar(<ZST>)) }
       }
   
       bb5: {
-          StorageDead(_8);                 // scope 2 at $DIR/funky_arms.rs:24:44: 24:45
-          _9 = discriminant(_7);           // scope 2 at $DIR/funky_arms.rs:24:12: 24:27
-          switchInt(move _9) -> [1_isize: bb6, otherwise: bb8]; // scope 2 at $DIR/funky_arms.rs:24:12: 24:27
+          StorageDead(_8);                 // scope 3 at $DIR/funky_arms.rs:24:44: 24:45
+          _9 = discriminant(_7);           // scope 3 at $DIR/funky_arms.rs:24:12: 24:27
+          switchInt(move _9) -> [1_isize: bb6, otherwise: bb8]; // scope 3 at $DIR/funky_arms.rs:24:12: 24:27
       }
   
       bb6: {
-          StorageLive(_10);                // scope 2 at $DIR/funky_arms.rs:24:17: 24:26
-          _10 = ((_7 as Some).0: usize);   // scope 2 at $DIR/funky_arms.rs:24:17: 24:26
-          StorageLive(_11);                // scope 2 at $DIR/funky_arms.rs:26:43: 26:46
-          _11 = &mut (*_1);                // scope 2 at $DIR/funky_arms.rs:26:43: 26:46
-          StorageLive(_12);                // scope 2 at $DIR/funky_arms.rs:26:48: 26:51
-          _12 = _2;                        // scope 2 at $DIR/funky_arms.rs:26:48: 26:51
-          StorageLive(_13);                // scope 2 at $DIR/funky_arms.rs:26:53: 26:57
-          _13 = _6;                        // scope 2 at $DIR/funky_arms.rs:26:53: 26:57
-          StorageLive(_14);                // scope 2 at $DIR/funky_arms.rs:26:59: 26:79
-          StorageLive(_15);                // scope 2 at $DIR/funky_arms.rs:26:59: 26:75
-          StorageLive(_16);                // scope 2 at $DIR/funky_arms.rs:26:59: 26:68
-          _16 = _10;                       // scope 2 at $DIR/funky_arms.rs:26:59: 26:68
-          _15 = move _16 as u32 (Misc);    // scope 2 at $DIR/funky_arms.rs:26:59: 26:75
-          StorageDead(_16);                // scope 2 at $DIR/funky_arms.rs:26:74: 26:75
-          _14 = Add(move _15, const 1_u32); // scope 2 at $DIR/funky_arms.rs:26:59: 26:79
-          StorageDead(_15);                // scope 2 at $DIR/funky_arms.rs:26:78: 26:79
-          StorageLive(_17);                // scope 2 at $DIR/funky_arms.rs:26:81: 26:86
-          _17 = _3;                        // scope 2 at $DIR/funky_arms.rs:26:81: 26:86
-          _0 = float_to_exponential_common_exact::<T>(move _11, move _12, move _13, move _14, move _17) -> bb7; // scope 2 at $DIR/funky_arms.rs:26:9: 26:87
+          StorageLive(_10);                // scope 3 at $DIR/funky_arms.rs:24:17: 24:26
+          _10 = ((_7 as Some).0: usize);   // scope 3 at $DIR/funky_arms.rs:24:17: 24:26
+          StorageLive(_11);                // scope 3 at $DIR/funky_arms.rs:26:43: 26:46
+          _11 = &mut (*_1);                // scope 3 at $DIR/funky_arms.rs:26:43: 26:46
+          StorageLive(_12);                // scope 3 at $DIR/funky_arms.rs:26:48: 26:51
+          _12 = _2;                        // scope 3 at $DIR/funky_arms.rs:26:48: 26:51
+          StorageLive(_13);                // scope 3 at $DIR/funky_arms.rs:26:53: 26:57
+          _13 = _6;                        // scope 3 at $DIR/funky_arms.rs:26:53: 26:57
+          StorageLive(_14);                // scope 3 at $DIR/funky_arms.rs:26:59: 26:79
+          StorageLive(_15);                // scope 3 at $DIR/funky_arms.rs:26:59: 26:75
+          StorageLive(_16);                // scope 3 at $DIR/funky_arms.rs:26:59: 26:68
+          _16 = _10;                       // scope 3 at $DIR/funky_arms.rs:26:59: 26:68
+          _15 = move _16 as u32 (Misc);    // scope 3 at $DIR/funky_arms.rs:26:59: 26:75
+          StorageDead(_16);                // scope 3 at $DIR/funky_arms.rs:26:74: 26:75
+          _14 = Add(move _15, const 1_u32); // scope 3 at $DIR/funky_arms.rs:26:59: 26:79
+          StorageDead(_15);                // scope 3 at $DIR/funky_arms.rs:26:78: 26:79
+          StorageLive(_17);                // scope 3 at $DIR/funky_arms.rs:26:81: 26:86
+          _17 = _3;                        // scope 3 at $DIR/funky_arms.rs:26:81: 26:86
+          _0 = float_to_exponential_common_exact::<T>(move _11, move _12, move _13, move _14, move _17) -> bb7; // scope 3 at $DIR/funky_arms.rs:26:9: 26:87
                                            // mir::Constant
                                            // + span: $DIR/funky_arms.rs:26:9: 26:42
                                            // + literal: Const { ty: for<'r, 's, 't0> fn(&'r mut Formatter<'s>, &'t0 T, Sign, u32, bool) -> Result<(), std::fmt::Error> {float_to_exponential_common_exact::<T>}, val: Value(Scalar(<ZST>)) }
       }
   
       bb7: {
-          StorageDead(_17);                // scope 2 at $DIR/funky_arms.rs:26:86: 26:87
-          StorageDead(_14);                // scope 2 at $DIR/funky_arms.rs:26:86: 26:87
-          StorageDead(_13);                // scope 2 at $DIR/funky_arms.rs:26:86: 26:87
-          StorageDead(_12);                // scope 2 at $DIR/funky_arms.rs:26:86: 26:87
-          StorageDead(_11);                // scope 2 at $DIR/funky_arms.rs:26:86: 26:87
+          StorageDead(_17);                // scope 3 at $DIR/funky_arms.rs:26:86: 26:87
+          StorageDead(_14);                // scope 3 at $DIR/funky_arms.rs:26:86: 26:87
+          StorageDead(_13);                // scope 3 at $DIR/funky_arms.rs:26:86: 26:87
+          StorageDead(_12);                // scope 3 at $DIR/funky_arms.rs:26:86: 26:87
+          StorageDead(_11);                // scope 3 at $DIR/funky_arms.rs:26:86: 26:87
           StorageDead(_10);                // scope 2 at $DIR/funky_arms.rs:27:5: 27:6
           goto -> bb10;                    // scope 2 at $DIR/funky_arms.rs:24:5: 29:6
       }
diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff
index 5b2b9f7e3a9..89414574898 100644
--- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff
+++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff
@@ -9,14 +9,16 @@
       let mut _4: *mut u8;                 // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
       let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
       let mut _6: ();                      // in scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
-+     let mut _7: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+      let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+      let mut _8: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
++     let mut _9: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
       scope 1 {
           debug _x => _1;                  // in scope 1 at $DIR/inline-into-box-place.rs:8:9: 8:11
       }
       scope 2 {
       }
 +     scope 3 (inlined Vec::<u32>::new) {  // at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         let mut _8: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         let mut _10: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
 +     }
   
       bb0: {
@@ -32,11 +34,13 @@
       bb1: {
           StorageLive(_5);                 // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
           _5 = ShallowInitBox(move _4, std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
--         (*_5) = Vec::<u32>::new() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         StorageLive(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         _7 = &mut (*_5);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         StorageLive(_8);                 // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         _8 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+          StorageLive(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+          _7 = (((_5.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+-         (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         StorageLive(_9);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         _9 = &mut (*_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         StorageLive(_10);                // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         _10 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
                                            // mir::Constant
 -                                          // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
 -                                          // + user_ty: UserType(1)
@@ -47,15 +51,16 @@
 +                                          // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
 +                                          // + user_ty: UserType(0)
 +                                          // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) }
-+         Deinit((*_7));                   // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         ((*_7).0: alloc::raw_vec::RawVec<u32>) = move _8; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         ((*_7).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         StorageDead(_8);                 // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         StorageDead(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         Deinit((*_9));                   // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         ((*_9).0: alloc::raw_vec::RawVec<u32>) = move _10; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         ((*_9).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         StorageDead(_10);                // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         StorageDead(_9);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+          StorageDead(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
           _1 = move _5;                    // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
           StorageDead(_5);                 // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
           _0 = const ();                   // scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2
--         drop(_1) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
+-         drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
 +         drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
       }
   
@@ -66,15 +71,16 @@
       }
   
 -     bb4 (cleanup): {
-+     bb3 (cleanup): {
-          resume;                          // scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2
--     }
-- 
--     bb5 (cleanup): {
--         _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb4; // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
+-         StorageDead(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+-         _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb5; // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
 -                                          // mir::Constant
 -                                          // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
 -                                          // + literal: Const { ty: unsafe fn(Unique<Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>}, val: Value(Scalar(<ZST>)) }
+-     }
+- 
+-     bb5 (cleanup): {
++     bb3 (cleanup): {
+          resume;                          // scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2
       }
   }
   
diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff
index 5b2b9f7e3a9..89414574898 100644
--- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff
+++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff
@@ -9,14 +9,16 @@
       let mut _4: *mut u8;                 // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
       let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
       let mut _6: ();                      // in scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
-+     let mut _7: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+      let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
+      let mut _8: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
++     let mut _9: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
       scope 1 {
           debug _x => _1;                  // in scope 1 at $DIR/inline-into-box-place.rs:8:9: 8:11
       }
       scope 2 {
       }
 +     scope 3 (inlined Vec::<u32>::new) {  // at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         let mut _8: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         let mut _10: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
 +     }
   
       bb0: {
@@ -32,11 +34,13 @@
       bb1: {
           StorageLive(_5);                 // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
           _5 = ShallowInitBox(move _4, std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
--         (*_5) = Vec::<u32>::new() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         StorageLive(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         _7 = &mut (*_5);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
-+         StorageLive(_8);                 // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         _8 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+          StorageLive(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+          _7 = (((_5.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+-         (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         StorageLive(_9);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         _9 = &mut (*_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         StorageLive(_10);                // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         _10 = const alloc::raw_vec::RawVec::<u32>::NEW; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
                                            // mir::Constant
 -                                          // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
 -                                          // + user_ty: UserType(1)
@@ -47,15 +51,16 @@
 +                                          // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
 +                                          // + user_ty: UserType(0)
 +                                          // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Unevaluated(alloc::raw_vec::RawVec::<T>::NEW, [u32], None) }
-+         Deinit((*_7));                   // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         ((*_7).0: alloc::raw_vec::RawVec<u32>) = move _8; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         ((*_7).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         StorageDead(_8);                 // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+         StorageDead(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
++         Deinit((*_9));                   // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         ((*_9).0: alloc::raw_vec::RawVec<u32>) = move _10; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         ((*_9).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         StorageDead(_10);                // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
++         StorageDead(_9);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+          StorageDead(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
           _1 = move _5;                    // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43
           StorageDead(_5);                 // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
           _0 = const ();                   // scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2
--         drop(_1) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
+-         drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
 +         drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2
       }
   
@@ -66,15 +71,16 @@
       }
   
 -     bb4 (cleanup): {
-+     bb3 (cleanup): {
-          resume;                          // scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2
--     }
-- 
--     bb5 (cleanup): {
--         _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb4; // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
+-         StorageDead(_7);                 // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43
+-         _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb5; // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
 -                                          // mir::Constant
 -                                          // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
 -                                          // + literal: Const { ty: unsafe fn(Unique<Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>}, val: Value(Scalar(<ZST>)) }
+-     }
+- 
+-     bb5 (cleanup): {
++     bb3 (cleanup): {
+          resume;                          // scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2
       }
   }
   
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
index 0bb3445a2d0..11a205eb415 100644
--- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
@@ -11,6 +11,7 @@ fn b(_1: &mut Box<T>) -> &mut T {
         let mut _5: &mut T;              // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         let mut _6: &mut T;              // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         let mut _7: std::boxed::Box<T>;  // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+        let mut _8: *const T;            // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
     }
 
     bb0: {
@@ -22,7 +23,10 @@ fn b(_1: &mut Box<T>) -> &mut T {
         StorageLive(_6);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         StorageLive(_7);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         _7 = move (*_4);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
-        _6 = &mut (*_7);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+        StorageLive(_8);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+        _8 = (((_7.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+        _6 = &mut (*_8);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+        StorageDead(_8);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         StorageDead(_7);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         _5 = &mut (*_6);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         _3 = &mut (*_5);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
index c22852b99f4..b04a91d7c95 100644
--- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
@@ -8,6 +8,7 @@ fn d(_1: &Box<T>) -> &T {
     scope 1 (inlined <Box<T> as AsRef<T>>::as_ref) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
         debug self => _3;                // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         let mut _4: std::boxed::Box<T>;  // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+        let mut _5: *const T;            // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
     }
 
     bb0: {
@@ -16,7 +17,10 @@ fn d(_1: &Box<T>) -> &T {
         _3 = &(*_1);                     // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
         StorageLive(_4);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         _4 = move (*_3);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
-        _2 = &(*_4);                     // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+        StorageLive(_5);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+        _5 = (((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+        _2 = &(*_5);                     // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+        StorageDead(_5);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         StorageDead(_4);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         _0 = &(*_2);                     // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
         StorageDead(_3);                 // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:14: 18:15
diff --git a/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir
index 54930937c91..ce7ca20358e 100644
--- a/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir
+++ b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir
@@ -14,9 +14,9 @@ fn main() -> () {
     let mut _11: isize;                  // in scope 0 at $DIR/issue-41888.rs:15:1: 15:2
     scope 1 {
         debug e => _1;                   // in scope 1 at $DIR/issue-41888.rs:7:9: 7:10
-        let _6: K;                       // in scope 1 at $DIR/issue-41888.rs:10:21: 10:23
         scope 2 {
             debug _k => _6;              // in scope 2 at $DIR/issue-41888.rs:10:21: 10:23
+            let _6: K;                   // in scope 2 at $DIR/issue-41888.rs:10:21: 10:23
         }
     }
 
@@ -51,15 +51,15 @@ fn main() -> () {
 
     bb4: {
         StorageDead(_3);                 // scope 1 at $DIR/issue-41888.rs:9:19: 9:20
-        _5 = discriminant(_1);           // scope 1 at $DIR/issue-41888.rs:10:16: 10:24
-        switchInt(move _5) -> [0_isize: bb5, otherwise: bb6]; // scope 1 at $DIR/issue-41888.rs:10:16: 10:24
+        _5 = discriminant(_1);           // scope 2 at $DIR/issue-41888.rs:10:16: 10:24
+        switchInt(move _5) -> [0_isize: bb5, otherwise: bb6]; // scope 2 at $DIR/issue-41888.rs:10:16: 10:24
     }
 
     bb5: {
-        StorageLive(_6);                 // scope 1 at $DIR/issue-41888.rs:10:21: 10:23
-        _9 = const false;                // scope 1 at $DIR/issue-41888.rs:10:21: 10:23
-        _6 = move ((_1 as F).0: K);      // scope 1 at $DIR/issue-41888.rs:10:21: 10:23
-        _0 = const ();                   // scope 1 at $DIR/issue-41888.rs:10:29: 13:10
+        StorageLive(_6);                 // scope 2 at $DIR/issue-41888.rs:10:21: 10:23
+        _9 = const false;                // scope 2 at $DIR/issue-41888.rs:10:21: 10:23
+        _6 = move ((_1 as F).0: K);      // scope 2 at $DIR/issue-41888.rs:10:21: 10:23
+        _0 = const ();                   // scope 2 at $DIR/issue-41888.rs:10:29: 13:10
         StorageDead(_6);                 // scope 1 at $DIR/issue-41888.rs:13:9: 13:10
         goto -> bb8;                     // scope 1 at $DIR/issue-41888.rs:10:9: 13:10
     }
diff --git a/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
index 299529ec649..b8023a6a8e6 100644
--- a/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
+++ b/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
@@ -10,11 +10,11 @@
       let mut _6: u32;                     // in scope 0 at $DIR/issue-75439.rs:10:33: 10:35
       scope 1 {
           debug dwords => _2;              // in scope 1 at $DIR/issue-75439.rs:7:9: 7:15
-          let _4: u32;                     // in scope 1 at $DIR/issue-75439.rs:9:27: 9:29
           scope 3 {
               debug ip => _4;              // in scope 3 at $DIR/issue-75439.rs:9:27: 9:29
-          }
-          scope 4 {
+              let _4: u32;                 // in scope 3 at $DIR/issue-75439.rs:9:27: 9:29
+              scope 4 {
+              }
           }
       }
       scope 2 {
@@ -32,19 +32,19 @@
   
       bb1: {
           StorageDead(_3);                 // scope 2 at $DIR/issue-75439.rs:7:52: 7:53
-          switchInt(_2[0 of 4]) -> [0_u32: bb2, otherwise: bb8]; // scope 1 at $DIR/issue-75439.rs:9:12: 9:30
+          switchInt(_2[0 of 4]) -> [0_u32: bb2, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:9:12: 9:30
       }
   
       bb2: {
-          switchInt(_2[1 of 4]) -> [0_u32: bb3, otherwise: bb8]; // scope 1 at $DIR/issue-75439.rs:9:12: 9:30
+          switchInt(_2[1 of 4]) -> [0_u32: bb3, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:9:12: 9:30
       }
   
       bb3: {
-          switchInt(_2[2 of 4]) -> [0_u32: bb5, 4294901760_u32: bb6, otherwise: bb8]; // scope 1 at $DIR/issue-75439.rs:9:12: 9:30
+          switchInt(_2[2 of 4]) -> [0_u32: bb5, 4294901760_u32: bb6, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:9:12: 9:30
       }
   
       bb4: {
-          StorageLive(_5);                 // scope 1 at $DIR/issue-75439.rs:10:14: 10:38
+          StorageLive(_5);                 // scope 3 at $DIR/issue-75439.rs:10:14: 10:38
           StorageLive(_6);                 // scope 4 at $DIR/issue-75439.rs:10:33: 10:35
           _6 = _4;                         // scope 4 at $DIR/issue-75439.rs:10:33: 10:35
           _5 = transmute::<u32, [u8; 4]>(move _6) -> bb7; // scope 4 at $DIR/issue-75439.rs:10:23: 10:36
@@ -54,23 +54,23 @@
       }
   
       bb5: {
-          StorageLive(_4);                 // scope 1 at $DIR/issue-75439.rs:9:27: 9:29
-          _4 = _2[3 of 4];                 // scope 1 at $DIR/issue-75439.rs:9:27: 9:29
-          goto -> bb4;                     // scope 1 at $DIR/issue-75439.rs:9:12: 9:30
+          StorageLive(_4);                 // scope 3 at $DIR/issue-75439.rs:9:27: 9:29
+          _4 = _2[3 of 4];                 // scope 3 at $DIR/issue-75439.rs:9:27: 9:29
+          goto -> bb4;                     // scope 3 at $DIR/issue-75439.rs:9:12: 9:30
       }
   
       bb6: {
-          StorageLive(_4);                 // scope 1 at $DIR/issue-75439.rs:9:27: 9:29
-          _4 = _2[3 of 4];                 // scope 1 at $DIR/issue-75439.rs:9:27: 9:29
-          goto -> bb4;                     // scope 1 at $DIR/issue-75439.rs:9:12: 9:30
+          StorageLive(_4);                 // scope 3 at $DIR/issue-75439.rs:9:27: 9:29
+          _4 = _2[3 of 4];                 // scope 3 at $DIR/issue-75439.rs:9:27: 9:29
+          goto -> bb4;                     // scope 3 at $DIR/issue-75439.rs:9:12: 9:30
       }
   
       bb7: {
           StorageDead(_6);                 // scope 4 at $DIR/issue-75439.rs:10:35: 10:36
-          Deinit(_0);                      // scope 1 at $DIR/issue-75439.rs:10:9: 10:39
-          ((_0 as Some).0: [u8; 4]) = move _5; // scope 1 at $DIR/issue-75439.rs:10:9: 10:39
-          discriminant(_0) = 1;            // scope 1 at $DIR/issue-75439.rs:10:9: 10:39
-          StorageDead(_5);                 // scope 1 at $DIR/issue-75439.rs:10:38: 10:39
+          Deinit(_0);                      // scope 3 at $DIR/issue-75439.rs:10:9: 10:39
+          ((_0 as Some).0: [u8; 4]) = move _5; // scope 3 at $DIR/issue-75439.rs:10:9: 10:39
+          discriminant(_0) = 1;            // scope 3 at $DIR/issue-75439.rs:10:9: 10:39
+          StorageDead(_5);                 // scope 3 at $DIR/issue-75439.rs:10:38: 10:39
           StorageDead(_4);                 // scope 1 at $DIR/issue-75439.rs:11:5: 11:6
           goto -> bb9;                     // scope 1 at $DIR/issue-75439.rs:9:5: 13:6
       }
diff --git a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff
index a8cc61f0526..075fe8d0908 100644
--- a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff
@@ -8,44 +8,44 @@
       let mut _3: std::option::Option<T>;  // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:51: 4:68
       let mut _4: isize;                   // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:22: 4:26
       let mut _5: isize;                   // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:13: 4:20
-      let _6: u8;                          // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19
 -     let mut _7: bool;                    // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20
 -     let mut _8: u8;                      // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13
       scope 1 {
           debug a => _6;                   // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19
+          let _6: u8;                      // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:30: 4:69
-          StorageLive(_2);                 // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:31: 4:49
-          Deinit(_2);                      // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:31: 4:49
-          discriminant(_2) = 0;            // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:31: 4:49
-          StorageLive(_3);                 // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:51: 4:68
-          Deinit(_3);                      // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:51: 4:68
-          discriminant(_3) = 0;            // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:51: 4:68
-          Deinit(_1);                      // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:30: 4:69
-          (_1.0: std::option::Option<u8>) = move _2; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:30: 4:69
-          (_1.1: std::option::Option<T>) = move _3; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:30: 4:69
-          StorageDead(_3);                 // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:68: 4:69
-          StorageDead(_2);                 // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:68: 4:69
-          _5 = discriminant((_1.0: std::option::Option<u8>)); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:12: 4:27
-          switchInt(move _5) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:12: 4:27
+          StorageLive(_1);                 // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:30: 4:69
+          StorageLive(_2);                 // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:31: 4:49
+          Deinit(_2);                      // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:31: 4:49
+          discriminant(_2) = 0;            // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:31: 4:49
+          StorageLive(_3);                 // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:51: 4:68
+          Deinit(_3);                      // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:51: 4:68
+          discriminant(_3) = 0;            // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:51: 4:68
+          Deinit(_1);                      // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:30: 4:69
+          (_1.0: std::option::Option<u8>) = move _2; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:30: 4:69
+          (_1.1: std::option::Option<T>) = move _3; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:30: 4:69
+          StorageDead(_3);                 // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:68: 4:69
+          StorageDead(_2);                 // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:68: 4:69
+          _5 = discriminant((_1.0: std::option::Option<u8>)); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:12: 4:27
+          switchInt(move _5) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:12: 4:27
       }
   
       bb1: {
-          _4 = discriminant((_1.1: std::option::Option<T>)); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:12: 4:27
-          switchInt(move _4) -> [0_isize: bb2, otherwise: bb3]; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:12: 4:27
+          _4 = discriminant((_1.1: std::option::Option<T>)); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:12: 4:27
+          switchInt(move _4) -> [0_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:12: 4:27
       }
   
       bb2: {
-          StorageLive(_6);                 // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19
-          _6 = (((_1.0: std::option::Option<u8>) as Some).0: u8); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19
--         StorageLive(_7);                 // scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20
--         StorageLive(_8);                 // scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13
--         _8 = _6;                         // scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13
--         _7 = Gt(move _8, const 42_u8);   // scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20
--         StorageDead(_8);                 // scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:19: 5:20
--         StorageDead(_7);                 // scope 0 at $DIR/simplify-locals-fixedpoint.rs:7:9: 7:10
+          StorageLive(_6);                 // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19
+          _6 = (((_1.0: std::option::Option<u8>) as Some).0: u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19
+-         StorageLive(_7);                 // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20
+-         StorageLive(_8);                 // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13
+-         _8 = _6;                         // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13
+-         _7 = Gt(move _8, const 42_u8);   // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20
+-         StorageDead(_8);                 // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:19: 5:20
+-         StorageDead(_7);                 // scope 1 at $DIR/simplify-locals-fixedpoint.rs:7:9: 7:10
           StorageDead(_6);                 // scope 0 at $DIR/simplify-locals-fixedpoint.rs:8:5: 8:6
           goto -> bb3;                     // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:5: 8:6
       }
diff --git a/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff
index 08312bde20f..70486f546d7 100644
--- a/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff
+++ b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff
@@ -5,36 +5,36 @@
       let mut _0: ();                      // return place in scope 0 at $DIR/unreachable.rs:8:11: 8:11
       let mut _1: std::option::Option<Empty>; // in scope 0 at $DIR/unreachable.rs:9:23: 9:30
       let mut _2: isize;                   // in scope 0 at $DIR/unreachable.rs:9:12: 9:20
-      let _3: Empty;                       // in scope 0 at $DIR/unreachable.rs:9:17: 9:19
-      let mut _4: i32;                     // in scope 0 at $DIR/unreachable.rs:10:13: 10:19
       let _5: ();                          // in scope 0 at $DIR/unreachable.rs:12:9: 16:10
       let mut _6: bool;                    // in scope 0 at $DIR/unreachable.rs:12:12: 12:16
       let mut _7: !;                       // in scope 0 at $DIR/unreachable.rs:18:9: 18:21
       scope 1 {
           debug _x => _3;                  // in scope 1 at $DIR/unreachable.rs:9:17: 9:19
-      }
-      scope 2 {
-          debug _y => _4;                  // in scope 2 at $DIR/unreachable.rs:10:13: 10:19
+          let _3: Empty;                   // in scope 1 at $DIR/unreachable.rs:9:17: 9:19
+          let mut _4: i32;                 // in scope 1 at $DIR/unreachable.rs:10:13: 10:19
+          scope 2 {
+              debug _y => _4;              // in scope 2 at $DIR/unreachable.rs:10:13: 10:19
+          }
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/unreachable.rs:9:23: 9:30
-          _1 = empty() -> bb1;             // scope 0 at $DIR/unreachable.rs:9:23: 9:30
+          StorageLive(_1);                 // scope 1 at $DIR/unreachable.rs:9:23: 9:30
+          _1 = empty() -> bb1;             // scope 1 at $DIR/unreachable.rs:9:23: 9:30
                                            // mir::Constant
                                            // + span: $DIR/unreachable.rs:9:23: 9:28
                                            // + literal: Const { ty: fn() -> Option<Empty> {empty}, val: Value(Scalar(<ZST>)) }
       }
   
       bb1: {
-          _2 = discriminant(_1);           // scope 0 at $DIR/unreachable.rs:9:12: 9:20
--         switchInt(move _2) -> [1_isize: bb2, otherwise: bb6]; // scope 0 at $DIR/unreachable.rs:9:12: 9:20
-+         goto -> bb2;                     // scope 0 at $DIR/unreachable.rs:9:12: 9:20
+          _2 = discriminant(_1);           // scope 1 at $DIR/unreachable.rs:9:12: 9:20
+-         switchInt(move _2) -> [1_isize: bb2, otherwise: bb6]; // scope 1 at $DIR/unreachable.rs:9:12: 9:20
++         goto -> bb2;                     // scope 1 at $DIR/unreachable.rs:9:12: 9:20
       }
   
       bb2: {
--         StorageLive(_3);                 // scope 0 at $DIR/unreachable.rs:9:17: 9:19
--         _3 = move ((_1 as Some).0: Empty); // scope 0 at $DIR/unreachable.rs:9:17: 9:19
--         StorageLive(_4);                 // scope 0 at $DIR/unreachable.rs:10:13: 10:19
+-         StorageLive(_3);                 // scope 1 at $DIR/unreachable.rs:9:17: 9:19
+-         _3 = move ((_1 as Some).0: Empty); // scope 1 at $DIR/unreachable.rs:9:17: 9:19
+-         StorageLive(_4);                 // scope 1 at $DIR/unreachable.rs:10:13: 10:19
 -         StorageLive(_5);                 // scope 2 at $DIR/unreachable.rs:12:9: 16:10
 -         StorageLive(_6);                 // scope 2 at $DIR/unreachable.rs:12:12: 12:16
 -         _6 = const true;                 // scope 2 at $DIR/unreachable.rs:12:12: 12:16
diff --git a/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff
index e5867ccfc5c..d9f2681d145 100644
--- a/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff
+++ b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff
@@ -11,56 +11,56 @@
       let mut _7: !;                       // in scope 0 at $DIR/unreachable_diverging.rs:18:9: 18:22
       scope 1 {
           debug x => _1;                   // in scope 1 at $DIR/unreachable_diverging.rs:13:9: 13:10
-          let _4: Empty;                   // in scope 1 at $DIR/unreachable_diverging.rs:14:17: 14:21
           scope 2 {
               debug bomb => _4;            // in scope 2 at $DIR/unreachable_diverging.rs:14:17: 14:21
+              let _4: Empty;               // in scope 2 at $DIR/unreachable_diverging.rs:14:17: 14:21
           }
       }
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/unreachable_diverging.rs:13:9: 13:10
           _1 = const true;                 // scope 0 at $DIR/unreachable_diverging.rs:13:13: 13:17
-          StorageLive(_2);                 // scope 1 at $DIR/unreachable_diverging.rs:14:25: 14:32
-          _2 = empty() -> bb1;             // scope 1 at $DIR/unreachable_diverging.rs:14:25: 14:32
+          StorageLive(_2);                 // scope 2 at $DIR/unreachable_diverging.rs:14:25: 14:32
+          _2 = empty() -> bb1;             // scope 2 at $DIR/unreachable_diverging.rs:14:25: 14:32
                                            // mir::Constant
                                            // + span: $DIR/unreachable_diverging.rs:14:25: 14:30
                                            // + literal: Const { ty: fn() -> Option<Empty> {empty}, val: Value(Scalar(<ZST>)) }
       }
   
       bb1: {
-          _3 = discriminant(_2);           // scope 1 at $DIR/unreachable_diverging.rs:14:12: 14:22
--         switchInt(move _3) -> [1_isize: bb2, otherwise: bb6]; // scope 1 at $DIR/unreachable_diverging.rs:14:12: 14:22
-+         switchInt(move _3) -> [1_isize: bb2, otherwise: bb5]; // scope 1 at $DIR/unreachable_diverging.rs:14:12: 14:22
+          _3 = discriminant(_2);           // scope 2 at $DIR/unreachable_diverging.rs:14:12: 14:22
+-         switchInt(move _3) -> [1_isize: bb2, otherwise: bb6]; // scope 2 at $DIR/unreachable_diverging.rs:14:12: 14:22
++         switchInt(move _3) -> [1_isize: bb2, otherwise: bb5]; // scope 2 at $DIR/unreachable_diverging.rs:14:12: 14:22
       }
   
       bb2: {
-          StorageLive(_4);                 // scope 1 at $DIR/unreachable_diverging.rs:14:17: 14:21
-          _4 = move ((_2 as Some).0: Empty); // scope 1 at $DIR/unreachable_diverging.rs:14:17: 14:21
-          StorageLive(_5);                 // scope 1 at $DIR/unreachable_diverging.rs:15:9: 17:10
-          StorageLive(_6);                 // scope 1 at $DIR/unreachable_diverging.rs:15:12: 15:13
-          _6 = _1;                         // scope 1 at $DIR/unreachable_diverging.rs:15:12: 15:13
--         switchInt(move _6) -> [false: bb4, otherwise: bb3]; // scope 1 at $DIR/unreachable_diverging.rs:15:12: 15:13
-+         goto -> bb3;                     // scope 1 at $DIR/unreachable_diverging.rs:15:12: 15:13
+          StorageLive(_4);                 // scope 2 at $DIR/unreachable_diverging.rs:14:17: 14:21
+          _4 = move ((_2 as Some).0: Empty); // scope 2 at $DIR/unreachable_diverging.rs:14:17: 14:21
+          StorageLive(_5);                 // scope 2 at $DIR/unreachable_diverging.rs:15:9: 17:10
+          StorageLive(_6);                 // scope 2 at $DIR/unreachable_diverging.rs:15:12: 15:13
+          _6 = _1;                         // scope 2 at $DIR/unreachable_diverging.rs:15:12: 15:13
+-         switchInt(move _6) -> [false: bb4, otherwise: bb3]; // scope 2 at $DIR/unreachable_diverging.rs:15:12: 15:13
++         goto -> bb3;                     // scope 2 at $DIR/unreachable_diverging.rs:15:12: 15:13
       }
   
       bb3: {
--         _5 = loop_forever() -> bb5;      // scope 1 at $DIR/unreachable_diverging.rs:16:13: 16:27
-+         _5 = loop_forever() -> bb4;      // scope 1 at $DIR/unreachable_diverging.rs:16:13: 16:27
+-         _5 = loop_forever() -> bb5;      // scope 2 at $DIR/unreachable_diverging.rs:16:13: 16:27
++         _5 = loop_forever() -> bb4;      // scope 2 at $DIR/unreachable_diverging.rs:16:13: 16:27
                                            // mir::Constant
                                            // + span: $DIR/unreachable_diverging.rs:16:13: 16:25
                                            // + literal: Const { ty: fn() {loop_forever}, val: Value(Scalar(<ZST>)) }
       }
   
       bb4: {
--         _5 = const ();                   // scope 1 at $DIR/unreachable_diverging.rs:17:10: 17:10
--         goto -> bb5;                     // scope 1 at $DIR/unreachable_diverging.rs:15:9: 17:10
+-         _5 = const ();                   // scope 2 at $DIR/unreachable_diverging.rs:17:10: 17:10
+-         goto -> bb5;                     // scope 2 at $DIR/unreachable_diverging.rs:15:9: 17:10
 -     }
 - 
 -     bb5: {
-          StorageDead(_6);                 // scope 1 at $DIR/unreachable_diverging.rs:17:9: 17:10
-          StorageDead(_5);                 // scope 1 at $DIR/unreachable_diverging.rs:17:9: 17:10
-          StorageLive(_7);                 // scope 1 at $DIR/unreachable_diverging.rs:18:9: 18:22
-          unreachable;                     // scope 1 at $DIR/unreachable_diverging.rs:18:15: 18:19
+          StorageDead(_6);                 // scope 2 at $DIR/unreachable_diverging.rs:17:9: 17:10
+          StorageDead(_5);                 // scope 2 at $DIR/unreachable_diverging.rs:17:9: 17:10
+          StorageLive(_7);                 // scope 2 at $DIR/unreachable_diverging.rs:18:9: 18:22
+          unreachable;                     // scope 2 at $DIR/unreachable_diverging.rs:18:15: 18:19
       }
   
 -     bb6: {
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff
index 0529b15522e..f8b41d7b4c5 100644
--- a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff
+++ b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.32bit.diff
@@ -13,28 +13,30 @@
       let mut _8: !;                       // in scope 0 at $DIR/while_let_loops.rs:7:5: 10:6
       scope 1 {
           debug _x => _1;                  // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15
+          scope 2 {
+          }
       }
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/while_let_loops.rs:6:9: 6:15
           _1 = const 0_i32;                // scope 0 at $DIR/while_let_loops.rs:6:18: 6:19
-          StorageLive(_3);                 // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
-          Deinit(_3);                      // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
-          discriminant(_3) = 0;            // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
--         _4 = discriminant(_3);           // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
--         switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
-+         _4 = const 0_isize;              // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
-+         switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
+          StorageLive(_3);                 // scope 2 at $DIR/while_let_loops.rs:7:28: 7:32
+          Deinit(_3);                      // scope 2 at $DIR/while_let_loops.rs:7:28: 7:32
+          discriminant(_3) = 0;            // scope 2 at $DIR/while_let_loops.rs:7:28: 7:32
+-         _4 = discriminant(_3);           // scope 2 at $DIR/while_let_loops.rs:7:15: 7:25
+-         switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:7:15: 7:25
++         _4 = const 0_isize;              // scope 2 at $DIR/while_let_loops.rs:7:15: 7:25
++         switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:7:15: 7:25
       }
   
       bb1: {
-          switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
+          switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:7:15: 7:25
       }
   
       bb2: {
-          _1 = const 1_i32;                // scope 1 at $DIR/while_let_loops.rs:8:9: 8:15
-          nop;                             // scope 1 at $DIR/while_let_loops.rs:9:9: 9:14
-          goto -> bb4;                     // scope 1 at $DIR/while_let_loops.rs:9:9: 9:14
+          _1 = const 1_i32;                // scope 2 at $DIR/while_let_loops.rs:8:9: 8:15
+          nop;                             // scope 2 at $DIR/while_let_loops.rs:9:9: 9:14
+          goto -> bb4;                     // scope 2 at $DIR/while_let_loops.rs:9:9: 9:14
       }
   
       bb3: {
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff
index 0529b15522e..f8b41d7b4c5 100644
--- a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff
+++ b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.64bit.diff
@@ -13,28 +13,30 @@
       let mut _8: !;                       // in scope 0 at $DIR/while_let_loops.rs:7:5: 10:6
       scope 1 {
           debug _x => _1;                  // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15
+          scope 2 {
+          }
       }
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/while_let_loops.rs:6:9: 6:15
           _1 = const 0_i32;                // scope 0 at $DIR/while_let_loops.rs:6:18: 6:19
-          StorageLive(_3);                 // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
-          Deinit(_3);                      // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
-          discriminant(_3) = 0;            // scope 1 at $DIR/while_let_loops.rs:7:28: 7:32
--         _4 = discriminant(_3);           // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
--         switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
-+         _4 = const 0_isize;              // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
-+         switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
+          StorageLive(_3);                 // scope 2 at $DIR/while_let_loops.rs:7:28: 7:32
+          Deinit(_3);                      // scope 2 at $DIR/while_let_loops.rs:7:28: 7:32
+          discriminant(_3) = 0;            // scope 2 at $DIR/while_let_loops.rs:7:28: 7:32
+-         _4 = discriminant(_3);           // scope 2 at $DIR/while_let_loops.rs:7:15: 7:25
+-         switchInt(move _4) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:7:15: 7:25
++         _4 = const 0_isize;              // scope 2 at $DIR/while_let_loops.rs:7:15: 7:25
++         switchInt(const 0_isize) -> [1_isize: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:7:15: 7:25
       }
   
       bb1: {
-          switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 1 at $DIR/while_let_loops.rs:7:15: 7:25
+          switchInt(((_3 as Some).0: u32)) -> [0_u32: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:7:15: 7:25
       }
   
       bb2: {
-          _1 = const 1_i32;                // scope 1 at $DIR/while_let_loops.rs:8:9: 8:15
-          nop;                             // scope 1 at $DIR/while_let_loops.rs:9:9: 9:14
-          goto -> bb4;                     // scope 1 at $DIR/while_let_loops.rs:9:9: 9:14
+          _1 = const 1_i32;                // scope 2 at $DIR/while_let_loops.rs:8:9: 8:15
+          nop;                             // scope 2 at $DIR/while_let_loops.rs:9:9: 9:14
+          goto -> bb4;                     // scope 2 at $DIR/while_let_loops.rs:9:9: 9:14
       }
   
       bb3: {
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir
index 3c94fbddc44..5657f9413a1 100644
--- a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir
+++ b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.32bit.mir
@@ -5,6 +5,8 @@ fn change_loop_body() -> () {
     let mut _1: i32;                     // in scope 0 at $DIR/while_let_loops.rs:6:9: 6:15
     scope 1 {
         debug _x => _1;                  // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15
+        scope 2 {
+        }
     }
 
     bb0: {
diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir
index 3c94fbddc44..5657f9413a1 100644
--- a/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir
+++ b/src/test/mir-opt/while_let_loops.change_loop_body.PreCodegen.after.64bit.mir
@@ -5,6 +5,8 @@ fn change_loop_body() -> () {
     let mut _1: i32;                     // in scope 0 at $DIR/while_let_loops.rs:6:9: 6:15
     scope 1 {
         debug _x => _1;                  // in scope 1 at $DIR/while_let_loops.rs:6:9: 6:15
+        scope 2 {
+        }
     }
 
     bb0: {
diff --git a/src/test/pretty/where-clauses.rs b/src/test/pretty/where-clauses.rs
index 5614a81b0eb..4183799457b 100644
--- a/src/test/pretty/where-clauses.rs
+++ b/src/test/pretty/where-clauses.rs
@@ -2,4 +2,7 @@
 
 fn f<'a, 'b, T>(t: T) -> isize where T: 'a, 'a: 'b, T: Eq { 0 }
 
+// This is legal syntax, sometimes generated by macros. `where T: $($bound+)*`
+fn zero_bounds<'a, T>() where 'a:, T: {}
+
 fn main() {}
diff --git a/src/test/rustdoc-gui/duplicate-macro-reexport.goml b/src/test/rustdoc-gui/duplicate-macro-reexport.goml
index c79b3a220c4..9ea5990622a 100644
--- a/src/test/rustdoc-gui/duplicate-macro-reexport.goml
+++ b/src/test/rustdoc-gui/duplicate-macro-reexport.goml
@@ -1,14 +1,14 @@
 // This test ensures that there is no macro duplicates in the sidebar.
 goto: file://|DOC_PATH|/test_docs/macro.a.html
 // Waiting for the elements in the sidebar to be rendered.
-wait-for: ".sidebar-elems .others .macro"
+wait-for: ".sidebar-elems .macro"
 // Check there is only one macro named "a" listed in the sidebar.
 assert-count: (
-    "//*[@class='sidebar-elems']//*[@class='others']/*[@class='block macro']//li/a[text()='a']",
+    "//*[@class='sidebar-elems']//*[@class='block macro']//li/a[text()='a']",
     1,
 )
 // Check there is only one macro named "b" listed in the sidebar.
 assert-count: (
-    "//*[@class='sidebar-elems']//*[@class='others']/*[@class='block macro']//li/a[text()='b']",
+    "//*[@class='sidebar-elems']//*[@class='block macro']//li/a[text()='b']",
     1,
 )
diff --git a/src/test/rustdoc-gui/headings.goml b/src/test/rustdoc-gui/headings.goml
index 8f126d98fe4..67e97eb686e 100644
--- a/src/test/rustdoc-gui/headings.goml
+++ b/src/test/rustdoc-gui/headings.goml
@@ -106,8 +106,8 @@ assert-css: ("h6#sub-heading-for-enum-impl-item-doc", {"border-bottom-width": "0
 assert-css: ("h6#sub-sub-heading-for-enum-impl-item-doc", {"font-size": "14px"})
 assert-css: ("h6#sub-sub-heading-for-enum-impl-item-doc", {"border-bottom-width": "0px"})
 
-assert-text: (".sidebar .others h3", "Modules")
-assert-css: (".sidebar .others h3", {"border-bottom-width": "0px"}, ALL)
+assert-text: (".sidebar .mod h3", "Modules")
+assert-css: (".sidebar .mod h3", {"border-bottom-width": "0px"}, ALL)
 
 goto: file://|DOC_PATH|/test_docs/union.HeavilyDocumentedUnion.html
 
diff --git a/src/test/rustdoc/tuples.link1_i32.html b/src/test/rustdoc/tuples.link1_i32.html
new file mode 100644
index 00000000000..4efde28ed52
--- /dev/null
+++ b/src/test/rustdoc/tuples.link1_i32.html
@@ -0,0 +1 @@
+<code>pub fn tuple1(x: (<a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a>,)) -&gt; (<a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a>,)</code>
\ No newline at end of file
diff --git a/src/test/rustdoc/tuples.link1_t.html b/src/test/rustdoc/tuples.link1_t.html
new file mode 100644
index 00000000000..1cbaec05733
--- /dev/null
+++ b/src/test/rustdoc/tuples.link1_t.html
@@ -0,0 +1 @@
+<code>pub fn tuple1_t&lt;T&gt;(x: <a class="primitive" href="{{channel}}/std/primitive.tuple.html">(T,)</a>) -&gt; <a class="primitive" href="{{channel}}/std/primitive.tuple.html">(T,)</a></code>
\ No newline at end of file
diff --git a/src/test/rustdoc/tuples.link2_i32.html b/src/test/rustdoc/tuples.link2_i32.html
new file mode 100644
index 00000000000..77c8d81b842
--- /dev/null
+++ b/src/test/rustdoc/tuples.link2_i32.html
@@ -0,0 +1 @@
+<code>pub fn tuple2(x: (<a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a>, <a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a>)) -&gt; (<a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a>, <a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a>)</code>
\ No newline at end of file
diff --git a/src/test/rustdoc/tuples.link2_t.html b/src/test/rustdoc/tuples.link2_t.html
new file mode 100644
index 00000000000..2477aa6be9d
--- /dev/null
+++ b/src/test/rustdoc/tuples.link2_t.html
@@ -0,0 +1 @@
+<code>pub fn tuple2_t&lt;T&gt;(x: <a class="primitive" href="{{channel}}/std/primitive.tuple.html">(T, T)</a>) -&gt; <a class="primitive" href="{{channel}}/std/primitive.tuple.html">(T, T)</a></code>
\ No newline at end of file
diff --git a/src/test/rustdoc/tuples.link2_tu.html b/src/test/rustdoc/tuples.link2_tu.html
new file mode 100644
index 00000000000..b02f8dd8d65
--- /dev/null
+++ b/src/test/rustdoc/tuples.link2_tu.html
@@ -0,0 +1 @@
+<code>pub fn tuple2_tu&lt;T, U&gt;(x: <a class="primitive" href="{{channel}}/std/primitive.tuple.html">(T, U)</a>) -&gt; <a class="primitive" href="{{channel}}/std/primitive.tuple.html">(T, U)</a></code>
\ No newline at end of file
diff --git a/src/test/rustdoc/tuples.link_unit.html b/src/test/rustdoc/tuples.link_unit.html
new file mode 100644
index 00000000000..839990e1587
--- /dev/null
+++ b/src/test/rustdoc/tuples.link_unit.html
@@ -0,0 +1 @@
+<code>pub fn tuple0(x: <a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>)</code>
\ No newline at end of file
diff --git a/src/test/rustdoc/tuples.rs b/src/test/rustdoc/tuples.rs
index 53654abff2a..62e2f9e7ef2 100644
--- a/src/test/rustdoc/tuples.rs
+++ b/src/test/rustdoc/tuples.rs
@@ -1,8 +1,20 @@
 #![crate_name = "foo"]
 
 // @has foo/fn.tuple0.html //pre 'pub fn tuple0(x: ())'
+// @snapshot link_unit - '//pre[@class="rust fn"]/code'
 pub fn tuple0(x: ()) -> () { x }
 // @has foo/fn.tuple1.html //pre 'pub fn tuple1(x: (i32,)) -> (i32,)'
+// @snapshot link1_i32 - '//pre[@class="rust fn"]/code'
 pub fn tuple1(x: (i32,)) -> (i32,) { x }
 // @has foo/fn.tuple2.html //pre 'pub fn tuple2(x: (i32, i32)) -> (i32, i32)'
+// @snapshot link2_i32 - '//pre[@class="rust fn"]/code'
 pub fn tuple2(x: (i32, i32)) -> (i32, i32) { x }
+// @has foo/fn.tuple1_t.html //pre 'pub fn tuple1_t<T>(x: (T,)) -> (T,)'
+// @snapshot link1_t - '//pre[@class="rust fn"]/code'
+pub fn tuple1_t<T>(x: (T,)) -> (T,) { x }
+// @has foo/fn.tuple2_t.html //pre 'pub fn tuple2_t<T>(x: (T, T)) -> (T, T)'
+// @snapshot link2_t - '//pre[@class="rust fn"]/code'
+pub fn tuple2_t<T>(x: (T, T)) -> (T, T) { x }
+// @has foo/fn.tuple2_tu.html //pre 'pub fn tuple2_tu<T, U>(x: (T, U)) -> (T, U)'
+// @snapshot link2_tu - '//pre[@class="rust fn"]/code'
+pub fn tuple2_tu<T, U>(x: (T, U)) -> (T, U) { x }
diff --git a/src/test/ui/argument-suggestions/basic.stderr b/src/test/ui/argument-suggestions/basic.stderr
index b44e77b43f8..dd4812b5b25 100644
--- a/src/test/ui/argument-suggestions/basic.stderr
+++ b/src/test/ui/argument-suggestions/basic.stderr
@@ -41,8 +41,8 @@ LL | fn missing(_i: u32) {}
    |    ^^^^^^^ -------
 help: provide the argument
    |
-LL |     missing({u32});
-   |     ~~~~~~~~~~~~~~
+LL |     missing(/* u32 */);
+   |     ~~~~~~~~~~~~~~~~~~
 
 error[E0308]: arguments to this function are incorrect
   --> $DIR/basic.rs:23:5
@@ -94,8 +94,8 @@ LL |     let closure = |x| x;
    |                   ^^^
 help: provide the argument
    |
-LL |     closure({_});
-   |     ~~~~~~~~~~~~
+LL |     closure(/* value */);
+   |     ~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/argument-suggestions/complex.stderr b/src/test/ui/argument-suggestions/complex.stderr
index c628f7dff34..fa030a8f49d 100644
--- a/src/test/ui/argument-suggestions/complex.stderr
+++ b/src/test/ui/argument-suggestions/complex.stderr
@@ -11,8 +11,8 @@ LL | fn complex(_i: u32, _s: &str, _e: E, _f: F, _g: G, _x: X, _y: Y, _z: Z ) {}
    |    ^^^^^^^ -------  --------  -----  -----  -----  -----  -----  ------
 help: did you mean
    |
-LL |   complex({u32}, &"", {E}, F::X2, G{}, X {}, Y {}, Z {});
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   complex(/* u32 */, &"", /* E */, F::X2, G{}, X {}, Y {}, Z {});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/argument-suggestions/issue-96638.stderr b/src/test/ui/argument-suggestions/issue-96638.stderr
index 35190e2ca0d..8af31b8b751 100644
--- a/src/test/ui/argument-suggestions/issue-96638.stderr
+++ b/src/test/ui/argument-suggestions/issue-96638.stderr
@@ -11,8 +11,8 @@ LL | fn f(_: usize, _: &usize, _: usize) {}
    |    ^ --------  ---------  --------
 help: provide the argument
    |
-LL |     f({usize}, &x, {usize});
-   |     ~~~~~~~~~~~~~~~~~~~~~~~
+LL |     f(/* usize */, &x, /* usize */);
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/argument-suggestions/issue-97197.stderr b/src/test/ui/argument-suggestions/issue-97197.stderr
index 10689d50957..ac54adc5eeb 100644
--- a/src/test/ui/argument-suggestions/issue-97197.stderr
+++ b/src/test/ui/argument-suggestions/issue-97197.stderr
@@ -11,8 +11,8 @@ LL | pub fn g(a1: (), a2: bool, a3: bool, a4: bool, a5: bool, a6: ()) -> () {}
    |        ^ ------  --------  --------  --------  --------  ------
 help: provide the arguments
    |
-LL |     g((), {bool}, {bool}, {bool}, {bool}, ());
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     g((), /* bool */, /* bool */, /* bool */, /* bool */, ());
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/argument-suggestions/issue-97484.stderr b/src/test/ui/argument-suggestions/issue-97484.stderr
index 62ddabea0d7..2af24d521f3 100644
--- a/src/test/ui/argument-suggestions/issue-97484.stderr
+++ b/src/test/ui/argument-suggestions/issue-97484.stderr
@@ -19,8 +19,8 @@ LL +     foo(&&A, B, C, D, E, F, G);
    |
 help: remove the extra arguments
    |
-LL |     foo(&&A, D, {&E}, G);
-   |     ~~~~~~~~~~~~~~~~~~~~
+LL |     foo(&&A, D, /* &E */, G);
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/argument-suggestions/missing_arguments.stderr b/src/test/ui/argument-suggestions/missing_arguments.stderr
index 5236d15b945..2509d22d7ff 100644
--- a/src/test/ui/argument-suggestions/missing_arguments.stderr
+++ b/src/test/ui/argument-suggestions/missing_arguments.stderr
@@ -11,8 +11,8 @@ LL | fn one_arg(_a: i32) {}
    |    ^^^^^^^ -------
 help: provide the argument
    |
-LL |   one_arg({i32});
-   |   ~~~~~~~~~~~~~~
+LL |   one_arg(/* i32 */);
+   |   ~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 2 arguments but 0 arguments were supplied
   --> $DIR/missing_arguments.rs:14:3
@@ -27,8 +27,8 @@ LL | fn two_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^ -------  -------
 help: provide the arguments
    |
-LL |   two_same({i32}, {i32});
-   |   ~~~~~~~~~~~~~~~~~~~~~~
+LL |   two_same(/* i32 */, /* i32 */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 2 arguments but 1 argument was supplied
   --> $DIR/missing_arguments.rs:15:3
@@ -43,8 +43,8 @@ LL | fn two_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^ -------  -------
 help: provide the argument
    |
-LL |   two_same(1, {i32});
-   |   ~~~~~~~~~~~~~~~~~~
+LL |   two_same(1, /* i32 */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 2 arguments but 0 arguments were supplied
   --> $DIR/missing_arguments.rs:16:3
@@ -59,8 +59,8 @@ LL | fn two_diff(_a: i32, _b: f32) {}
    |    ^^^^^^^^ -------  -------
 help: provide the arguments
    |
-LL |   two_diff({i32}, {f32});
-   |   ~~~~~~~~~~~~~~~~~~~~~~
+LL |   two_diff(/* i32 */, /* f32 */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 2 arguments but 1 argument was supplied
   --> $DIR/missing_arguments.rs:17:3
@@ -75,8 +75,8 @@ LL | fn two_diff(_a: i32, _b: f32) {}
    |    ^^^^^^^^ -------  -------
 help: provide the argument
    |
-LL |   two_diff(1, {f32});
-   |   ~~~~~~~~~~~~~~~~~~
+LL |   two_diff(1, /* f32 */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 2 arguments but 1 argument was supplied
   --> $DIR/missing_arguments.rs:18:3
@@ -91,8 +91,8 @@ LL | fn two_diff(_a: i32, _b: f32) {}
    |    ^^^^^^^^ -------  -------
 help: provide the argument
    |
-LL |   two_diff({i32}, 1.0);
-   |   ~~~~~~~~~~~~~~~~~~~~
+LL |   two_diff(/* i32 */, 1.0);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 3 arguments but 0 arguments were supplied
   --> $DIR/missing_arguments.rs:21:3
@@ -107,8 +107,8 @@ LL | fn three_same(_a: i32, _b: i32, _c: i32) {}
    |    ^^^^^^^^^^ -------  -------  -------
 help: provide the arguments
    |
-LL |   three_same({i32}, {i32}, {i32});
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_same(/* i32 */, /* i32 */, /* i32 */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 3 arguments but 1 argument was supplied
   --> $DIR/missing_arguments.rs:22:3
@@ -123,8 +123,8 @@ LL | fn three_same(_a: i32, _b: i32, _c: i32) {}
    |    ^^^^^^^^^^ -------  -------  -------
 help: provide the arguments
    |
-LL |   three_same(1, {i32}, {i32});
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_same(1, /* i32 */, /* i32 */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 3 arguments but 2 arguments were supplied
   --> $DIR/missing_arguments.rs:23:3
@@ -139,8 +139,8 @@ LL | fn three_same(_a: i32, _b: i32, _c: i32) {}
    |    ^^^^^^^^^^ -------  -------  -------
 help: provide the argument
    |
-LL |   three_same(1, 1, {i32});
-   |   ~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_same(1, 1, /* i32 */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 3 arguments but 2 arguments were supplied
   --> $DIR/missing_arguments.rs:26:3
@@ -155,8 +155,8 @@ LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
    |    ^^^^^^^^^^ -------  -------  --------
 help: provide the argument
    |
-LL |   three_diff({i32}, 1.0, "");
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_diff(/* i32 */, 1.0, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 3 arguments but 2 arguments were supplied
   --> $DIR/missing_arguments.rs:27:3
@@ -171,8 +171,8 @@ LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
    |    ^^^^^^^^^^ -------  -------  --------
 help: provide the argument
    |
-LL |   three_diff(1, {f32}, "");
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_diff(1, /* f32 */, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 3 arguments but 2 arguments were supplied
   --> $DIR/missing_arguments.rs:28:3
@@ -187,8 +187,8 @@ LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
    |    ^^^^^^^^^^ -------  -------  --------
 help: provide the argument
    |
-LL |   three_diff(1, 1.0, {&str});
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_diff(1, 1.0, /* &str */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 3 arguments but 1 argument was supplied
   --> $DIR/missing_arguments.rs:29:3
@@ -203,8 +203,8 @@ LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
    |    ^^^^^^^^^^ -------  -------  --------
 help: provide the arguments
    |
-LL |   three_diff({i32}, {f32}, "");
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_diff(/* i32 */, /* f32 */, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 3 arguments but 1 argument was supplied
   --> $DIR/missing_arguments.rs:30:3
@@ -222,8 +222,8 @@ LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
    |    ^^^^^^^^^^ -------  -------  --------
 help: provide the arguments
    |
-LL |   three_diff({i32}, 1.0, {&str});
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_diff(/* i32 */, 1.0, /* &str */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 3 arguments but 1 argument was supplied
   --> $DIR/missing_arguments.rs:31:3
@@ -238,8 +238,8 @@ LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
    |    ^^^^^^^^^^ -------  -------  --------
 help: provide the arguments
    |
-LL |   three_diff(1, {f32}, {&str});
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_diff(1, /* f32 */, /* &str */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 4 arguments but 0 arguments were supplied
   --> $DIR/missing_arguments.rs:34:3
@@ -254,8 +254,8 @@ LL | fn four_repeated(_a: i32, _b: f32, _c: f32, _d: &str) {}
    |    ^^^^^^^^^^^^^ -------  -------  -------  --------
 help: provide the arguments
    |
-LL |   four_repeated({i32}, {f32}, {f32}, {&str});
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   four_repeated(/* i32 */, /* f32 */, /* f32 */, /* &str */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 4 arguments but 2 arguments were supplied
   --> $DIR/missing_arguments.rs:35:3
@@ -270,8 +270,8 @@ LL | fn four_repeated(_a: i32, _b: f32, _c: f32, _d: &str) {}
    |    ^^^^^^^^^^^^^ -------  -------  -------  --------
 help: provide the arguments
    |
-LL |   four_repeated(1, {f32}, {f32}, "");
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   four_repeated(1, /* f32 */, /* f32 */, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 5 arguments but 0 arguments were supplied
   --> $DIR/missing_arguments.rs:38:3
@@ -286,8 +286,8 @@ LL | fn complex(_a: i32, _b: f32, _c: i32, _d: f32, _e: &str) {}
    |    ^^^^^^^ -------  -------  -------  -------  --------
 help: provide the arguments
    |
-LL |   complex({i32}, {f32}, {i32}, {f32}, {&str});
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   complex(/* i32 */, /* f32 */, /* i32 */, /* f32 */, /* &str */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 5 arguments but 2 arguments were supplied
   --> $DIR/missing_arguments.rs:39:3
@@ -302,8 +302,8 @@ LL | fn complex(_a: i32, _b: f32, _c: i32, _d: f32, _e: &str) {}
    |    ^^^^^^^ -------  -------  -------  -------  --------
 help: provide the arguments
    |
-LL |   complex(1, {f32}, {i32}, {f32}, "");
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   complex(1, /* f32 */, /* i32 */, /* f32 */, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 19 previous errors
 
diff --git a/src/test/ui/argument-suggestions/mixed_cases.stderr b/src/test/ui/argument-suggestions/mixed_cases.stderr
index 78765335c02..3fe4473a594 100644
--- a/src/test/ui/argument-suggestions/mixed_cases.stderr
+++ b/src/test/ui/argument-suggestions/mixed_cases.stderr
@@ -13,8 +13,8 @@ LL | fn two_args(_a: i32, _b: f32) {}
    |    ^^^^^^^^ -------  -------
 help: remove the extra argument
    |
-LL |   two_args(1, {f32});
-   |   ~~~~~~~~~~~~~~~~~~
+LL |   two_args(1, /* f32 */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 3 arguments but 4 arguments were supplied
   --> $DIR/mixed_cases.rs:11:3
@@ -32,8 +32,8 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
    |    ^^^^^^^^^^ -------  -------  --------
 help: did you mean
    |
-LL |   three_args(1, {f32}, "");
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_args(1, /* f32 */, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 3 arguments but 2 arguments were supplied
   --> $DIR/mixed_cases.rs:14:3
@@ -51,8 +51,8 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
    |    ^^^^^^^^^^ -------  -------  --------
 help: provide the argument
    |
-LL |   three_args(1, {f32}, {&str});
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_args(1, /* f32 */, /* &str */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0308]: arguments to this function are incorrect
   --> $DIR/mixed_cases.rs:17:3
@@ -69,8 +69,8 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
    |    ^^^^^^^^^^ -------  -------  --------
 help: did you mean
    |
-LL |   three_args(1, {f32}, "");
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_args(1, /* f32 */, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0308]: arguments to this function are incorrect
   --> $DIR/mixed_cases.rs:20:3
@@ -88,8 +88,8 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
    |    ^^^^^^^^^^ -------  -------  --------
 help: swap these arguments
    |
-LL |   three_args(1, {f32}, "");
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_args(1, /* f32 */, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 3 arguments but 2 arguments were supplied
   --> $DIR/mixed_cases.rs:23:3
@@ -108,8 +108,8 @@ LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
    |    ^^^^^^^^^^ -------  -------  --------
 help: did you mean
    |
-LL |   three_args(1, {f32}, "");
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   three_args(1, /* f32 */, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/issues/issue-47139-2.rs b/src/test/ui/associated-types/issue-47139-2.rs
index d2ef8942530..d2ef8942530 100644
--- a/src/test/ui/issues/issue-47139-2.rs
+++ b/src/test/ui/associated-types/issue-47139-2.rs
diff --git a/src/test/ui/c-variadic/variadic-ffi-1.stderr b/src/test/ui/c-variadic/variadic-ffi-1.stderr
index 9acf1e93b07..176bec819d6 100644
--- a/src/test/ui/c-variadic/variadic-ffi-1.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-1.stderr
@@ -17,8 +17,8 @@ LL |     fn foo(f: isize, x: u8, ...);
    |        ^^^
 help: provide the arguments
    |
-LL |         foo({isize}, {u8});
-   |         ~~~~~~~~~~~~~~~~~~
+LL |         foo(/* isize */, /* u8 */);
+   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0060]: this function takes at least 2 arguments but 1 argument was supplied
   --> $DIR/variadic-ffi-1.rs:21:9
@@ -33,8 +33,8 @@ LL |     fn foo(f: isize, x: u8, ...);
    |        ^^^
 help: provide the argument
    |
-LL |         foo(1, {u8});
-   |         ~~~~~~~~~~~~
+LL |         foo(1, /* u8 */);
+   |         ~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/variadic-ffi-1.rs:23:56
diff --git a/src/test/ui/issues/issue-10991.rs b/src/test/ui/cast/issue-10991.rs
index c36829fdf5b..c36829fdf5b 100644
--- a/src/test/ui/issues/issue-10991.rs
+++ b/src/test/ui/cast/issue-10991.rs
diff --git a/src/test/ui/issues/issue-10991.stderr b/src/test/ui/cast/issue-10991.stderr
index 5b8a1823386..5b8a1823386 100644
--- a/src/test/ui/issues/issue-10991.stderr
+++ b/src/test/ui/cast/issue-10991.stderr
diff --git a/src/test/ui/issues/issue-28950.rs b/src/test/ui/codegen/issue-28950.rs
index 8b55f42f3f4..8b55f42f3f4 100644
--- a/src/test/ui/issues/issue-28950.rs
+++ b/src/test/ui/codegen/issue-28950.rs
diff --git a/src/test/ui/issues/issue-63787.rs b/src/test/ui/codegen/issue-63787.rs
index cba079b2315..cba079b2315 100644
--- a/src/test/ui/issues/issue-63787.rs
+++ b/src/test/ui/codegen/issue-63787.rs
diff --git a/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.stderr b/src/test/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr
index f30693221a5..0a7db62472a 100644
--- a/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.stderr
+++ b/src/test/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr
@@ -1,5 +1,5 @@
 error: `&'static [u32]` is forbidden as the type of a const generic parameter
-  --> $DIR/static-reference-array-const-param.rs:1:15
+  --> $DIR/issue-73727-static-reference-array-const-param.rs:9:15
    |
 LL | fn a<const X: &'static [u32]>() {}
    |               ^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-73727-static-reference-array-const-param.rs b/src/test/ui/const-generics/issues/issue-73727-static-reference-array-const-param.rs
new file mode 100644
index 00000000000..f0d604835cb
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-73727-static-reference-array-const-param.rs
@@ -0,0 +1,14 @@
+// Regression test for #73727
+
+// revisions: full min
+//[full]check-pass
+
+#![cfg_attr(full, feature(adt_const_params))]
+#![cfg_attr(full, allow(incomplete_features))]
+
+fn a<const X: &'static [u32]>() {}
+//[min]~^ ERROR `&'static [u32]` is forbidden as the type of a const generic parameter
+
+fn main() {
+    a::<{&[]}>();
+}
diff --git a/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs b/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs
deleted file mode 100644
index 7518dc59e59..00000000000
--- a/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-fn a<const X: &'static [u32]>() {}
-//~^ ERROR `&'static [u32]` is forbidden as the type of a const generic parameter
-
-fn main() {
-    a::<{&[]}>();
-}
diff --git a/src/test/ui/consts/const-eval/format.rs b/src/test/ui/consts/const-eval/format.rs
new file mode 100644
index 00000000000..e43633da3cc
--- /dev/null
+++ b/src/test/ui/consts/const-eval/format.rs
@@ -0,0 +1,21 @@
+const fn failure() {
+    panic!("{:?}", 0);
+    //~^ ERROR cannot call non-const formatting macro in constant functions
+    //~| ERROR erroneous constant used
+    //~| ERROR erroneous constant used
+    //~| WARN this was previously accepted by the compiler
+    //~| WARN this was previously accepted by the compiler
+}
+
+const fn print() {
+    println!("{:?}", 0);
+    //~^ ERROR cannot call non-const formatting macro in constant functions
+    //~| ERROR `Arguments::<'a>::new_v1` is not yet stable as a const fn
+    //~| ERROR cannot call non-const fn `_print` in constant functions
+    //~| ERROR erroneous constant used
+    //~| ERROR erroneous constant used
+    //~| WARN this was previously accepted by the compiler
+    //~| WARN this was previously accepted by the compiler
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/const-eval/format.stderr b/src/test/ui/consts/const-eval/format.stderr
new file mode 100644
index 00000000000..44f436ae4e3
--- /dev/null
+++ b/src/test/ui/consts/const-eval/format.stderr
@@ -0,0 +1,78 @@
+error[E0015]: cannot call non-const formatting macro in constant functions
+  --> $DIR/format.rs:2:20
+   |
+LL |     panic!("{:?}", 0);
+   |                    ^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: this error originates in the macro `$crate::const_format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0015]: cannot call non-const formatting macro in constant functions
+  --> $DIR/format.rs:11:22
+   |
+LL |     println!("{:?}", 0);
+   |                      ^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: `Arguments::<'a>::new_v1` is not yet stable as a const fn
+  --> $DIR/format.rs:11:5
+   |
+LL |     println!("{:?}", 0);
+   |     ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(const_fmt_arguments_new)]` to the crate attributes to enable
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0015]: cannot call non-const fn `_print` in constant functions
+  --> $DIR/format.rs:11:5
+   |
+LL |     println!("{:?}", 0);
+   |     ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: erroneous constant used
+  --> $DIR/format.rs:2:12
+   |
+LL |     panic!("{:?}", 0);
+   |            ^^^^^^ referenced constant has errors
+   |
+   = note: `#[deny(const_err)]` on by default
+   = 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 #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+error: erroneous constant used
+  --> $DIR/format.rs:2:20
+   |
+LL |     panic!("{:?}", 0);
+   |                    ^ referenced constant has errors
+   |
+   = 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 #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: this error originates in the macro `$crate::const_format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: erroneous constant used
+  --> $DIR/format.rs:11:14
+   |
+LL |     println!("{:?}", 0);
+   |              ^^^^^^ referenced constant has errors
+   |
+   = 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 #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+error: erroneous constant used
+  --> $DIR/format.rs:11:22
+   |
+LL |     println!("{:?}", 0);
+   |                      ^ referenced constant has errors
+   |
+   = 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 #71800 <https://github.com/rust-lang/rust/issues/71800>
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
index 65ab1b02b35..acb9bda31d1 100644
--- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
+++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
@@ -1,3 +1,15 @@
+warning: the type `!` does not permit zero-initialization
+  --> $DIR/validate_uninhabited_zsts.rs:4:14
+   |
+LL |     unsafe { std::mem::transmute(()) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^
+   |              |
+   |              this code causes undefined behavior when executed
+   |              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: `#[warn(invalid_value)]` on by default
+   = note: the `!` type has no valid value
+
 error[E0080]: evaluation of constant value failed
   --> $DIR/validate_uninhabited_zsts.rs:4:14
    |
@@ -19,18 +31,6 @@ LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 0, align: 1) {}
 
-warning: the type `!` does not permit zero-initialization
-  --> $DIR/validate_uninhabited_zsts.rs:4:14
-   |
-LL |     unsafe { std::mem::transmute(()) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^
-   |              |
-   |              this code causes undefined behavior when executed
-   |              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
-   |
-   = note: `#[warn(invalid_value)]` on by default
-   = note: the `!` type has no valid value
-
 warning: the type `empty::Empty` does not permit zero-initialization
   --> $DIR/validate_uninhabited_zsts.rs:23:42
    |
diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
index 65ab1b02b35..acb9bda31d1 100644
--- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
+++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
@@ -1,3 +1,15 @@
+warning: the type `!` does not permit zero-initialization
+  --> $DIR/validate_uninhabited_zsts.rs:4:14
+   |
+LL |     unsafe { std::mem::transmute(()) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^
+   |              |
+   |              this code causes undefined behavior when executed
+   |              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: `#[warn(invalid_value)]` on by default
+   = note: the `!` type has no valid value
+
 error[E0080]: evaluation of constant value failed
   --> $DIR/validate_uninhabited_zsts.rs:4:14
    |
@@ -19,18 +31,6 @@ LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 0, align: 1) {}
 
-warning: the type `!` does not permit zero-initialization
-  --> $DIR/validate_uninhabited_zsts.rs:4:14
-   |
-LL |     unsafe { std::mem::transmute(()) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^
-   |              |
-   |              this code causes undefined behavior when executed
-   |              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
-   |
-   = note: `#[warn(invalid_value)]` on by default
-   = note: the `!` type has no valid value
-
 warning: the type `empty::Empty` does not permit zero-initialization
   --> $DIR/validate_uninhabited_zsts.rs:23:42
    |
diff --git a/src/test/ui/consts/recursive-zst-static.default.stderr b/src/test/ui/consts/recursive-zst-static.default.stderr
index 2a4ad5825ec..104899f4900 100644
--- a/src/test/ui/consts/recursive-zst-static.default.stderr
+++ b/src/test/ui/consts/recursive-zst-static.default.stderr
@@ -10,7 +10,15 @@ note: ...which requires const-evaluating + checking `FOO`...
 LL | static FOO: () = FOO;
    |                  ^^^
    = note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
-   = note: cycle used when running analysis passes on this crate
+note: cycle used when linting top-level module
+  --> $DIR/recursive-zst-static.rs:10:1
+   |
+LL | / static FOO: () = FOO;
+LL | |
+LL | | fn main() {
+LL | |     FOO
+LL | | }
+   | |_^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/recursive-zst-static.unleash.stderr b/src/test/ui/consts/recursive-zst-static.unleash.stderr
index 2a4ad5825ec..104899f4900 100644
--- a/src/test/ui/consts/recursive-zst-static.unleash.stderr
+++ b/src/test/ui/consts/recursive-zst-static.unleash.stderr
@@ -10,7 +10,15 @@ note: ...which requires const-evaluating + checking `FOO`...
 LL | static FOO: () = FOO;
    |                  ^^^
    = note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
-   = note: cycle used when running analysis passes on this crate
+note: cycle used when linting top-level module
+  --> $DIR/recursive-zst-static.rs:10:1
+   |
+LL | / static FOO: () = FOO;
+LL | |
+LL | | fn main() {
+LL | |     FOO
+LL | | }
+   | |_^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/write-to-static-mut-in-static.stderr b/src/test/ui/consts/write-to-static-mut-in-static.stderr
index ab4b8844e5b..8d5113cbfd9 100644
--- a/src/test/ui/consts/write-to-static-mut-in-static.stderr
+++ b/src/test/ui/consts/write-to-static-mut-in-static.stderr
@@ -16,7 +16,17 @@ note: ...which requires const-evaluating + checking `C`...
 LL | pub static mut C: u32 = unsafe { C = 1; 0 };
    |                                  ^^^^^
    = note: ...which again requires const-evaluating + checking `C`, completing the cycle
-   = note: cycle used when running analysis passes on this crate
+note: cycle used when linting top-level module
+  --> $DIR/write-to-static-mut-in-static.rs:1:1
+   |
+LL | / pub static mut A: u32 = 0;
+LL | | pub static mut B: () = unsafe { A = 1; };
+LL | |
+LL | |
+...  |
+LL | |
+LL | | fn main() {}
+   | |____________^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/derives/issue-97343.stderr b/src/test/ui/derives/issue-97343.stderr
index ac797a8f501..e83bbb5b60d 100644
--- a/src/test/ui/derives/issue-97343.stderr
+++ b/src/test/ui/derives/issue-97343.stderr
@@ -4,7 +4,7 @@ error[E0109]: type arguments are not allowed on type parameter `Irrelevant`
 LL | #[derive(Debug)]
    |          -----
    |          |
-   |          not allowed on this
+   |          not allowed on type parameter `Irrelevant`
    |          in this derive macro expansion
 LL | pub struct Irrelevant<Irrelevant> {
    |                       ^^^^^^^^^^ type argument not allowed
diff --git a/src/test/ui/issues/issue-6341.rs b/src/test/ui/deriving/issue-6341.rs
index 1be1394dfae..1be1394dfae 100644
--- a/src/test/ui/issues/issue-6341.rs
+++ b/src/test/ui/deriving/issue-6341.rs
diff --git a/src/test/ui/error-codes/E0057.stderr b/src/test/ui/error-codes/E0057.stderr
index 4b4d30a8387..3697b5fcf15 100644
--- a/src/test/ui/error-codes/E0057.stderr
+++ b/src/test/ui/error-codes/E0057.stderr
@@ -11,8 +11,8 @@ LL |     let f = |x| x * 3;
    |             ^^^
 help: provide the argument
    |
-LL |     let a = f({_});
-   |             ~~~~~~
+LL |     let a = f(/* value */);
+   |             ~~~~~~~~~~~~~~
 
 error[E0057]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/E0057.rs:5:13
diff --git a/src/test/ui/error-codes/E0060.stderr b/src/test/ui/error-codes/E0060.stderr
index 9dd649239e2..644fd598338 100644
--- a/src/test/ui/error-codes/E0060.stderr
+++ b/src/test/ui/error-codes/E0060.stderr
@@ -11,8 +11,8 @@ LL |     fn printf(_: *const u8, ...) -> u32;
    |        ^^^^^^
 help: provide the argument
    |
-LL |     unsafe { printf({*const u8}); }
-   |              ~~~~~~~~~~~~~~~~~~~
+LL |     unsafe { printf(/* *const u8 */); }
+   |              ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0061.stderr b/src/test/ui/error-codes/E0061.stderr
index f92c548f2de..fa55db0924d 100644
--- a/src/test/ui/error-codes/E0061.stderr
+++ b/src/test/ui/error-codes/E0061.stderr
@@ -11,8 +11,8 @@ LL | fn f(a: u16, b: &str) {}
    |    ^ ------  -------
 help: provide the argument
    |
-LL |     f(0, {&str});
-   |     ~~~~~~~~~~~~
+LL |     f(0, /* &str */);
+   |     ~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 1 argument but 0 arguments were supplied
   --> $DIR/E0061.rs:9:5
@@ -27,8 +27,8 @@ LL | fn f2(a: u16) {}
    |    ^^ ------
 help: provide the argument
    |
-LL |     f2({u16});
-   |     ~~~~~~~~~
+LL |     f2(/* u16 */);
+   |     ~~~~~~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/error-codes/E0109.stderr b/src/test/ui/error-codes/E0109.stderr
index 7858a9e3028..da00fdde6bd 100644
--- a/src/test/ui/error-codes/E0109.stderr
+++ b/src/test/ui/error-codes/E0109.stderr
@@ -4,7 +4,7 @@ error[E0109]: type arguments are not allowed on this type
 LL | type X = u32<i32>;
    |          --- ^^^ type argument not allowed
    |          |
-   |          not allowed on this
+   |          not allowed on this type
    |
 help: primitive type `u32` doesn't have generic parameters
    |
diff --git a/src/test/ui/error-codes/E0110.stderr b/src/test/ui/error-codes/E0110.stderr
index 68f98b6f17d..5babb5c2961 100644
--- a/src/test/ui/error-codes/E0110.stderr
+++ b/src/test/ui/error-codes/E0110.stderr
@@ -4,7 +4,7 @@ error[E0109]: lifetime arguments are not allowed on this type
 LL | type X = u32<'static>;
    |          --- ^^^^^^^ lifetime argument not allowed
    |          |
-   |          not allowed on this
+   |          not allowed on this type
    |
 help: primitive type `u32` doesn't have generic parameters
    |
diff --git a/src/test/ui/error-codes/E0411.stderr b/src/test/ui/error-codes/E0411.stderr
index c1c25e835c1..4c99f9fcbf1 100644
--- a/src/test/ui/error-codes/E0411.stderr
+++ b/src/test/ui/error-codes/E0411.stderr
@@ -1,6 +1,8 @@
 error[E0411]: cannot find type `Self` in this scope
   --> $DIR/E0411.rs:2:6
    |
+LL | fn main() {
+   |    ---- `Self` not allowed in a function
 LL |     <Self>::foo;
    |      ^^^^ `Self` is only available in impls, traits, and type definitions
 
diff --git a/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr b/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr
index 7a2441047b5..d429b4e8eff 100644
--- a/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr
+++ b/src/test/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr
@@ -7,9 +7,8 @@ LL |     m!(0f32, f32::NEG_INFINITY..);
    = note: the matched value is of type `f32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         _ => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, _ => todo!() }
+   |                                ++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:17:8
@@ -20,9 +19,8 @@ LL |     m!(0f32, ..f32::INFINITY);
    = note: the matched value is of type `f32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         _ => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, _ => todo!() }
+   |                                ++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `'\u{10ffff}'` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:26:8
@@ -33,9 +31,8 @@ LL |     m!('a', ..core::char::MAX);
    = note: the matched value is of type `char`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         '\u{10ffff}' => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, '\u{10ffff}' => todo!() }
+   |                                +++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `'\u{10fffe}'..='\u{10ffff}'` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:27:8
@@ -46,9 +43,8 @@ LL |     m!('a', ..ALMOST_MAX);
    = note: the matched value is of type `char`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         '\u{10fffe}'..='\u{10ffff}' => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, '\u{10fffe}'..='\u{10ffff}' => todo!() }
+   |                                ++++++++++++++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `'\0'` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:28:8
@@ -59,9 +55,8 @@ LL |     m!('a', ALMOST_MIN..);
    = note: the matched value is of type `char`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         '\0' => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, '\0' => todo!() }
+   |                                +++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `'\u{10ffff}'` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:29:8
@@ -72,9 +67,8 @@ LL |     m!('a', ..=ALMOST_MAX);
    = note: the matched value is of type `char`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         '\u{10ffff}' => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, '\u{10ffff}' => todo!() }
+   |                                +++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `'b'` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:30:8
@@ -85,9 +79,8 @@ LL |     m!('a', ..=VAL | VAL_2..);
    = note: the matched value is of type `char`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         'b' => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 'b' => todo!() }
+   |                                ++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `'b'` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:31:8
@@ -98,9 +91,8 @@ LL |     m!('a', ..VAL_1 | VAL_2..);
    = note: the matched value is of type `char`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         'b' => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 'b' => todo!() }
+   |                                ++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:41:12
@@ -111,9 +103,8 @@ LL |         m!(0, ..u8::MAX);
    = note: the matched value is of type `u8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u8::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u8::MAX => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `254_u8..=u8::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:42:12
@@ -124,9 +115,8 @@ LL |         m!(0, ..ALMOST_MAX);
    = note: the matched value is of type `u8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         254_u8..=u8::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 254_u8..=u8::MAX => todo!() }
+   |                                +++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `0_u8` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:43:12
@@ -137,9 +127,8 @@ LL |         m!(0, ALMOST_MIN..);
    = note: the matched value is of type `u8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         0_u8 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 0_u8 => todo!() }
+   |                                +++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:44:12
@@ -150,9 +139,8 @@ LL |         m!(0, ..=ALMOST_MAX);
    = note: the matched value is of type `u8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u8::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u8::MAX => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_u8` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:45:12
@@ -163,9 +151,8 @@ LL |         m!(0, ..=VAL | VAL_2..);
    = note: the matched value is of type `u8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_u8 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_u8 => todo!() }
+   |                                ++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_u8` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:46:12
@@ -176,9 +163,8 @@ LL |         m!(0, ..VAL_1 | VAL_2..);
    = note: the matched value is of type `u8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_u8 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_u8 => todo!() }
+   |                                ++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `u16::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:54:12
@@ -189,9 +175,8 @@ LL |         m!(0, ..u16::MAX);
    = note: the matched value is of type `u16`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u16::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u16::MAX => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `65534_u16..=u16::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:55:12
@@ -202,9 +187,8 @@ LL |         m!(0, ..ALMOST_MAX);
    = note: the matched value is of type `u16`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         65534_u16..=u16::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 65534_u16..=u16::MAX => todo!() }
+   |                                +++++++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `0_u16` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:56:12
@@ -215,9 +199,8 @@ LL |         m!(0, ALMOST_MIN..);
    = note: the matched value is of type `u16`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         0_u16 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 0_u16 => todo!() }
+   |                                ++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `u16::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:57:12
@@ -228,9 +211,8 @@ LL |         m!(0, ..=ALMOST_MAX);
    = note: the matched value is of type `u16`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u16::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u16::MAX => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_u16` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:58:12
@@ -241,9 +223,8 @@ LL |         m!(0, ..=VAL | VAL_2..);
    = note: the matched value is of type `u16`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_u16 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_u16 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_u16` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:59:12
@@ -254,9 +235,8 @@ LL |         m!(0, ..VAL_1 | VAL_2..);
    = note: the matched value is of type `u16`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_u16 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_u16 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `u32::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:67:12
@@ -267,9 +247,8 @@ LL |         m!(0, ..u32::MAX);
    = note: the matched value is of type `u32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u32::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u32::MAX => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `4294967294_u32..=u32::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:68:12
@@ -280,9 +259,8 @@ LL |         m!(0, ..ALMOST_MAX);
    = note: the matched value is of type `u32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         4294967294_u32..=u32::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 4294967294_u32..=u32::MAX => todo!() }
+   |                                ++++++++++++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `0_u32` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:69:12
@@ -293,9 +271,8 @@ LL |         m!(0, ALMOST_MIN..);
    = note: the matched value is of type `u32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         0_u32 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 0_u32 => todo!() }
+   |                                ++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `u32::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:70:12
@@ -306,9 +283,8 @@ LL |         m!(0, ..=ALMOST_MAX);
    = note: the matched value is of type `u32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u32::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u32::MAX => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_u32` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:71:12
@@ -319,9 +295,8 @@ LL |         m!(0, ..=VAL | VAL_2..);
    = note: the matched value is of type `u32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_u32 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_u32 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_u32` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:72:12
@@ -332,9 +307,8 @@ LL |         m!(0, ..VAL_1 | VAL_2..);
    = note: the matched value is of type `u32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_u32 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_u32 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `u64::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:80:12
@@ -345,9 +319,8 @@ LL |         m!(0, ..u64::MAX);
    = note: the matched value is of type `u64`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u64::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u64::MAX => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `18446744073709551614_u64..=u64::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:81:12
@@ -358,9 +331,8 @@ LL |         m!(0, ..ALMOST_MAX);
    = note: the matched value is of type `u64`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         18446744073709551614_u64..=u64::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 18446744073709551614_u64..=u64::MAX => todo!() }
+   |                                ++++++++++++++++++++++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `0_u64` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:82:12
@@ -371,9 +343,8 @@ LL |         m!(0, ALMOST_MIN..);
    = note: the matched value is of type `u64`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         0_u64 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 0_u64 => todo!() }
+   |                                ++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `u64::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:83:12
@@ -384,9 +355,8 @@ LL |         m!(0, ..=ALMOST_MAX);
    = note: the matched value is of type `u64`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u64::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u64::MAX => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_u64` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:84:12
@@ -397,9 +367,8 @@ LL |         m!(0, ..=VAL | VAL_2..);
    = note: the matched value is of type `u64`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_u64 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_u64 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_u64` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:85:12
@@ -410,9 +379,8 @@ LL |         m!(0, ..VAL_1 | VAL_2..);
    = note: the matched value is of type `u64`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_u64 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_u64 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:93:12
@@ -423,9 +391,8 @@ LL |         m!(0, ..u128::MAX);
    = note: the matched value is of type `u128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u128::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u128::MAX => todo!() }
+   |                                ++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211454_u128..=u128::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:94:12
@@ -436,9 +403,8 @@ LL |         m!(0, ..ALMOST_MAX);
    = note: the matched value is of type `u128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         340282366920938463463374607431768211454_u128..=u128::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 340282366920938463463374607431768211454_u128..=u128::MAX => todo!() }
+   |                                +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `0_u128` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:95:12
@@ -449,9 +415,8 @@ LL |         m!(0, ALMOST_MIN..);
    = note: the matched value is of type `u128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         0_u128 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 0_u128 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:96:12
@@ -462,9 +427,8 @@ LL |         m!(0, ..=ALMOST_MAX);
    = note: the matched value is of type `u128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u128::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u128::MAX => todo!() }
+   |                                ++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_u128` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:97:12
@@ -475,9 +439,8 @@ LL |         m!(0, ..=VAL | VAL_2..);
    = note: the matched value is of type `u128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_u128 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_u128 => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_u128` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:98:12
@@ -488,9 +451,8 @@ LL |         m!(0, ..VAL_1 | VAL_2..);
    = note: the matched value is of type `u128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_u128 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_u128 => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:109:12
@@ -501,9 +463,8 @@ LL |         m!(0, ..i8::MAX);
    = note: the matched value is of type `i8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i8::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i8::MAX => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `126_i8..=i8::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:110:12
@@ -514,9 +475,8 @@ LL |         m!(0, ..ALMOST_MAX);
    = note: the matched value is of type `i8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         126_i8..=i8::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 126_i8..=i8::MAX => todo!() }
+   |                                +++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i8::MIN` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:111:12
@@ -527,9 +487,8 @@ LL |         m!(0, ALMOST_MIN..);
    = note: the matched value is of type `i8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i8::MIN => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i8::MIN => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:112:12
@@ -540,9 +499,8 @@ LL |         m!(0, ..=ALMOST_MAX);
    = note: the matched value is of type `i8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i8::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i8::MAX => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_i8` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:113:12
@@ -553,9 +511,8 @@ LL |         m!(0, ..=VAL | VAL_2..);
    = note: the matched value is of type `i8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_i8 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_i8 => todo!() }
+   |                                ++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_i8` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:114:12
@@ -566,9 +523,8 @@ LL |         m!(0, ..VAL_1 | VAL_2..);
    = note: the matched value is of type `i8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_i8 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_i8 => todo!() }
+   |                                ++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i16::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:122:12
@@ -579,9 +535,8 @@ LL |         m!(0, ..i16::MAX);
    = note: the matched value is of type `i16`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i16::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i16::MAX => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `32766_i16..=i16::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:123:12
@@ -592,9 +547,8 @@ LL |         m!(0, ..ALMOST_MAX);
    = note: the matched value is of type `i16`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         32766_i16..=i16::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 32766_i16..=i16::MAX => todo!() }
+   |                                +++++++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i16::MIN` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:124:12
@@ -605,9 +559,8 @@ LL |         m!(0, ALMOST_MIN..);
    = note: the matched value is of type `i16`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i16::MIN => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i16::MIN => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i16::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:125:12
@@ -618,9 +571,8 @@ LL |         m!(0, ..=ALMOST_MAX);
    = note: the matched value is of type `i16`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i16::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i16::MAX => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_i16` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:126:12
@@ -631,9 +583,8 @@ LL |         m!(0, ..=VAL | VAL_2..);
    = note: the matched value is of type `i16`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_i16 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_i16 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_i16` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:127:12
@@ -644,9 +595,8 @@ LL |         m!(0, ..VAL_1 | VAL_2..);
    = note: the matched value is of type `i16`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_i16 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_i16 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i32::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:135:12
@@ -657,9 +607,8 @@ LL |         m!(0, ..i32::MAX);
    = note: the matched value is of type `i32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i32::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i32::MAX => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `2147483646_i32..=i32::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:136:12
@@ -670,9 +619,8 @@ LL |         m!(0, ..ALMOST_MAX);
    = note: the matched value is of type `i32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         2147483646_i32..=i32::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 2147483646_i32..=i32::MAX => todo!() }
+   |                                ++++++++++++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i32::MIN` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:137:12
@@ -683,9 +631,8 @@ LL |         m!(0, ALMOST_MIN..);
    = note: the matched value is of type `i32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i32::MIN => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i32::MIN => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i32::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:138:12
@@ -696,9 +643,8 @@ LL |         m!(0, ..=ALMOST_MAX);
    = note: the matched value is of type `i32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i32::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i32::MAX => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_i32` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:139:12
@@ -709,9 +655,8 @@ LL |         m!(0, ..=VAL | VAL_2..);
    = note: the matched value is of type `i32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_i32 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_i32 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_i32` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:140:12
@@ -722,9 +667,8 @@ LL |         m!(0, ..VAL_1 | VAL_2..);
    = note: the matched value is of type `i32`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_i32 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_i32 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i64::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:148:12
@@ -735,9 +679,8 @@ LL |         m!(0, ..i64::MAX);
    = note: the matched value is of type `i64`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i64::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i64::MAX => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `9223372036854775806_i64..=i64::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:149:12
@@ -748,9 +691,8 @@ LL |         m!(0, ..ALMOST_MAX);
    = note: the matched value is of type `i64`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         9223372036854775806_i64..=i64::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 9223372036854775806_i64..=i64::MAX => todo!() }
+   |                                +++++++++++++++++++++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i64::MIN` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:150:12
@@ -761,9 +703,8 @@ LL |         m!(0, ALMOST_MIN..);
    = note: the matched value is of type `i64`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i64::MIN => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i64::MIN => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i64::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:151:12
@@ -774,9 +715,8 @@ LL |         m!(0, ..=ALMOST_MAX);
    = note: the matched value is of type `i64`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i64::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i64::MAX => todo!() }
+   |                                +++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_i64` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:152:12
@@ -787,9 +727,8 @@ LL |         m!(0, ..=VAL | VAL_2..);
    = note: the matched value is of type `i64`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_i64 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_i64 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_i64` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:153:12
@@ -800,9 +739,8 @@ LL |         m!(0, ..VAL_1 | VAL_2..);
    = note: the matched value is of type `i64`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_i64 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_i64 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i128::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:161:12
@@ -813,9 +751,8 @@ LL |         m!(0, ..i128::MAX);
    = note: the matched value is of type `i128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i128::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i128::MAX => todo!() }
+   |                                ++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `170141183460469231731687303715884105726_i128..=i128::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:162:12
@@ -826,9 +763,8 @@ LL |         m!(0, ..ALMOST_MAX);
    = note: the matched value is of type `i128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         170141183460469231731687303715884105726_i128..=i128::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 170141183460469231731687303715884105726_i128..=i128::MAX => todo!() }
+   |                                +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i128::MIN` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:163:12
@@ -839,9 +775,8 @@ LL |         m!(0, ALMOST_MIN..);
    = note: the matched value is of type `i128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i128::MIN => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i128::MIN => todo!() }
+   |                                ++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i128::MAX` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:164:12
@@ -852,9 +787,8 @@ LL |         m!(0, ..=ALMOST_MAX);
    = note: the matched value is of type `i128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i128::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i128::MAX => todo!() }
+   |                                ++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_i128` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:165:12
@@ -865,9 +799,8 @@ LL |         m!(0, ..=VAL | VAL_2..);
    = note: the matched value is of type `i128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_i128 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_i128 => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `43_i128` not covered
   --> $DIR/half-open-range-pats-exhaustive-fail.rs:166:12
@@ -878,9 +811,8 @@ LL |         m!(0, ..VAL_1 | VAL_2..);
    = note: the matched value is of type `i128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         43_i128 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 43_i128 => todo!() }
+   |                                ++++++++++++++++++++
 
 error: aborting due to 68 previous errors
 
diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr
index a5770431eaf..b4312091edb 100644
--- a/src/test/ui/hrtb/hrtb-just-for-static.stderr
+++ b/src/test/ui/hrtb/hrtb-just-for-static.stderr
@@ -2,7 +2,7 @@ error: implementation of `Foo` is not general enough
   --> $DIR/hrtb-just-for-static.rs:24:5
    |
 LL |     want_hrtb::<StaticInt>()
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |     ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
    = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
    = note: ...but it actually implements `Foo<&'static isize>`
diff --git a/src/test/ui/hrtb/issue-58451.stderr b/src/test/ui/hrtb/issue-58451.stderr
index d2b3b1c2aa0..22ba63c3e86 100644
--- a/src/test/ui/hrtb/issue-58451.stderr
+++ b/src/test/ui/hrtb/issue-58451.stderr
@@ -11,8 +11,8 @@ LL | fn f<I>(i: I)
    |    ^    ----
 help: provide the argument
    |
-LL |     f(&[f({_})]);
-   |         ~~~~~~
+LL |     f(&[f(/* value */)]);
+   |         ~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-24883.rs b/src/test/ui/imports/issue-24883.rs
index 819a20ddbda..819a20ddbda 100644
--- a/src/test/ui/issues/issue-24883.rs
+++ b/src/test/ui/imports/issue-24883.rs
diff --git a/src/test/ui/issues/issue-68103.rs b/src/test/ui/imports/issue-68103.rs
index e775678fc60..e775678fc60 100644
--- a/src/test/ui/issues/issue-68103.rs
+++ b/src/test/ui/imports/issue-68103.rs
diff --git a/src/test/ui/issues/issue-72690.rs b/src/test/ui/inference/issue-72690.rs
index 8c0a0f51a21..8c0a0f51a21 100644
--- a/src/test/ui/issues/issue-72690.rs
+++ b/src/test/ui/inference/issue-72690.rs
diff --git a/src/test/ui/issues/issue-72690.stderr b/src/test/ui/inference/issue-72690.stderr
index 9edf14ef291..9edf14ef291 100644
--- a/src/test/ui/issues/issue-72690.stderr
+++ b/src/test/ui/inference/issue-72690.stderr
diff --git a/src/test/ui/issue-94866.rs b/src/test/ui/issue-94866.rs
new file mode 100644
index 00000000000..c4203487936
--- /dev/null
+++ b/src/test/ui/issue-94866.rs
@@ -0,0 +1,14 @@
+macro_rules! m {
+    () => {
+        {}
+    };
+}
+
+enum Enum { A, B }
+
+fn main() {
+    match Enum::A {
+    //~^ ERROR non-exhaustive patterns
+    Enum::A => m!()
+    }
+}
diff --git a/src/test/ui/issue-94866.stderr b/src/test/ui/issue-94866.stderr
new file mode 100644
index 00000000000..5477d83f449
--- /dev/null
+++ b/src/test/ui/issue-94866.stderr
@@ -0,0 +1,21 @@
+error[E0004]: non-exhaustive patterns: `B` not covered
+  --> $DIR/issue-94866.rs:10:11
+   |
+LL |     match Enum::A {
+   |           ^^^^^^^ pattern `B` not covered
+   |
+note: `Enum` defined here
+  --> $DIR/issue-94866.rs:7:16
+   |
+LL | enum Enum { A, B }
+   |      ----      ^ not covered
+   = note: the matched value is of type `Enum`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~     Enum::A => m!(),
+LL +     B => todo!()
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/issues/issue-18819.stderr b/src/test/ui/issues/issue-18819.stderr
index db228fded6e..6499dd0d81b 100644
--- a/src/test/ui/issues/issue-18819.stderr
+++ b/src/test/ui/issues/issue-18819.stderr
@@ -20,8 +20,8 @@ LL |     print_x(&X);
    |             ~~
 help: provide the argument
    |
-LL |     print_x({&dyn Foo<Item = bool>}, {&str});
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     print_x(/* &dyn Foo<Item = bool> */, /* &str */);
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-22706.stderr b/src/test/ui/issues/issue-22706.stderr
index 66911f081d7..5366a36b1a6 100644
--- a/src/test/ui/issues/issue-22706.stderr
+++ b/src/test/ui/issues/issue-22706.stderr
@@ -4,7 +4,7 @@ error[E0109]: type arguments are not allowed on module `marker`
 LL | fn is_copy<T: ::std::marker<i32>::Copy>() {}
    |                      ------ ^^^ type argument not allowed
    |                      |
-   |                      not allowed on this
+   |                      not allowed on module `marker`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-3044.stderr b/src/test/ui/issues/issue-3044.stderr
index 5bb07cfda21..6dbe6b59391 100644
--- a/src/test/ui/issues/issue-3044.stderr
+++ b/src/test/ui/issues/issue-3044.stderr
@@ -25,7 +25,7 @@ LL |     fn fold<B, F>(mut self, init: B, mut f: F) -> B
 help: provide the argument
    |
 LL ~     needlesArr.iter().fold(|x, y| {
-LL ~     }, {_});
+LL ~     }, /* value */);
    |
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-57924.stderr b/src/test/ui/issues/issue-57924.stderr
index 211b0dde48c..0323a4dfb8a 100644
--- a/src/test/ui/issues/issue-57924.stderr
+++ b/src/test/ui/issues/issue-57924.stderr
@@ -4,7 +4,7 @@ error[E0109]: type arguments are not allowed on self constructor
 LL |         Self::<E>(e)
    |         ----   ^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on self constructor
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-60989.stderr b/src/test/ui/issues/issue-60989.stderr
index 9076f4f9385..e0236567b2f 100644
--- a/src/test/ui/issues/issue-60989.stderr
+++ b/src/test/ui/issues/issue-60989.stderr
@@ -4,7 +4,7 @@ error[E0109]: type arguments are not allowed on local variable
 LL |     c1::<()>;
    |     --   ^^ type argument not allowed
    |     |
-   |     not allowed on this
+   |     not allowed on local variable
 
 error[E0109]: type arguments are not allowed on local variable
   --> $DIR/issue-60989.rs:16:10
@@ -12,7 +12,7 @@ error[E0109]: type arguments are not allowed on local variable
 LL |     c1::<dyn Into<B>>;
    |     --   ^^^^^^^^^^^ type argument not allowed
    |     |
-   |     not allowed on this
+   |     not allowed on local variable
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-98299.rs b/src/test/ui/issues/issue-98299.rs
new file mode 100644
index 00000000000..63c058f91fc
--- /dev/null
+++ b/src/test/ui/issues/issue-98299.rs
@@ -0,0 +1,18 @@
+use std::convert::TryFrom;
+
+pub fn test_usage(p: ()) {
+    SmallCString::try_from(p).map(|cstr| cstr);
+    //~^ ERROR: type annotations needed
+}
+
+pub struct SmallCString<const N: usize> {}
+
+impl<const N: usize> TryFrom<()> for SmallCString<N> {
+    type Error = ();
+
+    fn try_from(path: ()) -> Result<Self, Self::Error> {
+        unimplemented!();
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-98299.stderr b/src/test/ui/issues/issue-98299.stderr
new file mode 100644
index 00000000000..a61bffa91e7
--- /dev/null
+++ b/src/test/ui/issues/issue-98299.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/issue-98299.rs:4:5
+   |
+LL |     SmallCString::try_from(p).map(|cstr| cstr);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for enum `Result<SmallCString<{_: usize}>, ()>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/lifetimes/issue-97194.rs b/src/test/ui/lifetimes/issue-97194.rs
index accb4a99830..5f3560dbe94 100644
--- a/src/test/ui/lifetimes/issue-97194.rs
+++ b/src/test/ui/lifetimes/issue-97194.rs
@@ -2,7 +2,7 @@ extern "C" {
     fn bget(&self, index: [usize; Self::DIM]) -> bool {
         //~^ ERROR incorrect function inside `extern` block
         //~| ERROR `self` parameter is only allowed in associated functions
-        //~| ERROR use of undeclared type `Self`
+        //~| ERROR failed to resolve: `Self`
         type T<'a> = &'a str;
     }
 }
diff --git a/src/test/ui/lifetimes/issue-97194.stderr b/src/test/ui/lifetimes/issue-97194.stderr
index 15ad5aadf9f..93bde285a99 100644
--- a/src/test/ui/lifetimes/issue-97194.stderr
+++ b/src/test/ui/lifetimes/issue-97194.stderr
@@ -25,11 +25,11 @@ LL |     fn bget(&self, index: [usize; Self::DIM]) -> bool {
    |
    = note: associated functions are those in `impl` or `trait` definitions
 
-error[E0433]: failed to resolve: use of undeclared type `Self`
+error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
   --> $DIR/issue-97194.rs:2:35
    |
 LL |     fn bget(&self, index: [usize; Self::DIM]) -> bool {
-   |                                   ^^^^ use of undeclared type `Self`
+   |                                   ^^^^ `Self` is only available in impls, traits, and type definitions
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-35075.rs b/src/test/ui/lint/issue-35075.rs
index 0e54131c245..0e54131c245 100644
--- a/src/test/ui/issues/issue-35075.rs
+++ b/src/test/ui/lint/issue-35075.rs
diff --git a/src/test/ui/issues/issue-35075.stderr b/src/test/ui/lint/issue-35075.stderr
index 08bdaa72858..08bdaa72858 100644
--- a/src/test/ui/issues/issue-35075.stderr
+++ b/src/test/ui/lint/issue-35075.stderr
diff --git a/src/test/ui/lint/unused/unused-attr-doc-hidden.fixed b/src/test/ui/lint/unused/unused-attr-doc-hidden.fixed
deleted file mode 100644
index 362ad55707a..00000000000
--- a/src/test/ui/lint/unused/unused-attr-doc-hidden.fixed
+++ /dev/null
@@ -1,55 +0,0 @@
-#![feature(inherent_associated_types)]
-#![allow(dead_code, incomplete_features)]
-#![crate_type = "lib"]
-#![deny(unused_attributes)]
-// run-rustfix
-
-pub trait Trait {
-    type It;
-    const IT: ();
-    fn it0();
-    fn it1();
-    fn it2();
-}
-
-pub struct Implementor;
-
-impl Implementor {
-    #[doc(hidden)] // no error
-    type Inh = ();
-
-    #[doc(hidden)] // no error
-    const INH: () = ();
-
-    #[doc(hidden)] // no error
-    fn inh() {}
-}
-
-impl Trait for Implementor {
-    
-    type It = ();
-    //~^^ ERROR `#[doc(hidden)]` is ignored
-    //~|  WARNING this was previously accepted
-
-    
-    const IT: () = ();
-    //~^^ ERROR `#[doc(hidden)]` is ignored
-    //~|  WARNING this was previously accepted
-
-    #[doc(alias = "aka")]
-    fn it0() {}
-    //~^^ ERROR `#[doc(hidden)]` is ignored
-    //~|  WARNING this was previously accepted
-
-    #[doc(alias = "this", )]
-    fn it1() {}
-    //~^^ ERROR `#[doc(hidden)]` is ignored
-    //~|  WARNING this was previously accepted
-
-    #[doc()]
-    fn it2() {}
-    //~^^ ERROR `#[doc(hidden)]` is ignored
-    //~|  WARNING this was previously accepted
-    //~|  ERROR `#[doc(hidden)]` is ignored
-    //~|  WARNING this was previously accepted
-}
diff --git a/src/test/ui/lint/unused/unused-attr-doc-hidden.rs b/src/test/ui/lint/unused/unused-attr-doc-hidden.rs
deleted file mode 100644
index d493ed6dae2..00000000000
--- a/src/test/ui/lint/unused/unused-attr-doc-hidden.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-#![feature(inherent_associated_types)]
-#![allow(dead_code, incomplete_features)]
-#![crate_type = "lib"]
-#![deny(unused_attributes)]
-// run-rustfix
-
-pub trait Trait {
-    type It;
-    const IT: ();
-    fn it0();
-    fn it1();
-    fn it2();
-}
-
-pub struct Implementor;
-
-impl Implementor {
-    #[doc(hidden)] // no error
-    type Inh = ();
-
-    #[doc(hidden)] // no error
-    const INH: () = ();
-
-    #[doc(hidden)] // no error
-    fn inh() {}
-}
-
-impl Trait for Implementor {
-    #[doc(hidden)]
-    type It = ();
-    //~^^ ERROR `#[doc(hidden)]` is ignored
-    //~|  WARNING this was previously accepted
-
-    #[doc(hidden)]
-    const IT: () = ();
-    //~^^ ERROR `#[doc(hidden)]` is ignored
-    //~|  WARNING this was previously accepted
-
-    #[doc(hidden, alias = "aka")]
-    fn it0() {}
-    //~^^ ERROR `#[doc(hidden)]` is ignored
-    //~|  WARNING this was previously accepted
-
-    #[doc(alias = "this", hidden,)]
-    fn it1() {}
-    //~^^ ERROR `#[doc(hidden)]` is ignored
-    //~|  WARNING this was previously accepted
-
-    #[doc(hidden, hidden)]
-    fn it2() {}
-    //~^^ ERROR `#[doc(hidden)]` is ignored
-    //~|  WARNING this was previously accepted
-    //~|  ERROR `#[doc(hidden)]` is ignored
-    //~|  WARNING this was previously accepted
-}
diff --git a/src/test/ui/lint/unused/unused-attr-doc-hidden.stderr b/src/test/ui/lint/unused/unused-attr-doc-hidden.stderr
deleted file mode 100644
index f167bd460db..00000000000
--- a/src/test/ui/lint/unused/unused-attr-doc-hidden.stderr
+++ /dev/null
@@ -1,67 +0,0 @@
-error: `#[doc(hidden)]` is ignored on trait impl items
-  --> $DIR/unused-attr-doc-hidden.rs:29:5
-   |
-LL |     #[doc(hidden)]
-   |     ^^^^^^^^^^^^^^ help: remove this attribute
-   |
-note: the lint level is defined here
-  --> $DIR/unused-attr-doc-hidden.rs:4:9
-   |
-LL | #![deny(unused_attributes)]
-   |         ^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
-
-error: `#[doc(hidden)]` is ignored on trait impl items
-  --> $DIR/unused-attr-doc-hidden.rs:34:5
-   |
-LL |     #[doc(hidden)]
-   |     ^^^^^^^^^^^^^^ help: remove this attribute
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
-
-error: `#[doc(hidden)]` is ignored on trait impl items
-  --> $DIR/unused-attr-doc-hidden.rs:39:11
-   |
-LL |     #[doc(hidden, alias = "aka")]
-   |           ^^^^^^--
-   |           |
-   |           help: remove this attribute
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
-
-error: `#[doc(hidden)]` is ignored on trait impl items
-  --> $DIR/unused-attr-doc-hidden.rs:44:27
-   |
-LL |     #[doc(alias = "this", hidden,)]
-   |                           ^^^^^^-
-   |                           |
-   |                           help: remove this attribute
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
-
-error: `#[doc(hidden)]` is ignored on trait impl items
-  --> $DIR/unused-attr-doc-hidden.rs:49:11
-   |
-LL |     #[doc(hidden, hidden)]
-   |           ^^^^^^--
-   |           |
-   |           help: remove this attribute
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
-
-error: `#[doc(hidden)]` is ignored on trait impl items
-  --> $DIR/unused-attr-doc-hidden.rs:49:19
-   |
-LL |     #[doc(hidden, hidden)]
-   |                   ^^^^^^ help: remove this attribute
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
-
-error: aborting due to 6 previous errors
-
diff --git a/src/test/ui/lub-glb/empty-binder-future-compat.rs b/src/test/ui/lub-glb/empty-binder-future-compat.rs
new file mode 100644
index 00000000000..8700a88a36e
--- /dev/null
+++ b/src/test/ui/lub-glb/empty-binder-future-compat.rs
@@ -0,0 +1,22 @@
+// check-pass
+fn lt_in_fn_fn<'a: 'a>() -> fn(fn(&'a ())) {
+    |_| ()
+}
+
+
+fn foo<'a, 'b, 'lower>(v: bool)
+where
+    'a: 'lower,
+    'b: 'lower,
+{
+        // if we infer `x` to be higher ranked in the future,
+        // this would cause a type error.
+        let x = match v {
+            true => lt_in_fn_fn::<'a>(),
+            false => lt_in_fn_fn::<'b>(),
+        };
+
+        let _: fn(fn(&'lower())) = x;
+}
+
+fn main() {}
diff --git a/src/test/ui/lub-glb/empty-binders-err.rs b/src/test/ui/lub-glb/empty-binders-err.rs
new file mode 100644
index 00000000000..557480173ee
--- /dev/null
+++ b/src/test/ui/lub-glb/empty-binders-err.rs
@@ -0,0 +1,55 @@
+fn lt<'a: 'a>() -> &'a () {
+    &()
+}
+
+fn lt_in_fn<'a: 'a>() -> fn(&'a ()) {
+    |_| ()
+}
+
+struct Contra<'a>(fn(&'a ()));
+fn lt_in_contra<'a: 'a>() -> Contra<'a> {
+    Contra(|_| ())
+}
+
+fn covariance<'a, 'b, 'upper>(v: bool)
+where
+    'upper: 'a,
+    'upper: 'b,
+
+{
+    let _: &'upper () = match v {
+        //~^ ERROR lifetime may not live long enough
+        //~| ERROR lifetime may not live long enough
+        true => lt::<'a>(),
+        false => lt::<'b>(),
+    };
+}
+
+fn contra_fn<'a, 'b, 'lower>(v: bool)
+where
+    'a: 'lower,
+    'b: 'lower,
+
+{
+
+    let _: fn(&'lower ()) = match v {
+        //~^ ERROR lifetime may not live long enough
+        true => lt_in_fn::<'a>(),
+        false => lt_in_fn::<'b>(),
+    };
+}
+
+fn contra_struct<'a, 'b, 'lower>(v: bool)
+where
+    'a: 'lower,
+    'b: 'lower,
+
+{
+    let _: Contra<'lower> = match v {
+        //~^ ERROR lifetime may not live long enough
+        true => lt_in_contra::<'a>(),
+        false => lt_in_contra::<'b>(),
+    };
+}
+
+fn main() {}
diff --git a/src/test/ui/lub-glb/empty-binders-err.stderr b/src/test/ui/lub-glb/empty-binders-err.stderr
new file mode 100644
index 00000000000..f86f22d5e40
--- /dev/null
+++ b/src/test/ui/lub-glb/empty-binders-err.stderr
@@ -0,0 +1,59 @@
+error: lifetime may not live long enough
+  --> $DIR/empty-binders-err.rs:20:12
+   |
+LL | fn covariance<'a, 'b, 'upper>(v: bool)
+   |               --      ------ lifetime `'upper` defined here
+   |               |
+   |               lifetime `'a` defined here
+...
+LL |     let _: &'upper () = match v {
+   |            ^^^^^^^^^^ type annotation requires that `'a` must outlive `'upper`
+   |
+   = help: consider adding the following bound: `'a: 'upper`
+
+error: lifetime may not live long enough
+  --> $DIR/empty-binders-err.rs:20:12
+   |
+LL | fn covariance<'a, 'b, 'upper>(v: bool)
+   |                   --  ------ lifetime `'upper` defined here
+   |                   |
+   |                   lifetime `'b` defined here
+...
+LL |     let _: &'upper () = match v {
+   |            ^^^^^^^^^^ type annotation requires that `'b` must outlive `'upper`
+   |
+   = help: consider adding the following bound: `'b: 'upper`
+
+help: the following changes may resolve your lifetime errors
+   |
+   = help: add bound `'a: 'upper`
+   = help: add bound `'b: 'upper`
+
+error: lifetime may not live long enough
+  --> $DIR/empty-binders-err.rs:35:12
+   |
+LL | fn contra_fn<'a, 'b, 'lower>(v: bool)
+   |              --      ------ lifetime `'lower` defined here
+   |              |
+   |              lifetime `'a` defined here
+...
+LL |     let _: fn(&'lower ()) = match v {
+   |            ^^^^^^^^^^^^^^ type annotation requires that `'lower` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'lower: 'a`
+
+error: lifetime may not live long enough
+  --> $DIR/empty-binders-err.rs:48:12
+   |
+LL | fn contra_struct<'a, 'b, 'lower>(v: bool)
+   |                  --      ------ lifetime `'lower` defined here
+   |                  |
+   |                  lifetime `'a` defined here
+...
+LL |     let _: Contra<'lower> = match v {
+   |            ^^^^^^^^^^^^^^ type annotation requires that `'lower` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'lower: 'a`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/lub-glb/empty-binders.rs b/src/test/ui/lub-glb/empty-binders.rs
new file mode 100644
index 00000000000..f9d07e79fda
--- /dev/null
+++ b/src/test/ui/lub-glb/empty-binders.rs
@@ -0,0 +1,45 @@
+// check-pass
+//
+// Check that computing the lub works even for empty binders.
+fn lt<'a: 'a>() -> &'a () {
+    &()
+}
+
+fn lt_in_fn<'a: 'a>() -> fn(&'a ()) {
+    |_| ()
+}
+
+struct Contra<'a>(fn(&'a ()));
+fn lt_in_contra<'a: 'a>() -> Contra<'a> {
+    Contra(|_| ())
+}
+
+fn ok<'a, 'b, 'upper, 'lower>(v: bool)
+where
+    'upper: 'a,
+    'upper: 'b,
+    'a: 'lower,
+    'b: 'lower,
+
+{
+    let _: &'lower () = match v {
+        true => lt::<'a>(),
+        false => lt::<'b>(),
+    };
+
+    // This errored in the past because LUB and GLB always
+    // bailed out when encountering binders, even if they were
+    // empty.
+    let _: fn(&'upper ()) = match v {
+        true => lt_in_fn::<'a>(),
+        false => lt_in_fn::<'b>(),
+    };
+
+    // This was already accepted, as relate didn't encounter any binders.
+    let _: Contra<'upper> = match v {
+        true => lt_in_contra::<'a>(),
+        false => lt_in_contra::<'b>(),
+    };
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-8851.rs b/src/test/ui/macros/issue-8851.rs
index faacfe5f895..faacfe5f895 100644
--- a/src/test/ui/issues/issue-8851.rs
+++ b/src/test/ui/macros/issue-8851.rs
diff --git a/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs b/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs
index c0e9f29fdbc..f538ec64390 100644
--- a/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs
+++ b/src/test/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs
@@ -55,14 +55,56 @@ struct Foo {
   bar: i32
 }
 
+impl Foo {
+  fn add(&self, a: i32, b: i32) -> i32 { a + b }
+}
+
+fn add(a: i32, b: i32) -> i32 { a + b }
+
 fn main() {
   // ***** Allowed *****
 
   tests!(
     let mut elem = 1i32;
 
+    // addr of
+    [ &elem == &3 ] => "Assertion failed: &elem == &3\nWith captures:\n  elem = 1\n"
+
+    // array
+    [ [elem][0] == 3 ] => "Assertion failed: [elem][0] == 3\nWith captures:\n  elem = 1\n"
+
     // binary
     [ elem + 1 == 3 ] => "Assertion failed: elem + 1 == 3\nWith captures:\n  elem = 1\n"
+
+    // call
+    [ add(elem, elem) == 3 ] => "Assertion failed: add(elem, elem) == 3\nWith captures:\n  elem = 1\n"
+
+    // cast
+    [ elem as i32 == 3 ] => "Assertion failed: elem as i32 == 3\nWith captures:\n  elem = 1\n"
+
+    // index
+    [ [1i32, 1][elem as usize] == 3 ] => "Assertion failed: [1i32, 1][elem as usize] == 3\nWith captures:\n  elem = 1\n"
+
+    // method call
+    [ FOO.add(elem, elem) == 3 ] => "Assertion failed: FOO.add(elem, elem) == 3\nWith captures:\n  elem = 1\n"
+
+    // paren
+    [ (elem) == 3 ] => "Assertion failed: (elem) == 3\nWith captures:\n  elem = 1\n"
+
+    // range
+    [ (0..elem) == (0..3) ] => "Assertion failed: (0..elem) == (0..3)\nWith captures:\n  elem = 1\n"
+
+    // repeat
+    [ [elem; 1] == [3; 1] ] => "Assertion failed: [elem; 1] == [3; 1]\nWith captures:\n  elem = 1\n"
+
+    // struct
+    [ Foo { bar: elem } == Foo { bar: 3 } ] => "Assertion failed: Foo { bar: elem } == Foo { bar: 3 }\nWith captures:\n  elem = 1\n"
+
+    // tuple
+    [ (elem, 1) == (3, 3) ] => "Assertion failed: (elem, 1) == (3, 3)\nWith captures:\n  elem = 1\n"
+
+    // unary
+    [ -elem == -3 ] => "Assertion failed: -elem == -3\nWith captures:\n  elem = 1\n"
   );
 
   // ***** Disallowed *****
diff --git a/src/test/ui/issues/issue-46920-byte-array-patterns.rs b/src/test/ui/match/issue-46920-byte-array-patterns.rs
index 2a8b4bb4922..2a8b4bb4922 100644
--- a/src/test/ui/issues/issue-46920-byte-array-patterns.rs
+++ b/src/test/ui/match/issue-46920-byte-array-patterns.rs
diff --git a/src/test/ui/methods/method-call-err-msg.stderr b/src/test/ui/methods/method-call-err-msg.stderr
index 53e582f7f13..95edee6ad23 100644
--- a/src/test/ui/methods/method-call-err-msg.stderr
+++ b/src/test/ui/methods/method-call-err-msg.stderr
@@ -27,8 +27,8 @@ LL |     fn one(self, _: isize) -> Foo { self }
    |        ^^^ ----  --------
 help: provide the argument
    |
-LL |      .one({isize})
-   |       ~~~~~~~~~~~~
+LL |      .one(/* isize */)
+   |       ~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 2 arguments but 1 argument was supplied
   --> $DIR/method-call-err-msg.rs:15:7
@@ -43,8 +43,8 @@ LL |     fn two(self, _: isize, _: isize) -> Foo { self }
    |        ^^^ ----  --------  --------
 help: provide the argument
    |
-LL |      .two(0, {isize});
-   |       ~~~~~~~~~~~~~~~
+LL |      .two(0, /* isize */);
+   |       ~~~~~~~~~~~~~~~~~~~
 
 error[E0599]: `Foo` is not an iterator
   --> $DIR/method-call-err-msg.rs:19:7
@@ -89,8 +89,8 @@ LL |     fn three<T>(self, _: T, _: T, _: T) -> Foo { self }
    |        ^^^^^    ----  ----  ----  ----
 help: provide the arguments
    |
-LL |     y.three::<usize>({usize}, {usize}, {usize});
-   |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     y.three::<usize>(/* usize */, /* usize */, /* usize */);
+   |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/mir/ssa-analysis-regression-50041.rs b/src/test/ui/mir/ssa-analysis-regression-50041.rs
index 8c382ff0558..8e9c14a03c3 100644
--- a/src/test/ui/mir/ssa-analysis-regression-50041.rs
+++ b/src/test/ui/mir/ssa-analysis-regression-50041.rs
@@ -1,27 +1,29 @@
 // build-pass
 // compile-flags: -Z mir-opt-level=4
 
-#![crate_type="lib"]
+#![crate_type = "lib"]
 #![feature(lang_items)]
 #![no_std]
 
+struct NonNull<T: ?Sized>(*mut T);
+
+struct Unique<T: ?Sized>(NonNull<T>);
+
 #[lang = "owned_box"]
-pub struct Box<T: ?Sized>(*mut T, ());
+pub struct Box<T: ?Sized>(Unique<T>);
 
 impl<T: ?Sized> Drop for Box<T> {
-    fn drop(&mut self) {
-    }
+    fn drop(&mut self) {}
 }
 
 #[lang = "box_free"]
 #[inline(always)]
-unsafe fn box_free<T: ?Sized>(ptr: *mut T, _: ()) {
-    dealloc(ptr)
+unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
+    dealloc(ptr.0.0)
 }
 
 #[inline(never)]
-fn dealloc<T: ?Sized>(_: *mut T) {
-}
+fn dealloc<T: ?Sized>(_: *mut T) {}
 
 pub struct Foo<T>(T);
 
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
index a5742d6fe8c..4000b2ba312 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
@@ -25,8 +25,8 @@ LL |     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
    |                           ^^^^^^^^
 help: provide the argument
    |
-LL |     let ans = s({isize});
-   |               ~~~~~~~~~~
+LL |     let ans = s(/* isize */);
+   |               ~~~~~~~~~~~~~~
 
 error[E0057]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/overloaded-calls-bad.rs:31:15
@@ -43,8 +43,8 @@ LL |     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
    |                           ^^^^^^^^
 help: remove the extra argument
    |
-LL |     let ans = s({isize});
-   |               ~~~~~~~~~~
+LL |     let ans = s(/* isize */);
+   |               ~~~~~~~~~~~~~~
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/mod-subitem-as-enum-variant.stderr b/src/test/ui/mod-subitem-as-enum-variant.stderr
index 15da1d155a3..cf61e94bd86 100644
--- a/src/test/ui/mod-subitem-as-enum-variant.stderr
+++ b/src/test/ui/mod-subitem-as-enum-variant.stderr
@@ -4,7 +4,7 @@ error[E0109]: type arguments are not allowed on module `Mod`
 LL |     Mod::<i32>::FakeVariant(0);
    |     ---   ^^^ type argument not allowed
    |     |
-   |     not allowed on this
+   |     not allowed on module `Mod`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/issue-27282-move-match-input-into-guard.rs b/src/test/ui/nll/issue-27282-move-match-input-into-guard.rs
index 4109c10e2e4..4109c10e2e4 100644
--- a/src/test/ui/borrowck/issue-27282-move-match-input-into-guard.rs
+++ b/src/test/ui/nll/issue-27282-move-match-input-into-guard.rs
diff --git a/src/test/ui/borrowck/issue-27282-move-match-input-into-guard.stderr b/src/test/ui/nll/issue-27282-move-match-input-into-guard.stderr
index 9be1a927999..9be1a927999 100644
--- a/src/test/ui/borrowck/issue-27282-move-match-input-into-guard.stderr
+++ b/src/test/ui/nll/issue-27282-move-match-input-into-guard.stderr
diff --git a/src/test/ui/issues/issue-27282-move-ref-mut-into-guard.rs b/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.rs
index afa0ba780de..afa0ba780de 100644
--- a/src/test/ui/issues/issue-27282-move-ref-mut-into-guard.rs
+++ b/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.rs
diff --git a/src/test/ui/issues/issue-27282-move-ref-mut-into-guard.stderr b/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.stderr
index a0d32616f83..a0d32616f83 100644
--- a/src/test/ui/issues/issue-27282-move-ref-mut-into-guard.stderr
+++ b/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.stderr
diff --git a/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-1.rs b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-1.rs
index d17d6f07f68..d17d6f07f68 100644
--- a/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-1.rs
+++ b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-1.rs
diff --git a/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-1.stderr b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-1.stderr
index a1f973e0fdf..a1f973e0fdf 100644
--- a/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-1.stderr
+++ b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-1.stderr
diff --git a/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.rs b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-2.rs
index 9c3e7e9978e..9c3e7e9978e 100644
--- a/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.rs
+++ b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-2.rs
diff --git a/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.stderr b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-2.stderr
index dd46308d140..dd46308d140 100644
--- a/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.stderr
+++ b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-2.stderr
diff --git a/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.rs b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-3.rs
index cff9e963e27..cff9e963e27 100644
--- a/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.rs
+++ b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-3.rs
diff --git a/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.stderr b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-3.stderr
index 4a4a25790b9..4a4a25790b9 100644
--- a/src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.stderr
+++ b/src/test/ui/nll/issue-27282-mutate-before-diverging-arm-3.stderr
diff --git a/src/test/ui/borrowck/issue-27282-mutation-in-guard.rs b/src/test/ui/nll/issue-27282-mutation-in-guard.rs
index 395c7d214d0..395c7d214d0 100644
--- a/src/test/ui/borrowck/issue-27282-mutation-in-guard.rs
+++ b/src/test/ui/nll/issue-27282-mutation-in-guard.rs
diff --git a/src/test/ui/borrowck/issue-27282-mutation-in-guard.stderr b/src/test/ui/nll/issue-27282-mutation-in-guard.stderr
index c4ce7e62fda..c4ce7e62fda 100644
--- a/src/test/ui/borrowck/issue-27282-mutation-in-guard.stderr
+++ b/src/test/ui/nll/issue-27282-mutation-in-guard.stderr
diff --git a/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.rs b/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.rs
index 82d8b9e9ed9..82d8b9e9ed9 100644
--- a/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.rs
+++ b/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.rs
diff --git a/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr b/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.stderr
index 48433432de1..48433432de1 100644
--- a/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr
+++ b/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.stderr
diff --git a/src/test/ui/issues/issue-52057.rs b/src/test/ui/nll/issue-52057.rs
index 98f49fe8f55..98f49fe8f55 100644
--- a/src/test/ui/issues/issue-52057.rs
+++ b/src/test/ui/nll/issue-52057.rs
diff --git a/src/test/ui/nll/issue-97997.rs b/src/test/ui/nll/issue-97997.rs
new file mode 100644
index 00000000000..c64e720b12f
--- /dev/null
+++ b/src/test/ui/nll/issue-97997.rs
@@ -0,0 +1,16 @@
+trait Foo {
+    const ASSOC: bool = true;
+}
+impl<T> Foo for fn(T) {}
+
+fn foo(_x: i32) {}
+
+fn impls_foo<T: Foo>(_x: T) {}
+
+fn main() {
+    impls_foo(foo as fn(i32));
+
+    <fn(&u8) as Foo>::ASSOC;
+    //~^ ERROR implementation of `Foo` is not general enough
+    //~| ERROR implementation of `Foo` is not general enough
+}
diff --git a/src/test/ui/nll/issue-97997.stderr b/src/test/ui/nll/issue-97997.stderr
new file mode 100644
index 00000000000..78401bbf654
--- /dev/null
+++ b/src/test/ui/nll/issue-97997.stderr
@@ -0,0 +1,20 @@
+error: implementation of `Foo` is not general enough
+  --> $DIR/issue-97997.rs:13:5
+   |
+LL |     <fn(&u8) as Foo>::ASSOC;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r u8)`
+   = note: ...but `Foo` is actually implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0`
+
+error: implementation of `Foo` is not general enough
+  --> $DIR/issue-97997.rs:13:5
+   |
+LL |     <fn(&u8) as Foo>::ASSOC;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r u8)`
+   = note: ...but `Foo` is actually implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/not-enough-arguments.stderr b/src/test/ui/not-enough-arguments.stderr
index 4f502acc95c..b1df578ea80 100644
--- a/src/test/ui/not-enough-arguments.stderr
+++ b/src/test/ui/not-enough-arguments.stderr
@@ -11,8 +11,8 @@ LL | fn foo(a: isize, b: isize, c: isize, d:isize) {
    |    ^^^ --------  --------  --------  -------
 help: provide the argument
    |
-LL |   foo(1, 2, 3, {isize});
-   |   ~~~~~~~~~~~~~~~~~~~~~
+LL |   foo(1, 2, 3, /* isize */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 6 arguments but 3 arguments were supplied
   --> $DIR/not-enough-arguments.rs:29:3
@@ -39,8 +39,8 @@ LL |     f: i32,
    |     ------
 help: provide the arguments
    |
-LL |   bar(1, 2, 3, {i32}, {i32}, {i32});
-   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |   bar(1, 2, 3, /* i32 */, /* i32 */, /* i32 */);
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr
index fec54e89d63..f30ba05dff9 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr
+++ b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr
@@ -7,9 +7,8 @@ LL |     m!(0u8, 0..255);
    = note: the matched value is of type `u8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u8::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u8::MAX => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
   --> $DIR/exhaustiveness.rs:48:8
@@ -20,9 +19,8 @@ LL |     m!(0u8, 0..=254);
    = note: the matched value is of type `u8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u8::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u8::MAX => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `0_u8` not covered
   --> $DIR/exhaustiveness.rs:49:8
@@ -33,9 +31,8 @@ LL |     m!(0u8, 1..=255);
    = note: the matched value is of type `u8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         0_u8 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 0_u8 => todo!() }
+   |                                +++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `42_u8` not covered
   --> $DIR/exhaustiveness.rs:50:8
@@ -46,9 +43,8 @@ LL |     m!(0u8, 0..42 | 43..=255);
    = note: the matched value is of type `u8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         42_u8 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 42_u8 => todo!() }
+   |                                ++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
   --> $DIR/exhaustiveness.rs:51:8
@@ -59,9 +55,8 @@ LL |     m!(0i8, -128..127);
    = note: the matched value is of type `i8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i8::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i8::MAX => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
   --> $DIR/exhaustiveness.rs:52:8
@@ -72,9 +67,8 @@ LL |     m!(0i8, -128..=126);
    = note: the matched value is of type `i8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i8::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i8::MAX => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i8::MIN` not covered
   --> $DIR/exhaustiveness.rs:53:8
@@ -85,9 +79,8 @@ LL |     m!(0i8, -127..=127);
    = note: the matched value is of type `i8`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         i8::MIN => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, i8::MIN => todo!() }
+   |                                ++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `0_i8` not covered
   --> $DIR/exhaustiveness.rs:54:11
@@ -111,9 +104,8 @@ LL |     m!(0u128, 0..=ALMOST_MAX);
    = note: the matched value is of type `u128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         u128::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, u128::MAX => todo!() }
+   |                                ++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `5_u128..=u128::MAX` not covered
   --> $DIR/exhaustiveness.rs:60:8
@@ -124,9 +116,8 @@ LL |     m!(0u128, 0..=4);
    = note: the matched value is of type `u128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         5_u128..=u128::MAX => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 5_u128..=u128::MAX => todo!() }
+   |                                +++++++++++++++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `0_u128` not covered
   --> $DIR/exhaustiveness.rs:61:8
@@ -137,9 +128,8 @@ LL |     m!(0u128, 1..=u128::MAX);
    = note: the matched value is of type `u128`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         0_u128 => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, 0_u128 => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `(126_u8..=127_u8, false)` not covered
   --> $DIR/exhaustiveness.rs:69:11
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr
index fa4146a7ad8..e3eb98ccdcd 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr
+++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr
@@ -39,9 +39,8 @@ LL |     m!(0usize, 0..=usize::MAX);
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         _ => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, _ => todo!() }
+   |                                ++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:24:8
@@ -54,9 +53,8 @@ LL |     m!(0usize, 0..5 | 5..=usize::MAX);
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         _ => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, _ => todo!() }
+   |                                ++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:26:8
@@ -69,9 +67,8 @@ LL |     m!(0usize, 0..usize::MAX | usize::MAX);
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         _ => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, _ => todo!() }
+   |                                ++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `(_, _)` not covered
   --> $DIR/pointer-sized-int.rs:28:8
@@ -82,9 +79,8 @@ LL |     m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::
    = note: the matched value is of type `(usize, bool)`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         (_, _) => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, (_, _) => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:31:8
@@ -97,9 +93,8 @@ LL |     m!(0isize, isize::MIN..=isize::MAX);
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         _ => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, _ => todo!() }
+   |                                ++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:33:8
@@ -112,9 +107,8 @@ LL |     m!(0isize, isize::MIN..5 | 5..=isize::MAX);
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         _ => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, _ => todo!() }
+   |                                ++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:35:8
@@ -127,9 +121,8 @@ LL |     m!(0isize, isize::MIN..isize::MAX | isize::MAX);
    = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         _ => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, _ => todo!() }
+   |                                ++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `(_, _)` not covered
   --> $DIR/pointer-sized-int.rs:37:8
@@ -140,9 +133,8 @@ LL |     m!((0isize, true), (isize::MIN..5, true)
    = note: the matched value is of type `(isize, bool)`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         match $s { $($t)+ => {}
-LL ~         (_, _) => todo!() }
-   |
+LL |         match $s { $($t)+ => {}, (_, _) => todo!() }
+   |                                +++++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/pointer-sized-int.rs:41:11
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
index e7fa6a7814f..89b4e06efda 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
@@ -12,8 +12,8 @@ LL | enum T { A, B }
    = note: the matched value is of type `T`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL |     match x { T::B => { } A => todo!() }
-   |                           ++++++++++++
+LL |     match x { T::B => { }, A => todo!() }
+   |                          ++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `false` not covered
   --> $DIR/non-exhaustive-match.rs:8:11
diff --git a/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr b/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr
index fc0430d06fa..e2a65ff8524 100644
--- a/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr
+++ b/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr
@@ -12,7 +12,7 @@ LL | struct Foo(isize, isize);
    = note: the matched value is of type `Foo`
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~         Foo(2, b) => println!("{}", b)
+LL ~         Foo(2, b) => println!("{}", b),
 LL +         Foo(_, _) => todo!()
    |
 
diff --git a/src/test/ui/recursion/recursive-static-definition.stderr b/src/test/ui/recursion/recursive-static-definition.stderr
index be4f09f9286..d4d2c8c3d9c 100644
--- a/src/test/ui/recursion/recursive-static-definition.stderr
+++ b/src/test/ui/recursion/recursive-static-definition.stderr
@@ -10,7 +10,14 @@ note: ...which requires const-evaluating + checking `FOO`...
 LL | pub static FOO: u32 = FOO;
    |                       ^^^
    = note: ...which again requires const-evaluating + checking `FOO`, completing the cycle
-   = note: cycle used when running analysis passes on this crate
+note: cycle used when linting top-level module
+  --> $DIR/recursive-static-definition.rs:1:1
+   |
+LL | / pub static FOO: u32 = FOO;
+LL | |
+LL | |
+LL | | fn main() {}
+   | |____________^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/issue-24968.rs b/src/test/ui/resolve/issue-24968.rs
index 916b48205dc..19e16abcee3 100644
--- a/src/test/ui/resolve/issue-24968.rs
+++ b/src/test/ui/resolve/issue-24968.rs
@@ -1,5 +1,30 @@
+// Also includes more Self usages per #93796
+
 fn foo(_: Self) {
 //~^ ERROR cannot find type `Self`
 }
 
+fn foo2() {
+    let x: Self;
+    //~^ ERROR cannot find type `Self`
+}
+
+type Foo<T>
+where
+    Self: Clone,
+//~^ ERROR cannot find type `Self`
+= Vec<T>;
+
+const FOO: Self = 0;
+//~^ ERROR cannot find type `Self`
+
+const FOO2: u32 = Self::bar();
+//~^ ERROR failed to resolve: `Self`
+
+static FOO_S: Self = 0;
+//~^ ERROR cannot find type `Self`
+
+static FOO_S2: u32 = Self::bar();
+//~^ ERROR failed to resolve: `Self`
+
 fn main() {}
diff --git a/src/test/ui/resolve/issue-24968.stderr b/src/test/ui/resolve/issue-24968.stderr
index c891952c42b..7e539d25804 100644
--- a/src/test/ui/resolve/issue-24968.stderr
+++ b/src/test/ui/resolve/issue-24968.stderr
@@ -1,9 +1,57 @@
+error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
+  --> $DIR/issue-24968.rs:21:19
+   |
+LL | const FOO2: u32 = Self::bar();
+   |                   ^^^^ `Self` is only available in impls, traits, and type definitions
+
+error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
+  --> $DIR/issue-24968.rs:27:22
+   |
+LL | static FOO_S2: u32 = Self::bar();
+   |                      ^^^^ `Self` is only available in impls, traits, and type definitions
+
 error[E0411]: cannot find type `Self` in this scope
-  --> $DIR/issue-24968.rs:1:11
+  --> $DIR/issue-24968.rs:3:11
    |
 LL | fn foo(_: Self) {
-   |           ^^^^ `Self` is only available in impls, traits, and type definitions
+   |    ---    ^^^^ `Self` is only available in impls, traits, and type definitions
+   |    |
+   |    `Self` not allowed in a function
+
+error[E0411]: cannot find type `Self` in this scope
+  --> $DIR/issue-24968.rs:8:12
+   |
+LL | fn foo2() {
+   |    ---- `Self` not allowed in a function
+LL |     let x: Self;
+   |            ^^^^ `Self` is only available in impls, traits, and type definitions
+
+error[E0411]: cannot find type `Self` in this scope
+  --> $DIR/issue-24968.rs:14:5
+   |
+LL | type Foo<T>
+   |      --- `Self` not allowed in a type alias
+LL | where
+LL |     Self: Clone,
+   |     ^^^^ `Self` is only available in impls, traits, and type definitions
+
+error[E0411]: cannot find type `Self` in this scope
+  --> $DIR/issue-24968.rs:18:12
+   |
+LL | const FOO: Self = 0;
+   |       ---  ^^^^ `Self` is only available in impls, traits, and type definitions
+   |       |
+   |       `Self` not allowed in a constant item
+
+error[E0411]: cannot find type `Self` in this scope
+  --> $DIR/issue-24968.rs:24:15
+   |
+LL | static FOO_S: Self = 0;
+   |        -----  ^^^^ `Self` is only available in impls, traits, and type definitions
+   |        |
+   |        `Self` not allowed in a static item
 
-error: aborting due to previous error
+error: aborting due to 7 previous errors
 
-For more information about this error, try `rustc --explain E0411`.
+Some errors have detailed explanations: E0411, E0433.
+For more information about an error, try `rustc --explain E0411`.
diff --git a/src/test/ui/statics/uninhabited-static.stderr b/src/test/ui/statics/uninhabited-static.stderr
index 1e0becb7d5a..855e5dca92a 100644
--- a/src/test/ui/statics/uninhabited-static.stderr
+++ b/src/test/ui/statics/uninhabited-static.stderr
@@ -49,12 +49,6 @@ error[E0080]: could not evaluate static initializer
 LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
 
-error[E0080]: could not evaluate static initializer
-  --> $DIR/uninhabited-static.rs:16:32
-   |
-LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
-
 warning: the type `Void` does not permit zero-initialization
   --> $DIR/uninhabited-static.rs:12:31
    |
@@ -67,6 +61,12 @@ LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
    = note: `#[warn(invalid_value)]` on by default
    = note: enums with no variants have no valid value
 
+error[E0080]: could not evaluate static initializer
+  --> $DIR/uninhabited-static.rs:16:32
+   |
+LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
+
 warning: the type `Void` does not permit zero-initialization
   --> $DIR/uninhabited-static.rs:16:32
    |
diff --git a/src/test/ui/structs/struct-path-associated-type.stderr b/src/test/ui/structs/struct-path-associated-type.stderr
index 7424ceecbe3..bdce0e1b331 100644
--- a/src/test/ui/structs/struct-path-associated-type.stderr
+++ b/src/test/ui/structs/struct-path-associated-type.stderr
@@ -10,7 +10,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     let z = T::A::<u8> {};
    |                -   ^^ type argument not allowed
    |                |
-   |                not allowed on this
+   |                not allowed on this type
 
 error[E0071]: expected struct, variant or union type, found associated type
   --> $DIR/struct-path-associated-type.rs:14:13
@@ -30,7 +30,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     let z = T::A::<u8> {};
    |                -   ^^ type argument not allowed
    |                |
-   |                not allowed on this
+   |                not allowed on this type
 
 error[E0223]: ambiguous associated type
   --> $DIR/struct-path-associated-type.rs:32:13
diff --git a/src/test/ui/structs/struct-path-self.stderr b/src/test/ui/structs/struct-path-self.stderr
index 4bd0fb38985..c2a8623f9b4 100644
--- a/src/test/ui/structs/struct-path-self.stderr
+++ b/src/test/ui/structs/struct-path-self.stderr
@@ -10,7 +10,7 @@ error[E0109]: type arguments are not allowed on self type
 LL |         let z = Self::<u8> {};
    |                 ----   ^^ type argument not allowed
    |                 |
-   |                 not allowed on this
+   |                 not allowed on self type
    |
 help: the `Self` type doesn't accept type parameters
    |
@@ -36,7 +36,7 @@ error[E0109]: type arguments are not allowed on self type
 LL |         let z = Self::<u8> {};
    |                 ----   ^^ type argument not allowed
    |                 |
-   |                 not allowed on this
+   |                 not allowed on self type
    |
 note: `Self` is of type `S`
   --> $DIR/struct-path-self.rs:1:8
@@ -58,7 +58,7 @@ error[E0109]: type arguments are not allowed on self type
 LL |         let z = Self::<u8> {};
    |                 ----   ^^ type argument not allowed
    |                 |
-   |                 not allowed on this
+   |                 not allowed on self type
    |
 note: `Self` is of type `S`
   --> $DIR/struct-path-self.rs:1:8
diff --git a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
index aacbe1d9efb..3d367eca707 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
+++ b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
@@ -15,8 +15,8 @@ LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
    |     ^^^^
 help: remove the extra argument
    |
-LL |     let _: Option<(i32, bool)> = Some({(i32, bool)});
-   |                                  ~~~~~~~~~~~~~~~~~~~
+LL |     let _: Option<(i32, bool)> = Some(/* (i32, bool) */);
+   |                                  ~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple-errors.rs:8:5
@@ -35,8 +35,8 @@ LL | fn int_bool(_: (i32, bool)) {
    |    ^^^^^^^^ --------------
 help: remove the extra argument
    |
-LL |     int_bool({(i32, bool)});
-   |     ~~~~~~~~~~~~~~~~~~~~~~~
+LL |     int_bool(/* (i32, bool) */);
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
   --> $DIR/args-instead-of-tuple-errors.rs:11:28
@@ -51,8 +51,8 @@ LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
    |     ^^^^
 help: provide the argument
    |
-LL |     let _: Option<(i8,)> = Some({(i8,)});
-   |                            ~~~~~~~~~~~~~
+LL |     let _: Option<(i8,)> = Some(/* (i8,) */);
+   |                            ~~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/args-instead-of-tuple-errors.rs:14:34
diff --git a/src/test/ui/issues/issue-16597-empty.rs b/src/test/ui/test-attrs/issue-16597-empty.rs
index 2bdd08575c4..2bdd08575c4 100644
--- a/src/test/ui/issues/issue-16597-empty.rs
+++ b/src/test/ui/test-attrs/issue-16597-empty.rs
diff --git a/src/test/ui/issues/issue-16597.rs b/src/test/ui/test-attrs/issue-16597.rs
index 35769bfc117..35769bfc117 100644
--- a/src/test/ui/issues/issue-16597.rs
+++ b/src/test/ui/test-attrs/issue-16597.rs
diff --git a/src/test/ui/issues/issue-38033.rs b/src/test/ui/traits/issue-38033.rs
index 16b867ec88f..16b867ec88f 100644
--- a/src/test/ui/issues/issue-38033.rs
+++ b/src/test/ui/traits/issue-38033.rs
diff --git a/src/test/ui/tuple/wrong_argument_ice-3.stderr b/src/test/ui/tuple/wrong_argument_ice-3.stderr
index 6ea6e670fd6..667b15776ef 100644
--- a/src/test/ui/tuple/wrong_argument_ice-3.stderr
+++ b/src/test/ui/tuple/wrong_argument_ice-3.stderr
@@ -15,8 +15,8 @@ LL |     pub fn push(&mut self, value: T) {
    |            ^^^^
 help: remove the extra argument
    |
-LL |         groups.push({(Vec<String>, Vec<Process>)});
-   |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |         groups.push(/* (Vec<String>, Vec<Process>) */);
+   |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
index cfc596e1b78..9601bdce4c5 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
@@ -23,7 +23,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |         Self::TSVariant::<()>(());
    |               ---------   ^^ type argument not allowed
    |               |
-   |               not allowed on this
+   |               not allowed on this type
 
 error[E0109]: type arguments are not allowed on self type
   --> $DIR/enum-variant-generic-args.rs:17:16
@@ -31,7 +31,7 @@ error[E0109]: type arguments are not allowed on self type
 LL |         Self::<()>::TSVariant(());
    |         ----   ^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on self type
    |
 note: `Self` is of type `Enum<T>`
   --> $DIR/enum-variant-generic-args.rs:7:6
@@ -71,7 +71,7 @@ error[E0109]: type arguments are not allowed on self type
 LL |         Self::<()>::TSVariant::<()>(());
    |         ----   ^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on self type
    |
 note: `Self` is of type `Enum<T>`
   --> $DIR/enum-variant-generic-args.rs:7:6
@@ -92,7 +92,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |         Self::<()>::TSVariant::<()>(());
    |                     ---------   ^^ type argument not allowed
    |                     |
-   |                     not allowed on this
+   |                     not allowed on this type
 
 error[E0308]: mismatched types
   --> $DIR/enum-variant-generic-args.rs:26:29
@@ -112,7 +112,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |         Self::SVariant::<()> { v: () };
    |               --------   ^^ type argument not allowed
    |               |
-   |               not allowed on this
+   |               not allowed on this type
    |
    = note: enum variants can't have type parameters
 help: you might have meant to specity type parameters on enum `Enum`
@@ -139,7 +139,7 @@ error[E0109]: type arguments are not allowed on self type
 LL |         Self::<()>::SVariant { v: () };
    |         ----   ^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on self type
    |
 note: `Self` is of type `Enum<T>`
   --> $DIR/enum-variant-generic-args.rs:7:6
@@ -172,7 +172,7 @@ error[E0109]: type arguments are not allowed on self type
 LL |         Self::<()>::SVariant::<()> { v: () };
    |         ----   ^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on self type
    |
 note: `Self` is of type `Enum<T>`
   --> $DIR/enum-variant-generic-args.rs:7:6
@@ -193,7 +193,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |         Self::<()>::SVariant::<()> { v: () };
    |                     --------   ^^ type argument not allowed
    |                     |
-   |                     not allowed on this
+   |                     not allowed on this type
    |
    = note: enum variants can't have type parameters
 help: you might have meant to specity type parameters on enum `Enum`
@@ -220,7 +220,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |         Self::UVariant::<()>;
    |               --------   ^^ type argument not allowed
    |               |
-   |               not allowed on this
+   |               not allowed on this type
 
 error[E0109]: type arguments are not allowed on self type
   --> $DIR/enum-variant-generic-args.rs:43:16
@@ -228,7 +228,7 @@ error[E0109]: type arguments are not allowed on self type
 LL |         Self::<()>::UVariant;
    |         ----   ^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on self type
    |
 note: `Self` is of type `Enum<T>`
   --> $DIR/enum-variant-generic-args.rs:7:6
@@ -249,7 +249,7 @@ error[E0109]: type arguments are not allowed on self type
 LL |         Self::<()>::UVariant::<()>;
    |         ----   ^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on self type
    |
 note: `Self` is of type `Enum<T>`
   --> $DIR/enum-variant-generic-args.rs:7:6
@@ -270,7 +270,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |         Self::<()>::UVariant::<()>;
    |                     --------   ^^ type argument not allowed
    |                     |
-   |                     not allowed on this
+   |                     not allowed on this type
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/enum-variant-generic-args.rs:54:29
@@ -278,7 +278,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     Enum::<()>::TSVariant::<()>(());
    |                 ---------   ^^ type argument not allowed
    |                 |
-   |                 not allowed on this
+   |                 not allowed on this type
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/enum-variant-generic-args.rs:57:24
@@ -286,7 +286,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     Alias::TSVariant::<()>(());
    |            ---------   ^^ type argument not allowed
    |            |
-   |            not allowed on this
+   |            not allowed on this type
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/enum-variant-generic-args.rs:59:30
@@ -294,7 +294,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     Alias::<()>::TSVariant::<()>(());
    |                  ---------   ^^ type argument not allowed
    |                  |
-   |                  not allowed on this
+   |                  not allowed on this type
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/enum-variant-generic-args.rs:62:29
@@ -302,7 +302,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     AliasFixed::TSVariant::<()>(());
    |                 ---------   ^^ type argument not allowed
    |                 |
-   |                 not allowed on this
+   |                 not allowed on this type
 
 error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:64:5
@@ -338,7 +338,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     AliasFixed::<()>::TSVariant::<()>(());
    |                       ---------   ^^ type argument not allowed
    |                       |
-   |                       not allowed on this
+   |                       not allowed on this type
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/enum-variant-generic-args.rs:72:28
@@ -346,7 +346,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     Enum::<()>::SVariant::<()> { v: () };
    |                 --------   ^^ type argument not allowed
    |                 |
-   |                 not allowed on this
+   |                 not allowed on this type
    |
    = note: enum variants can't have type parameters
 
@@ -356,7 +356,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     Alias::SVariant::<()> { v: () };
    |            --------   ^^ type argument not allowed
    |            |
-   |            not allowed on this
+   |            not allowed on this type
    |
    = note: enum variants can't have type parameters
 help: you might have meant to specity type parameters on enum `Enum`
@@ -371,7 +371,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     Alias::<()>::SVariant::<()> { v: () };
    |                  --------   ^^ type argument not allowed
    |                  |
-   |                  not allowed on this
+   |                  not allowed on this type
    |
    = note: enum variants can't have type parameters
 help: you might have meant to specity type parameters on enum `Enum`
@@ -386,7 +386,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     AliasFixed::SVariant::<()> { v: () };
    |                 --------   ^^ type argument not allowed
    |                 |
-   |                 not allowed on this
+   |                 not allowed on this type
    |
    = note: enum variants can't have type parameters
 help: you might have meant to specity type parameters on enum `Enum`
@@ -429,7 +429,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     AliasFixed::<()>::SVariant::<()> { v: () };
    |                       --------   ^^ type argument not allowed
    |                       |
-   |                       not allowed on this
+   |                       not allowed on this type
    |
    = note: enum variants can't have type parameters
 help: you might have meant to specity type parameters on enum `Enum`
@@ -444,7 +444,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     Enum::<()>::UVariant::<()>;
    |                 --------   ^^ type argument not allowed
    |                 |
-   |                 not allowed on this
+   |                 not allowed on this type
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/enum-variant-generic-args.rs:93:23
@@ -452,7 +452,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     Alias::UVariant::<()>;
    |            --------   ^^ type argument not allowed
    |            |
-   |            not allowed on this
+   |            not allowed on this type
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/enum-variant-generic-args.rs:95:29
@@ -460,7 +460,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     Alias::<()>::UVariant::<()>;
    |                  --------   ^^ type argument not allowed
    |                  |
-   |                  not allowed on this
+   |                  not allowed on this type
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/enum-variant-generic-args.rs:98:28
@@ -468,7 +468,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     AliasFixed::UVariant::<()>;
    |                 --------   ^^ type argument not allowed
    |                 |
-   |                 not allowed on this
+   |                 not allowed on this type
 
 error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:100:5
@@ -504,7 +504,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     AliasFixed::<()>::UVariant::<()>;
    |                       --------   ^^ type argument not allowed
    |                       |
-   |                       not allowed on this
+   |                       not allowed on this type
 
 error: aborting due to 39 previous errors
 
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
index 3fc5a3594d8..6ae2aa1dc77 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
@@ -11,8 +11,8 @@ LL |     V(u8)
    |     ^
 help: provide the argument
    |
-LL |     <E>::V({u8});
-   |     ~~~~~~~~~~~~
+LL |     <E>::V(/* u8 */);
+   |     ~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17
diff --git a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr
index 474548a14a9..51b1c8a1068 100644
--- a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr
+++ b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr
@@ -4,7 +4,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     let _ = Alias::None::<u8>;
    |                    ----   ^^ type argument not allowed
    |                    |
-   |                    not allowed on this
+   |                    not allowed on this type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias/issue-62263-self-in-atb.rs b/src/test/ui/type-alias/issue-62263-self-in-atb.rs
index 1f64b4cfe5c..91522d8912f 100644
--- a/src/test/ui/type-alias/issue-62263-self-in-atb.rs
+++ b/src/test/ui/type-alias/issue-62263-self-in-atb.rs
@@ -3,6 +3,6 @@ pub trait Trait {
 }
 
 pub type Alias = dyn Trait<A = Self::A>;
-//~^ ERROR failed to resolve: use of undeclared type `Self` [E0433]
+//~^ ERROR failed to resolve: `Self`
 
 fn main() {}
diff --git a/src/test/ui/type-alias/issue-62263-self-in-atb.stderr b/src/test/ui/type-alias/issue-62263-self-in-atb.stderr
index d34b6ed5038..c20074dc27c 100644
--- a/src/test/ui/type-alias/issue-62263-self-in-atb.stderr
+++ b/src/test/ui/type-alias/issue-62263-self-in-atb.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type `Self`
+error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
   --> $DIR/issue-62263-self-in-atb.rs:5:32
    |
 LL | pub type Alias = dyn Trait<A = Self::A>;
-   |                                ^^^^ use of undeclared type `Self`
+   |                                ^^^^ `Self` is only available in impls, traits, and type definitions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias/issue-62305-self-assoc-ty.rs b/src/test/ui/type-alias/issue-62305-self-assoc-ty.rs
index 999902fb18b..a4d9a285485 100644
--- a/src/test/ui/type-alias/issue-62305-self-assoc-ty.rs
+++ b/src/test/ui/type-alias/issue-62305-self-assoc-ty.rs
@@ -1,4 +1,4 @@
 type Alias = Self::Target;
-//~^ ERROR failed to resolve: use of undeclared type `Self` [E0433]
+//~^ ERROR failed to resolve: `Self`
 
 fn main() {}
diff --git a/src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr b/src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr
index 823a5fa50fc..f3da50df926 100644
--- a/src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr
+++ b/src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type `Self`
+error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
   --> $DIR/issue-62305-self-assoc-ty.rs:1:14
    |
 LL | type Alias = Self::Target;
-   |              ^^^^ use of undeclared type `Self`
+   |              ^^^^ `Self` is only available in impls, traits, and type definitions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias/issue-62364-self-ty-arg.stderr b/src/test/ui/type-alias/issue-62364-self-ty-arg.stderr
index cae41672ead..7e15e42e3cc 100644
--- a/src/test/ui/type-alias/issue-62364-self-ty-arg.stderr
+++ b/src/test/ui/type-alias/issue-62364-self-ty-arg.stderr
@@ -2,9 +2,9 @@ error[E0411]: cannot find type `Self` in this scope
   --> $DIR/issue-62364-self-ty-arg.rs:5:29
    |
 LL | type Alias<'a> = Struct<&'a Self>;
-   |              -              ^^^^ `Self` is only available in impls, traits, and type definitions
-   |              |
-   |              help: you might be missing a type parameter: `, Self`
+   |      -----                  ^^^^ `Self` is only available in impls, traits, and type definitions
+   |      |
+   |      `Self` not allowed in a type alias
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type/issue-91268.stderr b/src/test/ui/type/issue-91268.stderr
index 1df5a2cf07b..e426f450b11 100644
--- a/src/test/ui/type/issue-91268.stderr
+++ b/src/test/ui/type/issue-91268.stderr
@@ -41,7 +41,7 @@ error[E0109]: type arguments are not allowed on this type
 LL |     0: u8(ţ
    |        -- ^ type argument not allowed
    |        |
-   |        not allowed on this
+   |        not allowed on this type
    |
 help: primitive type `u8` doesn't have generic parameters
    |
diff --git a/src/test/ui/issues/issue-10401.rs b/src/test/ui/typeck/issue-10401.rs
index d77ff381e1a..d77ff381e1a 100644
--- a/src/test/ui/issues/issue-10401.rs
+++ b/src/test/ui/typeck/issue-10401.rs
diff --git a/src/test/ui/issues/issue-10401.stderr b/src/test/ui/typeck/issue-10401.stderr
index 1f68abcfb43..1f68abcfb43 100644
--- a/src/test/ui/issues/issue-10401.stderr
+++ b/src/test/ui/typeck/issue-10401.stderr
diff --git a/src/test/ui/typeck/prim-with-args.stderr b/src/test/ui/typeck/prim-with-args.stderr
index cdc7e96bfc5..c45fd00bae9 100644
--- a/src/test/ui/typeck/prim-with-args.stderr
+++ b/src/test/ui/typeck/prim-with-args.stderr
@@ -4,7 +4,7 @@ error[E0109]: type arguments are not allowed on this type
 LL | let _x: isize<isize>;
    |         ----- ^^^^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `isize` doesn't have generic parameters
    |
@@ -18,7 +18,7 @@ error[E0109]: type arguments are not allowed on this type
 LL | let _x: i8<isize>;
    |         -- ^^^^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `i8` doesn't have generic parameters
    |
@@ -32,7 +32,7 @@ error[E0109]: type arguments are not allowed on this type
 LL | let _x: i16<isize>;
    |         --- ^^^^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `i16` doesn't have generic parameters
    |
@@ -46,7 +46,7 @@ error[E0109]: type arguments are not allowed on this type
 LL | let _x: i32<isize>;
    |         --- ^^^^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `i32` doesn't have generic parameters
    |
@@ -60,7 +60,7 @@ error[E0109]: type arguments are not allowed on this type
 LL | let _x: i64<isize>;
    |         --- ^^^^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `i64` doesn't have generic parameters
    |
@@ -74,7 +74,7 @@ error[E0109]: type arguments are not allowed on this type
 LL | let _x: usize<isize>;
    |         ----- ^^^^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `usize` doesn't have generic parameters
    |
@@ -88,7 +88,7 @@ error[E0109]: type arguments are not allowed on this type
 LL | let _x: u8<isize>;
    |         -- ^^^^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `u8` doesn't have generic parameters
    |
@@ -102,7 +102,7 @@ error[E0109]: type arguments are not allowed on this type
 LL | let _x: u16<isize>;
    |         --- ^^^^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `u16` doesn't have generic parameters
    |
@@ -116,7 +116,7 @@ error[E0109]: type arguments are not allowed on this type
 LL | let _x: u32<isize>;
    |         --- ^^^^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `u32` doesn't have generic parameters
    |
@@ -130,7 +130,7 @@ error[E0109]: type arguments are not allowed on this type
 LL | let _x: u64<isize>;
    |         --- ^^^^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `u64` doesn't have generic parameters
    |
@@ -144,7 +144,7 @@ error[E0109]: type arguments are not allowed on this type
 LL | let _x: char<isize>;
    |         ---- ^^^^^ type argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `char` doesn't have generic parameters
    |
@@ -158,7 +158,7 @@ error[E0109]: lifetime arguments are not allowed on this type
 LL | let _x: isize<'static>;
    |         ----- ^^^^^^^ lifetime argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `isize` doesn't have generic parameters
    |
@@ -172,7 +172,7 @@ error[E0109]: lifetime arguments are not allowed on this type
 LL | let _x: i8<'static>;
    |         -- ^^^^^^^ lifetime argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `i8` doesn't have generic parameters
    |
@@ -186,7 +186,7 @@ error[E0109]: lifetime arguments are not allowed on this type
 LL | let _x: i16<'static>;
    |         --- ^^^^^^^ lifetime argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `i16` doesn't have generic parameters
    |
@@ -200,7 +200,7 @@ error[E0109]: lifetime arguments are not allowed on this type
 LL | let _x: i32<'static>;
    |         --- ^^^^^^^ lifetime argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `i32` doesn't have generic parameters
    |
@@ -214,7 +214,7 @@ error[E0109]: lifetime arguments are not allowed on this type
 LL | let _x: i64<'static>;
    |         --- ^^^^^^^ lifetime argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `i64` doesn't have generic parameters
    |
@@ -228,7 +228,7 @@ error[E0109]: lifetime arguments are not allowed on this type
 LL | let _x: usize<'static>;
    |         ----- ^^^^^^^ lifetime argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `usize` doesn't have generic parameters
    |
@@ -242,7 +242,7 @@ error[E0109]: lifetime arguments are not allowed on this type
 LL | let _x: u8<'static>;
    |         -- ^^^^^^^ lifetime argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `u8` doesn't have generic parameters
    |
@@ -256,7 +256,7 @@ error[E0109]: lifetime arguments are not allowed on this type
 LL | let _x: u16<'static>;
    |         --- ^^^^^^^ lifetime argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `u16` doesn't have generic parameters
    |
@@ -270,7 +270,7 @@ error[E0109]: lifetime arguments are not allowed on this type
 LL | let _x: u32<'static>;
    |         --- ^^^^^^^ lifetime argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `u32` doesn't have generic parameters
    |
@@ -284,7 +284,7 @@ error[E0109]: lifetime arguments are not allowed on this type
 LL | let _x: u64<'static>;
    |         --- ^^^^^^^ lifetime argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `u64` doesn't have generic parameters
    |
@@ -298,7 +298,7 @@ error[E0109]: lifetime arguments are not allowed on this type
 LL | let _x: char<'static>;
    |         ---- ^^^^^^^ lifetime argument not allowed
    |         |
-   |         not allowed on this
+   |         not allowed on this type
    |
 help: primitive type `char` doesn't have generic parameters
    |
diff --git a/src/test/ui/typeck/struct-enum-wrong-args.stderr b/src/test/ui/typeck/struct-enum-wrong-args.stderr
index aafb29f25d0..2ea822df275 100644
--- a/src/test/ui/typeck/struct-enum-wrong-args.stderr
+++ b/src/test/ui/typeck/struct-enum-wrong-args.stderr
@@ -45,8 +45,8 @@ LL |     Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
    |     ^^
 help: provide the argument
    |
-LL |     let _ = Ok({_});
-   |             ~~~~~~~
+LL |     let _ = Ok(/* value */);
+   |             ~~~~~~~~~~~~~~~
 
 error[E0061]: this struct takes 1 argument but 0 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:9:13
@@ -61,8 +61,8 @@ LL | struct Wrapper(i32);
    |        ^^^^^^^
 help: provide the argument
    |
-LL |     let _ = Wrapper({i32});
-   |             ~~~~~~~~~~~~~~
+LL |     let _ = Wrapper(/* i32 */);
+   |             ~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this struct takes 1 argument but 2 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:10:13
@@ -93,8 +93,8 @@ LL | struct DoubleWrapper(i32, i32);
    |        ^^^^^^^^^^^^^
 help: provide the arguments
    |
-LL |     let _ = DoubleWrapper({i32}, {i32});
-   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     let _ = DoubleWrapper(/* i32 */, /* i32 */);
+   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this struct takes 2 arguments but 1 argument was supplied
   --> $DIR/struct-enum-wrong-args.rs:12:13
@@ -109,8 +109,8 @@ LL | struct DoubleWrapper(i32, i32);
    |        ^^^^^^^^^^^^^
 help: provide the argument
    |
-LL |     let _ = DoubleWrapper(5, {i32});
-   |             ~~~~~~~~~~~~~~~~~~~~~~~
+LL |     let _ = DoubleWrapper(5, /* i32 */);
+   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this struct takes 2 arguments but 3 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:13:13
diff --git a/src/test/ui/issues/issue-3080.mir.stderr b/src/test/ui/unsafe/issue-3080.mir.stderr
index f395c30b815..f395c30b815 100644
--- a/src/test/ui/issues/issue-3080.mir.stderr
+++ b/src/test/ui/unsafe/issue-3080.mir.stderr
diff --git a/src/test/ui/issues/issue-3080.rs b/src/test/ui/unsafe/issue-3080.rs
index 2b5269dda8f..2b5269dda8f 100644
--- a/src/test/ui/issues/issue-3080.rs
+++ b/src/test/ui/unsafe/issue-3080.rs
diff --git a/src/test/ui/issues/issue-3080.thir.stderr b/src/test/ui/unsafe/issue-3080.thir.stderr
index 4d8acac61d9..4d8acac61d9 100644
--- a/src/test/ui/issues/issue-3080.thir.stderr
+++ b/src/test/ui/unsafe/issue-3080.thir.stderr
diff --git a/src/test/ui/issues/issue-47412.mir.stderr b/src/test/ui/unsafe/issue-47412.mir.stderr
index 305f482e8c2..305f482e8c2 100644
--- a/src/test/ui/issues/issue-47412.mir.stderr
+++ b/src/test/ui/unsafe/issue-47412.mir.stderr
diff --git a/src/test/ui/issues/issue-47412.rs b/src/test/ui/unsafe/issue-47412.rs
index df6d6e4222e..df6d6e4222e 100644
--- a/src/test/ui/issues/issue-47412.rs
+++ b/src/test/ui/unsafe/issue-47412.rs
diff --git a/src/test/ui/issues/issue-47412.thir.stderr b/src/test/ui/unsafe/issue-47412.thir.stderr
index 305f482e8c2..305f482e8c2 100644
--- a/src/test/ui/issues/issue-47412.thir.stderr
+++ b/src/test/ui/unsafe/issue-47412.thir.stderr
diff --git a/src/test/ui/use/use-self-type.rs b/src/test/ui/use/use-self-type.rs
index 370593b2eb2..3b4ce429701 100644
--- a/src/test/ui/use/use-self-type.rs
+++ b/src/test/ui/use/use-self-type.rs
@@ -4,7 +4,7 @@ impl S {
     fn f() {}
     fn g() {
         use Self::f; //~ ERROR unresolved import
-        pub(in Self::f) struct Z; //~ ERROR use of undeclared type `Self`
+        pub(in Self::f) struct Z; //~ ERROR failed to resolve: `Self`
     }
 }
 
diff --git a/src/test/ui/use/use-self-type.stderr b/src/test/ui/use/use-self-type.stderr
index d1469fb3490..e6153941151 100644
--- a/src/test/ui/use/use-self-type.stderr
+++ b/src/test/ui/use/use-self-type.stderr
@@ -1,14 +1,14 @@
-error[E0433]: failed to resolve: use of undeclared type `Self`
+error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
   --> $DIR/use-self-type.rs:7:16
    |
 LL |         pub(in Self::f) struct Z;
-   |                ^^^^ use of undeclared type `Self`
+   |                ^^^^ `Self` is only available in impls, traits, and type definitions
 
 error[E0432]: unresolved import `Self`
   --> $DIR/use-self-type.rs:6:13
    |
 LL |         use Self::f;
-   |             ^^^^ use of undeclared type `Self`
+   |             ^^^^ `Self` is only available in impls, traits, and type definitions
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/usize-generic-argument-parent.stderr b/src/test/ui/usize-generic-argument-parent.stderr
index b3980101104..abe8c09b739 100644
--- a/src/test/ui/usize-generic-argument-parent.stderr
+++ b/src/test/ui/usize-generic-argument-parent.stderr
@@ -4,7 +4,7 @@ error[E0109]: const arguments are not allowed on this type
 LL |     let x: usize<foo>;
    |            ----- ^^^ const argument not allowed
    |            |
-   |            not allowed on this
+   |            not allowed on this type
    |
 help: primitive type `usize` doesn't have generic parameters
    |
diff --git a/src/test/ui/wf/issue-95665.rs b/src/test/ui/wf/issue-95665.rs
new file mode 100644
index 00000000000..67923cbb2d6
--- /dev/null
+++ b/src/test/ui/wf/issue-95665.rs
@@ -0,0 +1,18 @@
+// Regression test for the ICE described in #95665.
+// Ensure that the expected error is output (and thus that there is no ICE)
+
+pub trait Trait: {}
+
+pub struct Struct<T: Trait> {
+    member: T,
+}
+
+// uncomment and bug goes away
+// impl Trait for u8 {}
+
+extern "C" {
+    static VAR: Struct<u8>;
+                //~^ 14:17: 14:27: the trait bound `u8: Trait` is not satisfied [E0277]
+}
+
+fn main() {}
diff --git a/src/test/ui/wf/issue-95665.stderr b/src/test/ui/wf/issue-95665.stderr
new file mode 100644
index 00000000000..b1cda59a916
--- /dev/null
+++ b/src/test/ui/wf/issue-95665.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `u8: Trait` is not satisfied
+  --> $DIR/issue-95665.rs:14:17
+   |
+LL |     static VAR: Struct<u8>;
+   |                 ^^^^^^^^^^ the trait `Trait` is not implemented for `u8`
+   |
+note: required by a bound in `Struct`
+  --> $DIR/issue-95665.rs:6:22
+   |
+LL | pub struct Struct<T: Trait> {
+   |                      ^^^^^ required by this bound in `Struct`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer
-Subproject 366bd7242ed00c65f293497a26eb81c7510ac68
+Subproject 427061da19723f2206fe4dcb175c9c43b9a6193
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index f59121181d2..8ec5c332493 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -8,7 +8,7 @@ use std::path::Path;
 const ENTRY_LIMIT: usize = 1000;
 // FIXME: The following limits should be reduced eventually.
 const ROOT_ENTRY_LIMIT: usize = 968;
-const ISSUES_ENTRY_LIMIT: usize = 2179;
+const ISSUES_ENTRY_LIMIT: usize = 2147;
 
 fn check_entries(path: &Path, bad: &mut bool) {
     let dirs = walkdir::WalkDir::new(&path.join("test/ui"))