about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/bootstrap.py18
-rw-r--r--src/bootstrap/builder.rs2
-rw-r--r--src/bootstrap/dist.rs18
-rw-r--r--src/bootstrap/doc.rs151
-rw-r--r--src/bootstrap/lib.rs8
-rw-r--r--src/bootstrap/native.rs85
-rw-r--r--src/bootstrap/test.rs45
-rw-r--r--src/bootstrap/tool.rs1
-rw-r--r--src/build_helper/lib.rs1
-rw-r--r--src/ci/docker/host-x86_64/armhf-gnu/Dockerfile2
-rwxr-xr-xsrc/ci/docker/host-x86_64/disabled/dist-x86_64-dragonfly/build-toolchain.sh2
-rw-r--r--src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.config2
-rw-r--r--src/ci/docker/host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.config2
-rw-r--r--src/ci/docker/host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.config4
-rw-r--r--src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config5
-rw-r--r--src/ci/docker/host-x86_64/dist-various-2/Dockerfile2
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh2
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh1
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile5
-rwxr-xr-xsrc/ci/pgo.sh8
-rw-r--r--src/ci/shared.sh2
-rw-r--r--src/doc/rustdoc/src/SUMMARY.md1
-rw-r--r--src/doc/rustdoc/src/website-features.md25
-rw-r--r--src/doc/unstable-book/src/library-features/asm.md3
-rw-r--r--src/doc/unstable-book/src/library-features/try-trait.md50
-rw-r--r--src/etc/installer/README.md2
-rw-r--r--src/etc/natvis/intrinsic.natvis26
-rw-r--r--src/etc/natvis/libstd.natvis2
-rw-r--r--src/librustdoc/clean/auto_trait.rs18
-rw-r--r--src/librustdoc/clean/inline.rs30
-rw-r--r--src/librustdoc/clean/mod.rs105
-rw-r--r--src/librustdoc/clean/simplify.rs28
-rw-r--r--src/librustdoc/clean/types.rs8
-rw-r--r--src/librustdoc/clean/utils.rs20
-rw-r--r--src/librustdoc/core.rs44
-rw-r--r--src/librustdoc/doctest.rs3
-rw-r--r--src/librustdoc/formats/cache.rs20
-rw-r--r--src/librustdoc/html/format.rs63
-rw-r--r--src/librustdoc/html/highlight.rs2
-rw-r--r--src/librustdoc/html/render/cache.rs29
-rw-r--r--src/librustdoc/html/render/mod.rs34
-rw-r--r--src/librustdoc/html/render/print_item.rs35
-rw-r--r--src/librustdoc/html/static/normalize.css2
-rw-r--r--src/librustdoc/html/static/rustdoc.css95
-rw-r--r--src/librustdoc/html/static/search.js93
-rw-r--r--src/librustdoc/json/conversions.rs32
-rw-r--r--src/librustdoc/lib.rs4
-rw-r--r--src/librustdoc/lint.rs2
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs3
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links/early.rs63
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs4
-rw-r--r--src/librustdoc/passes/mod.rs2
-rw-r--r--src/stage0.txt2
-rw-r--r--src/test/assembly/asm/mips-types.rs3
-rw-r--r--src/test/assembly/asm/powerpc-types.rs3
-rw-r--r--src/test/assembly/asm/riscv-types.rs3
-rw-r--r--src/test/assembly/asm/x86-modifiers.rs2
-rw-r--r--src/test/assembly/asm/x86-types.rs2
-rw-r--r--src/test/assembly/static-relocation-model.rs4
-rw-r--r--src/test/codegen/abi-efiapi.rs7
-rw-r--r--src/test/codegen/asm-options.rs7
-rw-r--r--src/test/codegen/asm-sanitize-llvm.rs3
-rw-r--r--src/test/codegen/async-fn-debug-msvc.rs2
-rw-r--r--src/test/codegen/async-fn-debug.rs2
-rw-r--r--src/test/codegen/default-requires-uwtable.rs3
-rw-r--r--src/test/codegen/fn-impl-trait-self.rs3
-rw-r--r--src/test/codegen/frame-pointer.rs35
-rw-r--r--src/test/codegen/generator-debug-msvc.rs2
-rw-r--r--src/test/codegen/generator-debug.rs2
-rw-r--r--src/test/codegen/i686-macosx-deployment-target.rs1
-rw-r--r--src/test/codegen/i686-no-macosx-deployment-target.rs1
-rw-r--r--src/test/codegen/sparc-struct-abi.rs3
-rw-r--r--src/test/codegen/x86_64-macosx-deployment-target.rs1
-rw-r--r--src/test/codegen/x86_64-no-macosx-deployment-target.rs1
-rw-r--r--src/test/debuginfo/basic-types.rs44
-rw-r--r--src/test/debuginfo/fixed-sized-array.rs39
-rw-r--r--src/test/debuginfo/function-names.rs175
-rw-r--r--src/test/debuginfo/generator-objects.rs16
-rw-r--r--src/test/debuginfo/generic-struct.rs21
-rw-r--r--src/test/debuginfo/issue-57822.rs8
-rw-r--r--src/test/debuginfo/msvc-pretty-enums.rs29
-rw-r--r--src/test/debuginfo/mutable-locs.rs51
-rw-r--r--src/test/debuginfo/mutex.rs38
-rw-r--r--src/test/debuginfo/pretty-std-collections-hash.rs5
-rw-r--r--src/test/debuginfo/pretty-std.rs23
-rw-r--r--src/test/debuginfo/range-types.rs47
-rw-r--r--src/test/debuginfo/rc_arc.rs26
-rw-r--r--src/test/debuginfo/result-types.rs28
-rw-r--r--src/test/debuginfo/rwlock-read.rs35
-rw-r--r--src/test/debuginfo/rwlock-write.rs27
-rw-r--r--src/test/debuginfo/simple-tuple.rs14
-rw-r--r--src/test/debuginfo/thread.rs31
-rw-r--r--src/test/debuginfo/tuple-in-tuple.rs42
-rw-r--r--src/test/debuginfo/type-names.cdb.js17
-rw-r--r--src/test/debuginfo/type-names.rs289
-rw-r--r--src/test/debuginfo/var-captured-in-nested-closure.rs2
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir106
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff160
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching2.rs34
-rw-r--r--src/test/pretty/ast-stmt-expr-attr.rs2
-rw-r--r--src/test/pretty/block-comment-wchar.pp2
-rw-r--r--src/test/pretty/block-comment-wchar.rs2
-rw-r--r--src/test/pretty/hir-pretty-loop.pp9
-rw-r--r--src/test/pretty/hir-pretty-loop.rs9
-rw-r--r--src/test/pretty/stmt_expr_attributes.rs3
-rw-r--r--src/test/run-make-fulldeps/core-no-fp-fmt-parse/Makefile4
-rw-r--r--src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c2
-rw-r--r--src/test/run-make/track-path-dep-info/Makefile13
-rw-r--r--src/test/run-make/track-path-dep-info/emojis.txt1
-rw-r--r--src/test/run-make/track-path-dep-info/macro_def.rs11
-rw-r--r--src/test/run-make/track-path-dep-info/macro_use.rs6
-rw-r--r--src/test/rustdoc-gui/font-weight.goml13
-rw-r--r--src/test/rustdoc-gui/label-next-to-symbol.goml36
-rw-r--r--src/test/rustdoc-gui/sidebar.goml10
-rw-r--r--src/test/rustdoc-gui/src/lib.rs6
-rw-r--r--src/test/rustdoc-gui/src/lib2.rs2
-rw-r--r--src/test/rustdoc-gui/type-weight.rs2
-rw-r--r--src/test/rustdoc-js-std/alias-4.js7
-rw-r--r--src/test/rustdoc-js-std/typed-query.js12
-rw-r--r--src/test/rustdoc-js/generics-trait.js23
-rw-r--r--src/test/rustdoc-js/generics-trait.rs8
-rw-r--r--src/test/rustdoc-js/generics.js44
-rw-r--r--src/test/rustdoc-js/generics.rs21
-rw-r--r--src/test/rustdoc-ui/auxiliary/panic-item.rs17
-rw-r--r--src/test/rustdoc-ui/renamed-lint-still-applies.rs3
-rw-r--r--src/test/rustdoc-ui/renamed-lint-still-applies.stderr21
-rw-r--r--src/test/rustdoc-ui/unknown-renamed-lints.rs3
-rw-r--r--src/test/rustdoc-ui/unknown-renamed-lints.stderr12
-rw-r--r--src/test/rustdoc-ui/unused-extern-crate.rs3
-rw-r--r--src/test/rustdoc/auxiliary/cross-crate-hidden-impl-parameter.rs5
-rw-r--r--src/test/rustdoc/auxiliary/issue-66159-1.rs2
-rw-r--r--src/test/rustdoc/auxiliary/issue-85454.rs17
-rw-r--r--src/test/rustdoc/cross-crate-hidden-impl-parameter.rs35
-rw-r--r--src/test/rustdoc/deprecated.rs6
-rw-r--r--src/test/rustdoc/doc-cfg.rs6
-rw-r--r--src/test/rustdoc/duplicate-cfg.rs5
-rw-r--r--src/test/rustdoc/for-lifetime.rs12
-rw-r--r--src/test/rustdoc/higher-ranked-trait-bounds.rs61
-rw-r--r--src/test/rustdoc/inline_cross/macros.rs6
-rw-r--r--src/test/rustdoc/internal.rs8
-rw-r--r--src/test/rustdoc/issue-32374.rs10
-rw-r--r--src/test/rustdoc/issue-46377.rs2
-rw-r--r--src/test/rustdoc/issue-55364.rs8
-rw-r--r--src/test/rustdoc/issue-66159.rs10
-rw-r--r--src/test/rustdoc/issue-85454.rs14
-rw-r--r--src/test/rustdoc/reexport-check.rs6
-rw-r--r--src/test/rustdoc/same-crate-hidden-impl-parameter.rs36
-rw-r--r--src/test/rustdoc/short-docblock-codeblock.rs6
-rw-r--r--src/test/rustdoc/short-docblock.rs25
-rw-r--r--src/test/rustdoc/short-dockblock.rs25
-rw-r--r--src/test/ui/anon-params/anon-params-deprecated.fixed6
-rw-r--r--src/test/ui/anon-params/anon-params-deprecated.rs6
-rw-r--r--src/test/ui/anon-params/anon-params-deprecated.stderr6
-rw-r--r--src/test/ui/asm/bad-options.stderr24
-rw-r--r--src/test/ui/asm/inline-syntax.arm.stderr12
-rw-r--r--src/test/ui/asm/inline-syntax.rs4
-rw-r--r--src/test/ui/asm/inline-syntax.x86_64.stderr14
-rw-r--r--src/test/ui/asm/issue-82869.rs (renamed from src/test/ui/issues/issue-82869.rs)0
-rw-r--r--src/test/ui/asm/issue-82869.stderr (renamed from src/test/ui/issues/issue-82869.stderr)0
-rw-r--r--src/test/ui/asm/parse-error.stderr20
-rw-r--r--src/test/ui/associated-types/issue-20005.rs (renamed from src/test/ui/issues/issue-20005.rs)0
-rw-r--r--src/test/ui/associated-types/issue-20005.stderr (renamed from src/test/ui/issues/issue-20005.stderr)0
-rw-r--r--src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs20
-rw-r--r--src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr20
-rw-r--r--src/test/ui/async-await/await-keyword/2015-edition-warning.fixed12
-rw-r--r--src/test/ui/async-await/await-keyword/2015-edition-warning.rs12
-rw-r--r--src/test/ui/async-await/await-keyword/2015-edition-warning.stderr12
-rw-r--r--src/test/ui/async-await/issue-84841.rs16
-rw-r--r--src/test/ui/async-await/issue-84841.stderr28
-rw-r--r--src/test/ui/borrowck/fsu-moves-and-copies.rs (renamed from src/test/ui/fsu-moves-and-copies.rs)0
-rw-r--r--src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs4
-rw-r--r--src/test/ui/cast/fat-ptr-cast-rpass.rs17
-rw-r--r--src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/by_value.rs8
-rw-r--r--src/test/ui/closures/2229_closure_analysis/by_value.stderr27
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr29
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr23
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr23
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr23
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.stderr21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.stderr21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-enums.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/capture-enums.stderr39
-rw-r--r--src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr25
-rw-r--r--src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr25
-rw-r--r--src/test/ui/closures/2229_closure_analysis/destructure_patterns.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/destructure_patterns.stderr53
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr25
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.rs3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.stderr13
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.rs3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.stderr13
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr13
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr15
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/box.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr17
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.stderr13
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.rs3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr15
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr13
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr15
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr15
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr15
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr15
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr13
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr15
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr13
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr13
-rw-r--r--src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/filter-on-struct-member.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/filter-on-struct-member.stderr19
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr9
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr60
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr12
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/issue-86753.rs34
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr10
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/precise.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr58
-rw-r--r--src/test/ui/closures/2229_closure_analysis/move_closure.rs40
-rw-r--r--src/test/ui/closures/2229_closure_analysis/move_closure.stderr159
-rw-r--r--src/test/ui/closures/2229_closure_analysis/multilevel-path-1.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/multilevel-path-1.stderr21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/multilevel-path-2.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/multilevel-path-2.stderr21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/nested-closure.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/nested-closure.stderr39
-rw-r--r--src/test/ui/closures/2229_closure_analysis/path-with-array-access.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/path-with-array-access.stderr21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.stderr27
-rw-r--r--src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.stderr55
-rw-r--r--src/test/ui/closures/2229_closure_analysis/repr_packed.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/repr_packed.stderr47
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/box.rs7
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/box.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/by_value.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/capture_with_wildcard_match.rs3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/capture_with_wildcard_match.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr17
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/destructure_patterns.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/destructure_patterns.stderr29
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.rs5
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.rs3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/tuple-struct-pattern-matching-with-methods.rs3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/tuple-struct-pattern-matching-with-methods.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs4
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/use_of_mutable_borrow_and_fake_reads.rs3
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/use_of_mutable_borrow_and_fake_reads.stderr11
-rw-r--r--src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr23
-rw-r--r--src/test/ui/closures/2229_closure_analysis/unsafe_ptr.rs7
-rw-r--r--src/test/ui/closures/2229_closure_analysis/unsafe_ptr.stderr31
-rw-r--r--src/test/ui/closures/2229_closure_analysis/wild_patterns.rs6
-rw-r--r--src/test/ui/closures/2229_closure_analysis/wild_patterns.stderr41
-rw-r--r--src/test/ui/cmse-nonsecure/cmse-nonsecure-call/params-on-registers.rs16
-rw-r--r--src/test/ui/cmse-nonsecure/cmse-nonsecure-call/params-on-stack.rs18
-rw-r--r--src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs8
-rw-r--r--src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr8
-rw-r--r--src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs8
-rw-r--r--src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr4
-rw-r--r--src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.rs9
-rw-r--r--src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.stderr11
-rw-r--r--src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs14
-rw-r--r--src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs16
-rw-r--r--src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs13
-rw-r--r--src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr4
-rw-r--r--src/test/ui/coercion/issue-37655.rs (renamed from src/test/ui/issues/issue-37655.rs)0
-rw-r--r--src/test/ui/conditional-compilation/test-cfg.rs (renamed from src/test/ui/test-cfg.rs)0
-rw-r--r--src/test/ui/conditional-compilation/test-cfg.stderr (renamed from src/test/ui/test-cfg.stderr)0
-rw-r--r--src/test/ui/const-generics/impl-trait-with-const-arguments.full.stderr1
-rw-r--r--src/test/ui/const-generics/impl-trait-with-const-arguments.min.stderr1
-rw-r--r--src/test/ui/const-generics/issues/issue-83765.rs38
-rw-r--r--src/test/ui/const-generics/issues/issue-83765.stderr29
-rw-r--r--src/test/ui/const-generics/issues/issue-85848.rs31
-rw-r--r--src/test/ui/const-generics/issues/issue-85848.stderr44
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr2
-rw-r--r--src/test/ui/const-ptr/out_of_bounds_read.rs16
-rw-r--r--src/test/ui/const-ptr/out_of_bounds_read.stderr70
-rw-r--r--src/test/ui/consts/const-eval/ub-upvars.32bit.stderr2
-rw-r--r--src/test/ui/consts/const-eval/ub-upvars.64bit.stderr2
-rw-r--r--src/test/ui/consts/const-float-classify.rs3
-rw-r--r--src/test/ui/consts/copy-intrinsic.rs51
-rw-r--r--src/test/ui/consts/copy-intrinsic.stderr27
-rw-r--r--src/test/ui/consts/issue-17756.rs (renamed from src/test/ui/issues/issue-17756.rs)0
-rw-r--r--src/test/ui/consts/issue-69532.rs (renamed from src/test/ui/issues/issue-69532.rs)0
-rw-r--r--src/test/ui/consts/issue-79690.64bit.stderr2
-rw-r--r--src/test/ui/consts/large_const_alloc.rs18
-rw-r--r--src/test/ui/consts/large_const_alloc.stderr15
-rw-r--r--src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr2
-rw-r--r--src/test/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr2
-rw-r--r--src/test/ui/crate-loading/missing-std.rs1
-rw-r--r--src/test/ui/crate-loading/missing-std.stderr2
-rw-r--r--src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed28
-rw-r--r--src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs28
-rw-r--r--src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr28
-rw-r--r--src/test/ui/dyn-keyword/dyn-2018-edition-lint.rs6
-rw-r--r--src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr6
-rw-r--r--src/test/ui/editions/edition-raw-pointer-method-2015.rs2
-rw-r--r--src/test/ui/editions/edition-raw-pointer-method-2015.stderr2
-rw-r--r--src/test/ui/extern/extern-main-issue-86110.rs7
-rw-r--r--src/test/ui/extern/extern-main-issue-86110.stderr8
-rw-r--r--src/test/ui/extern/extern-types-distinct-types.stderr2
-rw-r--r--src/test/ui/future-incompatible-lint-group.rs14
-rw-r--r--src/test/ui/future-incompatible-lint-group.stderr25
-rw-r--r--src/test/ui/generic-associated-types/collections-project-default.rs2
-rw-r--r--src/test/ui/generic-associated-types/collections.rs2
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs2
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-86483.rs15
-rw-r--r--src/test/ui/generic-associated-types/issue-86483.stderr36
-rw-r--r--src/test/ui/impl-trait/issues/universal-issue-48703.stderr1
-rw-r--r--src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr1
-rw-r--r--src/test/ui/inference/inference-variable-behind-raw-pointer.rs2
-rw-r--r--src/test/ui/inference/inference-variable-behind-raw-pointer.stderr2
-rw-r--r--src/test/ui/inference/issue-70703.rs26
-rw-r--r--src/test/ui/intrinsics/non-integer-atomic.rs (renamed from src/test/ui/non-integer-atomic.rs)0
-rw-r--r--src/test/ui/intrinsics/non-integer-atomic.stderr (renamed from src/test/ui/non-integer-atomic.stderr)0
-rw-r--r--src/test/ui/invalid-compile-flags/codegen-option-without-group.rs1
-rw-r--r--src/test/ui/invalid-compile-flags/codegen-option-without-group.stderr2
-rw-r--r--src/test/ui/invalid-compile-flags/debug-option-without-group.rs1
-rw-r--r--src/test/ui/invalid-compile-flags/debug-option-without-group.stderr2
-rw-r--r--src/test/ui/issues/issue-51714.rs16
-rw-r--r--src/test/ui/issues/issue-51714.stderr60
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-2018.rs12
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-2018.stderr58
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.fixed49
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.rs49
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.stderr304
-rw-r--r--src/test/ui/keyword/keyword-self-as-type-param.rs (renamed from src/test/ui/issues/issue-36638.rs)2
-rw-r--r--src/test/ui/keyword/keyword-self-as-type-param.stderr (renamed from src/test/ui/issues/issue-36638.stderr)6
-rw-r--r--src/test/ui/lint/bare-trait-objects-path.rs6
-rw-r--r--src/test/ui/lint/bare-trait-objects-path.stderr6
-rw-r--r--src/test/ui/lint/force-warn/force-allowed-by-default-lint.stderr2
-rw-r--r--src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.stderr2
-rw-r--r--src/test/ui/lint/force-warn/force-allowed-warning.stderr2
-rw-r--r--src/test/ui/lint/force-warn/force-deny-by-default-lint.stderr2
-rw-r--r--src/test/ui/lint/force-warn/force-lint-allow-all-warnings.stderr2
-rw-r--r--src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.stderr2
-rw-r--r--src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs2
-rw-r--r--src/test/ui/lint/force-warn/force-lint-in-allowed-group.stderr4
-rw-r--r--src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs2
-rw-r--r--src/test/ui/lint/force-warn/force-warn-group-allow-warning.stderr4
-rw-r--r--src/test/ui/lint/force-warn/force-warn-group.rs2
-rw-r--r--src/test/ui/lint/force-warn/force-warn-group.stderr4
-rw-r--r--src/test/ui/lint/inclusive-range-pattern-syntax.fixed4
-rw-r--r--src/test/ui/lint/inclusive-range-pattern-syntax.rs4
-rw-r--r--src/test/ui/lint/inclusive-range-pattern-syntax.stderr4
-rw-r--r--src/test/ui/lint/issue-78660-cap-lints-future-compat.rs10
-rw-r--r--src/test/ui/lint/issue-78660-cap-lints-future-compat.stderr11
-rw-r--r--src/test/ui/lint/lint-pre-expansion-extern-module.stderr2
-rw-r--r--src/test/ui/macros/auxiliary/or-pattern.rs6
-rw-r--r--src/test/ui/macros/issue-52169.rs (renamed from src/test/ui/issues/issue-52169.rs)0
-rw-r--r--src/test/ui/macros/macro-or-patterns-back-compat.fixed14
-rw-r--r--src/test/ui/macros/macro-or-patterns-back-compat.rs14
-rw-r--r--src/test/ui/macros/macro-or-patterns-back-compat.stderr18
-rw-r--r--src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.rs2
-rw-r--r--src/test/ui/nll/issue-24535-allow-mutable-borrow-in-match-guard.rs (renamed from src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs)0
-rw-r--r--src/test/ui/nll/issue-45157.rs (renamed from src/test/ui/issues/issue-45157.rs)0
-rw-r--r--src/test/ui/nll/issue-45157.stderr (renamed from src/test/ui/issues/issue-45157.stderr)0
-rw-r--r--src/test/ui/non-fmt-panic.stderr36
-rw-r--r--src/test/ui/nullable-pointer-iotareduction.rs2
-rw-r--r--src/test/ui/packed/issue-27060-2.rs (renamed from src/test/ui/issues/issue-27060-2.rs)0
-rw-r--r--src/test/ui/packed/issue-27060-2.stderr (renamed from src/test/ui/issues/issue-27060-2.stderr)0
-rw-r--r--src/test/ui/packed/issue-27060-rpass.rs (renamed from src/test/ui/issues/issue-27060-rpass.rs)0
-rw-r--r--src/test/ui/packed/issue-27060.rs (renamed from src/test/ui/issues/issue-27060.rs)0
-rw-r--r--src/test/ui/packed/issue-27060.stderr (renamed from src/test/ui/issues/issue-27060.stderr)0
-rw-r--r--src/test/ui/parser/issue-48636.fixed (renamed from src/test/ui/issues/issue-48636.fixed)0
-rw-r--r--src/test/ui/parser/issue-48636.rs (renamed from src/test/ui/issues/issue-48636.rs)0
-rw-r--r--src/test/ui/parser/issue-48636.stderr (renamed from src/test/ui/issues/issue-48636.stderr)0
-rw-r--r--src/test/ui/parser/issue-54521-1.rs (renamed from src/test/ui/issues/issue-54521-1.rs)0
-rw-r--r--src/test/ui/parser/issue-54521-2.fixed (renamed from src/test/ui/issues/issue-54521-2.fixed)0
-rw-r--r--src/test/ui/parser/issue-54521-2.rs (renamed from src/test/ui/issues/issue-54521-2.rs)0
-rw-r--r--src/test/ui/parser/issue-54521-2.stderr (renamed from src/test/ui/issues/issue-54521-2.stderr)0
-rw-r--r--src/test/ui/parser/issue-54521-3.fixed (renamed from src/test/ui/issues/issue-54521.fixed)0
-rw-r--r--src/test/ui/parser/issue-54521-3.rs (renamed from src/test/ui/issues/issue-54521.rs)0
-rw-r--r--src/test/ui/parser/issue-54521-3.stderr (renamed from src/test/ui/issues/issue-54521.stderr)8
-rw-r--r--src/test/ui/parser/issue-68890-2.rs2
-rw-r--r--src/test/ui/parser/issue-68890-2.stderr2
-rw-r--r--src/test/ui/parser/issue-73568-lifetime-after-mut.rs4
-rw-r--r--src/test/ui/parser/issue-73568-lifetime-after-mut.stderr4
-rw-r--r--src/test/ui/parser/macro/trait-object-macro-matcher.rs2
-rw-r--r--src/test/ui/parser/macro/trait-object-macro-matcher.stderr2
-rw-r--r--src/test/ui/parser/parser-unicode-whitespace.rs2
-rw-r--r--src/test/ui/parser/recover-range-pats.rs18
-rw-r--r--src/test/ui/parser/recover-range-pats.stderr18
-rw-r--r--src/test/ui/parser/trait-object-trait-parens.rs6
-rw-r--r--src/test/ui/parser/trait-object-trait-parens.stderr6
-rw-r--r--src/test/ui/process-termination/process-termination-blocking-io.rs2
-rw-r--r--src/test/ui/range/range-inclusive-pattern-precedence.fixed2
-rw-r--r--src/test/ui/range/range-inclusive-pattern-precedence.rs2
-rw-r--r--src/test/ui/range/range-inclusive-pattern-precedence.stderr2
-rw-r--r--src/test/ui/range/range-inclusive-pattern-precedence2.rs2
-rw-r--r--src/test/ui/range/range-inclusive-pattern-precedence2.stderr2
-rw-r--r--src/test/ui/repr/repr-transparent.rs32
-rw-r--r--src/test/ui/repr/repr-transparent.stderr82
-rw-r--r--src/test/ui/resolve/use_suggestion_placement.fixed39
-rw-r--r--src/test/ui/resolve/use_suggestion_placement.rs9
-rw-r--r--src/test/ui/resolve/use_suggestion_placement.stderr6
-rw-r--r--src/test/ui/retslot-cast.stderr3
-rw-r--r--src/test/ui/return/issue-86188-return-not-in-fn-body.rs41
-rw-r--r--src/test/ui/return/issue-86188-return-not-in-fn-body.stderr52
-rw-r--r--src/test/ui/return/return-match-array-const.rs15
-rw-r--r--src/test/ui/return/return-match-array-const.stderr55
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs22
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs22
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs3
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs3
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs3
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs3
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr9
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/cross-crate.rs22
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr15
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.rs20
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.stderr10
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/staged-api.rs39
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/staged-api.staged.stderr10
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/staged-api.stock.stderr18
-rw-r--r--src/test/ui/rust-2018/async-ident-allowed.rs2
-rw-r--r--src/test/ui/rust-2018/async-ident-allowed.stderr2
-rw-r--r--src/test/ui/rust-2018/async-ident.fixed30
-rw-r--r--src/test/ui/rust-2018/async-ident.rs30
-rw-r--r--src/test/ui/rust-2018/async-ident.stderr30
-rw-r--r--src/test/ui/rust-2018/dyn-keyword.fixed2
-rw-r--r--src/test/ui/rust-2018/dyn-keyword.rs2
-rw-r--r--src/test/ui/rust-2018/dyn-keyword.stderr2
-rw-r--r--src/test/ui/rust-2018/edition-lint-fully-qualified-paths.fixed7
-rw-r--r--src/test/ui/rust-2018/edition-lint-fully-qualified-paths.rs7
-rw-r--r--src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr8
-rw-r--r--src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed6
-rw-r--r--src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs6
-rw-r--r--src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr6
-rw-r--r--src/test/ui/rust-2018/edition-lint-nested-paths.fixed4
-rw-r--r--src/test/ui/rust-2018/edition-lint-nested-paths.rs4
-rw-r--r--src/test/ui/rust-2018/edition-lint-nested-paths.stderr4
-rw-r--r--src/test/ui/rust-2018/edition-lint-paths.fixed27
-rw-r--r--src/test/ui/rust-2018/edition-lint-paths.rs29
-rw-r--r--src/test/ui/rust-2018/edition-lint-paths.stderr32
-rw-r--r--src/test/ui/rust-2018/extern-crate-rename.fixed2
-rw-r--r--src/test/ui/rust-2018/extern-crate-rename.rs2
-rw-r--r--src/test/ui/rust-2018/extern-crate-rename.stderr2
-rw-r--r--src/test/ui/rust-2018/extern-crate-submod.fixed2
-rw-r--r--src/test/ui/rust-2018/extern-crate-submod.rs2
-rw-r--r--src/test/ui/rust-2018/extern-crate-submod.stderr2
-rw-r--r--src/test/ui/rust-2018/try-ident.fixed4
-rw-r--r--src/test/ui/rust-2018/try-ident.rs4
-rw-r--r--src/test/ui/rust-2018/try-ident.stderr4
-rw-r--r--src/test/ui/rust-2018/try-macro.fixed4
-rw-r--r--src/test/ui/rust-2018/try-macro.rs4
-rw-r--r--src/test/ui/rust-2018/try-macro.stderr2
-rw-r--r--src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2018.rs25
-rw-r--r--src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2021.rs25
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.fixed6
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.rs6
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.stderr6
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-unneeded.rs16
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision.fixed22
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision.rs22
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision.stderr32
-rw-r--r--src/test/ui/rust-2021/generic-type-collision.fixed2
-rw-r--r--src/test/ui/rust-2021/generic-type-collision.rs2
-rw-r--r--src/test/ui/rust-2021/generic-type-collision.stderr2
-rw-r--r--src/test/ui/rust-2021/inherent-dyn-collision.fixed2
-rw-r--r--src/test/ui/rust-2021/inherent-dyn-collision.rs2
-rw-r--r--src/test/ui/rust-2021/inherent-dyn-collision.stderr2
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-migration.fixed38
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-migration.rs38
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-migration.stderr72
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-via-macro-2.rs21
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-via-macro-2.stderr29
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-via-macro.rs12
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes.rs36
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes.stderr110
-rw-r--r--src/test/ui/sanitize/crt-static.rs1
-rw-r--r--src/test/ui/sanitize/incompatible.rs1
-rw-r--r--src/test/ui/sanitize/unsupported-target.rs1
-rw-r--r--src/test/ui/simd-intrinsic/issue-85855.rs19
-rw-r--r--src/test/ui/simd-intrinsic/issue-85855.stderr21
-rw-r--r--src/test/ui/suggestions/issue-61963.rs4
-rw-r--r--src/test/ui/suggestions/issue-61963.stderr4
-rw-r--r--src/test/ui/suggestions/issue-86667.rs16
-rw-r--r--src/test/ui/suggestions/issue-86667.stderr27
-rw-r--r--src/test/ui/suggestions/use-placement-resolve.fixed13
-rw-r--r--src/test/ui/suggestions/use-placement-resolve.rs11
-rw-r--r--src/test/ui/suggestions/use-placement-resolve.stderr14
-rw-r--r--src/test/ui/suggestions/use-placement-typeck.fixed22
-rw-r--r--src/test/ui/suggestions/use-placement-typeck.rs20
-rw-r--r--src/test/ui/suggestions/use-placement-typeck.stderr21
-rw-r--r--src/test/ui/synthetic-param.stderr1
-rw-r--r--src/test/ui/test-attrs/test-panic-abort-disabled.rs (renamed from src/test/ui/test-panic-abort-disabled.rs)0
-rw-r--r--src/test/ui/test-attrs/test-panic-abort-disabled.stderr (renamed from src/test/ui/test-panic-abort-disabled.stderr)0
-rw-r--r--src/test/ui/test-attrs/test-panic-abort-nocapture.rs (renamed from src/test/ui/test-panic-abort-nocapture.rs)0
-rw-r--r--src/test/ui/test-attrs/test-panic-abort-nocapture.run.stderr (renamed from src/test/ui/test-panic-abort-nocapture.run.stderr)0
-rw-r--r--src/test/ui/test-attrs/test-panic-abort-nocapture.run.stdout (renamed from src/test/ui/test-panic-abort-nocapture.run.stdout)0
-rw-r--r--src/test/ui/test-attrs/test-panic-abort.rs (renamed from src/test/ui/test-panic-abort.rs)0
-rw-r--r--src/test/ui/test-attrs/test-panic-abort.run.stdout (renamed from src/test/ui/test-panic-abort.run.stdout)0
-rw-r--r--src/test/ui/test-attrs/test-panic-while-printing.rs (renamed from src/test/ui/test-panic-while-printing.rs)0
-rw-r--r--src/test/ui/test-attrs/test-passed-wasm.rs (renamed from src/test/ui/test-passed-wasm.rs)0
-rw-r--r--src/test/ui/test-attrs/test-passed-wasm.run.stdout (renamed from src/test/ui/test-passed-wasm.run.stdout)0
-rw-r--r--src/test/ui/test-attrs/test-passed.rs (renamed from src/test/ui/test-passed.rs)0
-rw-r--r--src/test/ui/test-attrs/test-passed.run.stdout (renamed from src/test/ui/test-passed.run.stdout)0
-rw-r--r--src/test/ui/test-attrs/test-thread-capture.rs (renamed from src/test/ui/test-thread-capture.rs)0
-rw-r--r--src/test/ui/test-attrs/test-thread-capture.run.stdout (renamed from src/test/ui/test-thread-capture.run.stdout)0
-rw-r--r--src/test/ui/test-attrs/test-thread-nocapture.rs (renamed from src/test/ui/test-thread-nocapture.rs)0
-rw-r--r--src/test/ui/test-attrs/test-thread-nocapture.run.stderr (renamed from src/test/ui/test-thread-nocapture.run.stderr)0
-rw-r--r--src/test/ui/test-attrs/test-thread-nocapture.run.stdout (renamed from src/test/ui/test-thread-nocapture.run.stdout)0
-rw-r--r--src/test/ui/thread-local-static.rs1
-rw-r--r--src/test/ui/thread-local-static.stderr10
-rw-r--r--src/test/ui/traits/bound/not-on-bare-trait.rs2
-rw-r--r--src/test/ui/traits/bound/not-on-bare-trait.stderr2
-rw-r--r--src/test/ui/traits/issue-83538-tainted-cache-after-cycle.rs18
-rw-r--r--src/test/ui/traits/issue-83538-tainted-cache-after-cycle.stderr12
-rw-r--r--src/test/ui/traits/reservation-impl/non-lattice-ok.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-65384.rs16
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-65384.stderr14
-rw-r--r--src/test/ui/typeck/conversion-methods.rs (renamed from src/test/ui/conversion-methods.rs)0
-rw-r--r--src/test/ui/typeck/conversion-methods.stderr (renamed from src/test/ui/conversion-methods.stderr)0
-rw-r--r--src/test/ui/typeck/issue-84160.rs9
-rw-r--r--src/test/ui/typeck/issue-84160.stderr15
-rw-r--r--src/test/ui/typeck/issue-86721-return-expr-ice.rev1.stderr9
-rw-r--r--src/test/ui/typeck/issue-86721-return-expr-ice.rev2.stderr9
-rw-r--r--src/test/ui/typeck/issue-86721-return-expr-ice.rs17
-rw-r--r--src/test/ui/unpretty-expr-fn-arg.rs13
-rw-r--r--src/test/ui/unpretty-expr-fn-arg.stdout17
-rw-r--r--src/test/ui/unsized/unsized3-rpass.rs25
-rw-r--r--src/test/ui/unused/unused-doc-comments-edge-cases.rs29
-rw-r--r--src/test/ui/unused/unused-doc-comments-edge-cases.stderr61
-rw-r--r--src/test/ui/unused/useless-comment.stderr16
-rw-r--r--src/test/ui/wait-forked-but-failed-child.rs2
-rw-r--r--src/test/ui/write-fmt-errors.rs4
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/.github/workflows/clippy.yml2
-rw-r--r--src/tools/clippy/.github/workflows/clippy_bors.yml7
-rw-r--r--src/tools/clippy/.github/workflows/remark.yml2
-rw-r--r--src/tools/clippy/.remarkrc1
-rw-r--r--src/tools/clippy/CHANGELOG.md139
-rw-r--r--src/tools/clippy/CONTRIBUTING.md2
-rw-r--r--src/tools/clippy/Cargo.toml2
-rw-r--r--src/tools/clippy/README.md26
-rw-r--r--src/tools/clippy/clippy_dev/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_dev/src/fmt.rs8
-rw-r--r--src/tools/clippy/clippy_dev/src/ide_setup.rs103
-rw-r--r--src/tools/clippy/clippy_dev/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/main.rs81
-rw-r--r--src/tools/clippy/clippy_dev/src/setup/git_hook.rs85
-rw-r--r--src/tools/clippy/clippy_dev/src/setup/intellij.rs223
-rw-r--r--src/tools/clippy/clippy_dev/src/setup/mod.rs23
-rw-r--r--src/tools/clippy/clippy_dev/src/setup/vscode.rs104
-rw-r--r--src/tools/clippy/clippy_dev/src/update_lints.rs5
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml3
-rw-r--r--src/tools/clippy/clippy_lints/src/assign_ops.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/blacklisted_name.rs31
-rw-r--r--src/tools/clippy/clippy_lints/src/bytecount.rs70
-rw-r--r--src/tools/clippy/clippy_lints/src/collapsible_match.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/default.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/deprecated_lints.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_method.rs29
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs112
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_type.rs126
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs64
-rw-r--r--src/tools/clippy/clippy_lints/src/eval_order_dependence.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/formatting.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/get_last_with_len.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/if_let_mutex.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs82
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mod.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/needless_collect.rs97
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_map.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/map_identity.rs126
-rw-r--r--src/tools/clippy/clippy_lints/src/matches.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/append_instead_of_extend.rs41
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs40
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/flat_map_identity.rs44
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_identity.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs65
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs102
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_key.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs276
-rw-r--r--src/tools/clippy/clippy_lints/src/ranges.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_clone.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs363
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/conf.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs40
-rw-r--r--src/tools/clippy/clippy_lints/src/wildcard_imports.rs12
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs11
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs5
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs108
-rw-r--r--src/tools/clippy/clippy_utils/src/ptr.rs32
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs4
-rw-r--r--src/tools/clippy/doc/basics.md4
-rw-r--r--src/tools/clippy/doc/common_tools_writing_lints.md2
-rw-r--r--src/tools/clippy/doc/release.md15
-rw-r--r--src/tools/clippy/lintcheck/README.md2
-rw-r--r--src/tools/clippy/lintcheck/src/main.rs9
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/src/main.rs26
-rw-r--r--src/tools/clippy/tests/compile-test.rs19
-rw-r--r--src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/clippy.toml10
-rw-r--r--src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs16
-rw-r--r--src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr40
-rw-r--r--src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/clippy.toml6
-rw-r--r--src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs44
-rw-r--r--src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr94
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallowed_method/clippy.toml6
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallowed_type/clippy.toml9
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.rs35
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.stderr88
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr2
-rw-r--r--src/tools/clippy/tests/ui/append_instead_of_extend.fixed55
-rw-r--r--src/tools/clippy/tests/ui/append_instead_of_extend.rs55
-rw-r--r--src/tools/clippy/tests/ui/append_instead_of_extend.stderr22
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_constants.rs3
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/macro_rules.rs7
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/non-exhaustive-enum.rs8
-rw-r--r--src/tools/clippy/tests/ui/blacklisted_name.rs12
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3969.stderr6
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback.rs23
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback.stderr61
-rw-r--r--src/tools/clippy/tests/ui/deprecated.stderr4
-rw-r--r--src/tools/clippy/tests/ui/disallowed_script_idents.rs10
-rw-r--r--src/tools/clippy/tests/ui/disallowed_script_idents.stderr20
-rw-r--r--src/tools/clippy/tests/ui/doc/doc.rs (renamed from src/tools/clippy/tests/ui/doc.rs)2
-rw-r--r--src/tools/clippy/tests/ui/doc/doc.stderr (renamed from src/tools/clippy/tests/ui/doc.stderr)0
-rw-r--r--src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs36
-rw-r--r--src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr64
-rw-r--r--src/tools/clippy/tests/ui/field_reassign_with_default.rs20
-rw-r--r--src/tools/clippy/tests/ui/field_reassign_with_default.stderr36
-rw-r--r--src/tools/clippy/tests/ui/filter_map_identity.fixed5
-rw-r--r--src/tools/clippy/tests/ui/filter_map_identity.rs5
-rw-r--r--src/tools/clippy/tests/ui/filter_map_identity.stderr14
-rw-r--r--src/tools/clippy/tests/ui/flat_map_identity.fixed5
-rw-r--r--src/tools/clippy/tests/ui/flat_map_identity.rs5
-rw-r--r--src/tools/clippy/tests/ui/flat_map_identity.stderr12
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms.stderr7
-rw-r--r--src/tools/clippy/tests/ui/match_same_arms2.stderr7
-rw-r--r--src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed7
-rw-r--r--src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs7
-rw-r--r--src/tools/clippy/tests/ui/mut_key.stderr2
-rw-r--r--src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs44
-rw-r--r--src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr14
-rw-r--r--src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/use_self.fixed23
-rw-r--r--src/tools/clippy/tests/ui/use_self.rs25
-rw-r--r--src/tools/clippy/tests/ui/use_self.stderr4
-rw-r--r--src/tools/clippy/tests/ui/vec.fixed2
-rw-r--r--src/tools/clippy/tests/ui/vec.rs2
-rw-r--r--src/tools/clippy/tests/ui/while_let_on_iterator.fixed14
-rw-r--r--src/tools/clippy/tests/ui/while_let_on_iterator.rs14
-rw-r--r--src/tools/clippy/tests/ui/while_let_on_iterator.stderr10
-rw-r--r--src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed39
-rw-r--r--src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs37
-rw-r--r--src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr22
-rw-r--r--src/tools/clippy/tests/ui/zero_offset.rs20
-rw-r--r--src/tools/clippy/tests/ui/zero_offset.stderr55
-rwxr-xr-xsrc/tools/clippy/util/etc/pre-commit.sh21
-rw-r--r--src/tools/clippy/util/etc/vscode-tasks.json57
-rw-r--r--src/tools/clippy/util/lintlib.py5
-rw-r--r--src/tools/compiletest/src/header.rs460
-rw-r--r--src/tools/compiletest/src/header/tests.rs113
-rw-r--r--src/tools/compiletest/src/main.rs64
-rw-r--r--src/tools/compiletest/src/runtest.rs26
-rw-r--r--src/tools/html-checker/Cargo.toml12
-rw-r--r--src/tools/html-checker/main.rs93
m---------src/tools/miri18
m---------src/tools/rust-analyzer36
-rw-r--r--src/tools/rustc-workspace-hack/Cargo.toml2
-rw-r--r--src/tools/rustfmt/src/lib.rs1
-rw-r--r--src/tools/tidy/src/features.rs1
-rw-r--r--src/tools/tidy/src/lib.rs1
-rw-r--r--src/tools/tidy/src/main.rs2
-rw-r--r--src/tools/tidy/src/style.rs1
-rw-r--r--src/tools/tidy/src/target_specific_tests.rs96
-rw-r--r--src/tools/tidy/src/ui_tests.rs4
772 files changed, 9676 insertions, 4538 deletions
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 7c7f162b82c..7fd6b7d1609 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -77,7 +77,7 @@ def download(path, url, probably_big, verbose):
 def _download(path, url, probably_big, verbose, exception):
     if probably_big or verbose:
         print("downloading {}".format(url))
-    # see http://serverfault.com/questions/301128/how-to-download
+    # see https://serverfault.com/questions/301128/how-to-download
     if sys.platform == 'win32':
         run(["PowerShell.exe", "/nologo", "-Command",
              "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;",
@@ -993,28 +993,20 @@ class RustBuild(object):
         ).decode(default_encoding).splitlines()]
         filtered_submodules = []
         submodules_names = []
-        llvm_checked_out = os.path.exists(os.path.join(self.rust_root, "src/llvm-project/.git"))
-        external_llvm_provided = self.get_toml('llvm-config') or self.downloading_llvm()
-        llvm_needed = not self.get_toml('codegen-backends', 'rust') \
-            or "llvm" in self.get_toml('codegen-backends', 'rust')
         for module in submodules:
+            # This is handled by native::Llvm in rustbuild, not here
             if module.endswith("llvm-project"):
-                # Don't sync the llvm-project submodule if an external LLVM was
-                # provided, if we are downloading LLVM or if the LLVM backend is
-                # not being built. Also, if the submodule has been initialized
-                # already, sync it anyways so that it doesn't mess up contributor
-                # pull requests.
-                if external_llvm_provided or not llvm_needed:
-                    if self.get_toml('lld') != 'true' and not llvm_checked_out:
-                        continue
+                continue
             check = self.check_submodule(module, slow_submodules)
             filtered_submodules.append((module, check))
             submodules_names.append(module)
         recorded = subprocess.Popen(["git", "ls-tree", "HEAD"] + submodules_names,
                                     cwd=self.rust_root, stdout=subprocess.PIPE)
         recorded = recorded.communicate()[0].decode(default_encoding).strip().splitlines()
+        # { filename: hash }
         recorded_submodules = {}
         for data in recorded:
+            # [mode, kind, hash, filename]
             data = data.split()
             recorded_submodules[data[3]] = data[2]
         for module in filtered_submodules:
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index e2f605257bd..56ecc6e68a9 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -450,6 +450,7 @@ impl<'a> Builder<'a> {
                 test::RustdocTheme,
                 test::RustdocUi,
                 test::RustdocJson,
+                test::HtmlCheck,
                 // Run bootstrap close to the end as it's unlikely to fail
                 test::Bootstrap,
                 // Run run-make last, since these won't pass without make on Windows
@@ -464,6 +465,7 @@ impl<'a> Builder<'a> {
                 doc::Std,
                 doc::Rustc,
                 doc::Rustdoc,
+                doc::Rustfmt,
                 doc::ErrorIndex,
                 doc::Nomicon,
                 doc::Reference,
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 71ed0af4a7c..92853378e58 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -400,12 +400,12 @@ impl Step for Rustc {
 
             // Copy over lld if it's there
             if builder.config.lld_enabled {
-                let exe = exe("rust-lld", compiler.host);
-                builder.copy(&src_dir.join(&exe), &dst_dir.join(&exe));
+                let rust_lld = exe("rust-lld", compiler.host);
+                builder.copy(&src_dir.join(&rust_lld), &dst_dir.join(&rust_lld));
                 // for `-Z gcc-ld=lld`
                 let gcc_lld_dir = dst_dir.join("gcc-ld");
                 t!(fs::create_dir(&gcc_lld_dir));
-                builder.copy(&src_dir.join(&exe), &gcc_lld_dir.join(&exe));
+                builder.copy(&src_dir.join(&rust_lld), &gcc_lld_dir.join(exe("ld", compiler.host)));
             }
 
             // Copy over llvm-dwp if it's there
@@ -1072,6 +1072,12 @@ impl Step for RustAnalyzer {
     }
 
     fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
+        // This prevents rust-analyzer from being built for "dist" or "install"
+        // on the stable/beta channels. It is a nightly-only tool and should
+        // not be included.
+        if !builder.build.unstable_features() {
+            return None;
+        }
         let compiler = self.compiler;
         let target = self.target;
         assert!(builder.config.extended);
@@ -1171,6 +1177,12 @@ impl Step for Miri {
     }
 
     fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
+        // This prevents miri from being built for "dist" or "install"
+        // on the stable/beta channels. It is a nightly-only tool and should
+        // not be included.
+        if !builder.build.unstable_features() {
+            return None;
+        }
         let compiler = self.compiler;
         let target = self.target;
         assert!(builder.config.extended);
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index d2fabf9967f..8603361362c 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -501,8 +501,8 @@ impl Step for Std {
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct Rustc {
-    stage: u32,
-    target: TargetSelection,
+    pub stage: u32,
+    pub target: TargetSelection,
 }
 
 impl Step for Rustc {
@@ -593,84 +593,97 @@ impl Step for Rustc {
     }
 }
 
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
-pub struct Rustdoc {
-    stage: u32,
-    target: TargetSelection,
-}
-
-impl Step for Rustdoc {
-    type Output = ();
-    const DEFAULT: bool = true;
-    const ONLY_HOSTS: bool = true;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.krate("rustdoc-tool")
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Rustdoc { stage: run.builder.top_stage, target: run.target });
-    }
-
-    /// Generates compiler documentation.
-    ///
-    /// This will generate all documentation for compiler and dependencies.
-    /// Compiler documentation is distributed separately, so we make sure
-    /// we do not merge it with the other documentation from std, test and
-    /// proc_macros. This is largely just a wrapper around `cargo doc`.
-    fn run(self, builder: &Builder<'_>) {
-        let stage = self.stage;
-        let target = self.target;
-        builder.info(&format!("Documenting stage{} rustdoc ({})", stage, target));
-
-        // This is the intended out directory for compiler documentation.
-        let out = builder.compiler_doc_out(target);
-        t!(fs::create_dir_all(&out));
+macro_rules! tool_doc {
+    ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?] $(, binary=$bin:expr)?) => {
+        #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+        pub struct $tool {
+            stage: u32,
+            target: TargetSelection,
+        }
 
-        let compiler = builder.compiler(stage, builder.config.build);
+        impl Step for $tool {
+            type Output = ();
+            const DEFAULT: bool = true;
+            const ONLY_HOSTS: bool = true;
 
-        if !builder.config.compiler_docs {
-            builder.info("\tskipping - compiler/librustdoc docs disabled");
-            return;
-        }
+            fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+                run.krate($should_run)
+            }
 
-        // Build rustc docs so that we generate relative links.
-        builder.ensure(Rustc { stage, target });
+            fn make_run(run: RunConfig<'_>) {
+                run.builder.ensure($tool { stage: run.builder.top_stage, target: run.target });
+            }
 
-        // Build rustdoc.
-        builder.ensure(tool::Rustdoc { compiler });
+            /// Generates compiler documentation.
+            ///
+            /// This will generate all documentation for compiler and dependencies.
+            /// Compiler documentation is distributed separately, so we make sure
+            /// we do not merge it with the other documentation from std, test and
+            /// proc_macros. This is largely just a wrapper around `cargo doc`.
+            fn run(self, builder: &Builder<'_>) {
+                let stage = self.stage;
+                let target = self.target;
+                builder.info(&format!("Documenting stage{} {} ({})", stage, stringify!($tool).to_lowercase(), target));
 
-        // Symlink compiler docs to the output directory of rustdoc documentation.
-        let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target.triple).join("doc");
-        t!(fs::create_dir_all(&out_dir));
-        t!(symlink_dir_force(&builder.config, &out, &out_dir));
+                // This is the intended out directory for compiler documentation.
+                let out = builder.compiler_doc_out(target);
+                t!(fs::create_dir_all(&out));
 
-        // Build cargo command.
-        let mut cargo = prepare_tool_cargo(
-            builder,
-            compiler,
-            Mode::ToolRustc,
-            target,
-            "doc",
-            "src/tools/rustdoc",
-            SourceType::InTree,
-            &[],
-        );
+                let compiler = builder.compiler(stage, builder.config.build);
 
-        cargo.arg("-Zskip-rustdoc-fingerprint");
-        // Only include compiler crates, no dependencies of those, such as `libc`.
-        cargo.arg("--no-deps");
-        cargo.arg("-p").arg("rustdoc");
-        cargo.arg("-p").arg("rustdoc-json-types");
+                if !builder.config.compiler_docs {
+                    builder.info("\tskipping - compiler/tool docs disabled");
+                    return;
+                }
 
-        cargo.rustdocflag("--document-private-items");
-        cargo.rustdocflag("--enable-index-page");
-        cargo.rustdocflag("--show-type-layout");
-        cargo.rustdocflag("-Zunstable-options");
-        builder.run(&mut cargo.into());
+                // Build rustc docs so that we generate relative links.
+                builder.ensure(Rustc { stage, target });
+
+                // Symlink compiler docs to the output directory of rustdoc documentation.
+                let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target.triple).join("doc");
+                t!(fs::create_dir_all(&out_dir));
+                t!(symlink_dir_force(&builder.config, &out, &out_dir));
+
+                // Build cargo command.
+                let mut cargo = prepare_tool_cargo(
+                    builder,
+                    compiler,
+                    Mode::ToolRustc,
+                    target,
+                    "doc",
+                    $path,
+                    SourceType::InTree,
+                    &[],
+                );
+
+                cargo.arg("-Zskip-rustdoc-fingerprint");
+                // Only include compiler crates, no dependencies of those, such as `libc`.
+                cargo.arg("--no-deps");
+                $(
+                    cargo.arg("-p").arg($krate);
+                )+
+
+                $(if !$bin {
+                    cargo.rustdocflag("--document-private-items");
+                })?
+                cargo.rustdocflag("--enable-index-page");
+                cargo.rustdocflag("--show-type-layout");
+                cargo.rustdocflag("-Zunstable-options");
+                builder.run(&mut cargo.into());
+            }
+        }
     }
 }
 
+tool_doc!(Rustdoc, "rustdoc-tool", "src/tools/rustdoc", ["rustdoc", "rustdoc-json-types"]);
+tool_doc!(
+    Rustfmt,
+    "rustfmt-nightly",
+    "src/tools/rustfmt",
+    ["rustfmt-nightly", "rustfmt-config_proc_macro"],
+    binary = true
+);
+
 #[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct ErrorIndex {
     pub target: TargetSelection,
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 347236c655a..69c5de0b408 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -483,6 +483,12 @@ impl Build {
             job::setup(self);
         }
 
+        // If the LLVM submodule has been initialized already, sync it unconditionally. This avoids
+        // contributors checking in a submodule change by accident.
+        if self.in_tree_llvm_info.is_git() {
+            native::update_llvm_submodule(self);
+        }
+
         if let Subcommand::Format { check, paths } = &self.config.cmd {
             return format::format(self, *check, &paths);
         }
@@ -857,7 +863,7 @@ impl Build {
         }
 
         // Work around an apparently bad MinGW / GCC optimization,
-        // See: http://lists.llvm.org/pipermail/cfe-dev/2016-December/051980.html
+        // See: https://lists.llvm.org/pipermail/cfe-dev/2016-December/051980.html
         // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78936
         if &*target.triple == "i686-pc-windows-gnu" {
             base.push("-fno-omit-frame-pointer".into());
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 449fdb87b02..b967b6dbd2d 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -21,7 +21,7 @@ use build_helper::{output, t};
 use crate::builder::{Builder, RunConfig, ShouldRun, Step};
 use crate::config::TargetSelection;
 use crate::util::{self, exe};
-use crate::GitRepo;
+use crate::{Build, GitRepo};
 use build_helper::up_to_date;
 
 pub struct Meta {
@@ -91,6 +91,82 @@ pub fn prebuilt_llvm_config(
     Err(Meta { stamp, build_llvm_config, out_dir, root: root.into() })
 }
 
+// modified from `check_submodule` and `update_submodule` in bootstrap.py
+pub(crate) fn update_llvm_submodule(build: &Build) {
+    let llvm_project = &Path::new("src").join("llvm-project");
+
+    fn dir_is_empty(dir: &Path) -> bool {
+        t!(std::fs::read_dir(dir)).next().is_none()
+    }
+
+    // NOTE: The check for the empty directory is here because when running x.py
+    // the first time, the llvm submodule won't be checked out. Check it out
+    // now so we can build it.
+    if !build.in_tree_llvm_info.is_git() && !dir_is_empty(&build.config.src.join(llvm_project)) {
+        return;
+    }
+
+    // check_submodule
+    if build.config.fast_submodules {
+        let checked_out_hash = output(
+            Command::new("git")
+                .args(&["rev-parse", "HEAD"])
+                .current_dir(build.config.src.join(llvm_project)),
+        );
+        // update_submodules
+        let recorded = output(
+            Command::new("git")
+                .args(&["ls-tree", "HEAD"])
+                .arg(llvm_project)
+                .current_dir(&build.config.src),
+        );
+        let actual_hash = recorded
+            .split_whitespace()
+            .nth(2)
+            .unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
+
+        // update_submodule
+        if actual_hash == checked_out_hash.trim_end() {
+            // already checked out
+            return;
+        }
+    }
+
+    println!("Updating submodule {}", llvm_project.display());
+    build.run(
+        Command::new("git")
+            .args(&["submodule", "-q", "sync"])
+            .arg(llvm_project)
+            .current_dir(&build.config.src),
+    );
+
+    // Try passing `--progress` to start, then run git again without if that fails.
+    let update = |progress: bool| {
+        let mut git = Command::new("git");
+        git.args(&["submodule", "update", "--init", "--recursive"]);
+        if progress {
+            git.arg("--progress");
+        }
+        git.arg(llvm_project).current_dir(&build.config.src);
+        git
+    };
+    // NOTE: doesn't use `try_run` because this shouldn't print an error if it fails.
+    if !update(true).status().map_or(false, |status| status.success()) {
+        build.run(&mut update(false));
+    }
+
+    build.run(
+        Command::new("git")
+            .args(&["reset", "-q", "--hard"])
+            .current_dir(build.config.src.join(llvm_project)),
+    );
+    build.run(
+        Command::new("git")
+            .args(&["clean", "-qdfx"])
+            .current_dir(build.config.src.join(llvm_project)),
+    );
+}
+
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct Llvm {
     pub target: TargetSelection,
@@ -128,6 +204,9 @@ impl Step for Llvm {
                 Err(m) => m,
             };
 
+        if !builder.config.dry_run {
+            update_llvm_submodule(builder);
+        }
         if builder.config.llvm_link_shared
             && (target.contains("windows") || target.contains("apple-darwin"))
         {
@@ -139,7 +218,7 @@ impl Step for Llvm {
         let _time = util::timeit(&builder);
         t!(fs::create_dir_all(&out_dir));
 
-        // http://llvm.org/docs/CMake.html
+        // https://llvm.org/docs/CMake.html
         let mut cfg = cmake::Config::new(builder.src.join(root));
 
         let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) {
@@ -276,7 +355,7 @@ impl Step for Llvm {
             }
         }
 
-        // http://llvm.org/docs/HowToCrossCompileLLVM.html
+        // https://llvm.org/docs/HowToCrossCompileLLVM.html
         if target != builder.config.build {
             builder.ensure(Llvm { target: builder.config.build });
             // FIXME: if the llvm root for the build triple is overridden then we
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 92ac3b364f6..64b3ee7c359 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -9,7 +9,7 @@ use std::fmt;
 use std::fs;
 use std::iter;
 use std::path::{Path, PathBuf};
-use std::process::Command;
+use std::process::{Command, Stdio};
 
 use build_helper::{self, output, t};
 
@@ -161,6 +161,49 @@ You can skip linkcheck with --exclude src/tools/linkchecker"
     }
 }
 
+fn check_if_tidy_is_installed() -> bool {
+    Command::new("tidy")
+        .arg("--version")
+        .stdout(Stdio::null())
+        .status()
+        .map_or(false, |status| status.success())
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct HtmlCheck {
+    target: TargetSelection,
+}
+
+impl Step for HtmlCheck {
+    type Output = ();
+    const DEFAULT: bool = true;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        let run = run.path("src/tools/html-checker");
+        run.lazy_default_condition(Box::new(check_if_tidy_is_installed))
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(HtmlCheck { target: run.target });
+    }
+
+    fn run(self, builder: &Builder<'_>) {
+        if !check_if_tidy_is_installed() {
+            eprintln!("not running HTML-check tool because `tidy` is missing");
+            eprintln!(
+                "Note that `tidy` is not the in-tree `src/tools/tidy` but needs to be installed"
+            );
+            panic!("Cannot run html-check tests");
+        }
+        // Ensure that a few different kinds of documentation are available.
+        builder.default_doc(&[]);
+        builder.ensure(crate::doc::Rustc { target: self.target, stage: builder.top_stage });
+
+        try_run(builder, builder.tool_cmd(Tool::HtmlChecker).arg(builder.doc_out(self.target)));
+    }
+}
+
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Cargotest {
     stage: u32,
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 9d75ad0918a..aa7fe658df3 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -376,6 +376,7 @@ bootstrap_tool!(
     ExpandYamlAnchors, "src/tools/expand-yaml-anchors", "expand-yaml-anchors";
     LintDocs, "src/tools/lint-docs", "lint-docs";
     JsonDocCk, "src/tools/jsondocck", "jsondocck";
+    HtmlChecker, "src/tools/html-checker", "html-checker";
 );
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs
index 80f804174ed..b1ec072f3f8 100644
--- a/src/build_helper/lib.rs
+++ b/src/build_helper/lib.rs
@@ -130,6 +130,7 @@ pub fn make(host: &str) -> PathBuf {
     }
 }
 
+#[track_caller]
 pub fn output(cmd: &mut Command) -> String {
     let output = match cmd.stderr(Stdio::inherit()).output() {
         Ok(status) => status,
diff --git a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
index 8a91859379b..e2dbc7cfd7c 100644
--- a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
+++ b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
@@ -58,7 +58,7 @@ RUN curl https://www.busybox.net/downloads/busybox-1.32.1.tar.bz2 | tar xjf - &&
 # Download the ubuntu rootfs, which we'll use as a chroot for all our tests.
 WORKDIR /tmp
 RUN mkdir rootfs/ubuntu
-RUN curl http://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.1-base-armhf.tar.gz | \
+RUN curl https://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.1-base-armhf.tar.gz | \
       tar xzf - -C rootfs/ubuntu && \
       cd rootfs && mkdir proc sys dev etc etc/init.d
 
diff --git a/src/ci/docker/host-x86_64/disabled/dist-x86_64-dragonfly/build-toolchain.sh b/src/ci/docker/host-x86_64/disabled/dist-x86_64-dragonfly/build-toolchain.sh
index 409bca45c94..b305f358c5a 100755
--- a/src/ci/docker/host-x86_64/disabled/dist-x86_64-dragonfly/build-toolchain.sh
+++ b/src/ci/docker/host-x86_64/disabled/dist-x86_64-dragonfly/build-toolchain.sh
@@ -39,7 +39,7 @@ rm -rf binutils
 
 # Next, download the DragonFly libc and relevant header files
 
-URL=http://mirror-master.dragonflybsd.org/iso-images/dfly-x86_64-5.0.0_REL.iso.bz2
+URL=https://mirror-master.dragonflybsd.org/iso-images/dfly-x86_64-5.0.0_REL.iso.bz2
 mkdir dragonfly
 curl $URL | bzcat | bsdtar xf - -C dragonfly ./usr/include ./usr/lib ./lib
 
diff --git a/src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.config b/src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.config
index 66709a4004c..acdf9a0e041 100644
--- a/src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.config
+++ b/src/ci/docker/host-x86_64/dist-arm-linux/arm-linux-gnueabi.config
@@ -711,7 +711,7 @@ CT_ZLIB_PATCH_ORDER="global"
 CT_ZLIB_V_1_2_11=y
 # CT_ZLIB_NO_VERSIONS is not set
 CT_ZLIB_VERSION="1.2.11"
-CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
+CT_ZLIB_MIRRORS="https://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
 CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
 CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
 CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz"
diff --git a/src/ci/docker/host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.config b/src/ci/docker/host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.config
index a3dcff1c936..69f86663ec2 100644
--- a/src/ci/docker/host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.config
+++ b/src/ci/docker/host-x86_64/dist-armhf-linux/arm-linux-gnueabihf.config
@@ -725,7 +725,7 @@ CT_ZLIB_PATCH_ORDER="global"
 CT_ZLIB_V_1_2_11=y
 # CT_ZLIB_NO_VERSIONS is not set
 CT_ZLIB_VERSION="1.2.11"
-CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
+CT_ZLIB_MIRRORS="https://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
 CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
 CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
 CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz"
diff --git a/src/ci/docker/host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.config b/src/ci/docker/host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.config
index 81b3d7477ec..e3d032fc7e8 100644
--- a/src/ci/docker/host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.config
+++ b/src/ci/docker/host-x86_64/dist-armv7-linux/armv7-linux-gnueabihf.config
@@ -671,7 +671,7 @@ CT_MPFR_PATCH_ORDER="global"
 CT_MPFR_V_3_1=y
 # CT_MPFR_NO_VERSIONS is not set
 CT_MPFR_VERSION="3.1.6"
-CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)"
+CT_MPFR_MIRRORS="https://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)"
 CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
 CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
 CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip"
@@ -711,7 +711,7 @@ CT_ZLIB_PATCH_ORDER="global"
 CT_ZLIB_V_1_2_11=y
 # CT_ZLIB_NO_VERSIONS is not set
 CT_ZLIB_VERSION="1.2.11"
-CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
+CT_ZLIB_MIRRORS="https://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
 CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
 CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
 CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz"
diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config b/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config
index ffb2e9195b1..45d5ff756cd 100644
--- a/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config
+++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.config
@@ -645,7 +645,8 @@ CT_EXPAT_PATCH_ORDER="global"
 CT_EXPAT_V_2_2=y
 # CT_EXPAT_NO_VERSIONS is not set
 CT_EXPAT_VERSION="2.4.1"
-CT_EXPAT_MIRRORS="http://downloads.sourceforge.net/project/expat/expat/${CT_EXPAT_VERSION}"
+CT_EXPAT_VERSION_TAG="2_4_1"
+CT_EXPAT_MIRRORS="https://github.com/libexpat/libexpat/releases/download/R_${CT_EXPAT_VERSION_TAG}"
 CT_EXPAT_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
 CT_EXPAT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
 CT_EXPAT_ARCHIVE_FORMATS=".tar.bz2"
@@ -862,7 +863,7 @@ CT_ZLIB_PATCH_ORDER="global"
 CT_ZLIB_V_1_2_11=y
 # CT_ZLIB_NO_VERSIONS is not set
 CT_ZLIB_VERSION="1.2.11"
-CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
+CT_ZLIB_MIRRORS="https://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
 CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
 CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
 CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz"
diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
index b7f181adf2a..e363c4f79f9 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -27,7 +27,7 @@ RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no
   g++-8-arm-linux-gnueabi
 
 RUN apt-key adv --batch --yes --keyserver keyserver.ubuntu.com --recv-keys 74DA7924C5513486
-RUN add-apt-repository -y 'deb http://apt.dilos.org/dilos dilos2 main'
+RUN add-apt-repository -y 'deb https://apt.dilos.org/dilos dilos2 main'
 
 ENV \
     AR_x86_64_fuchsia=x86_64-fuchsia-ar \
diff --git a/src/ci/docker/host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh b/src/ci/docker/host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh
index f7acedcfb47..eabff87284d 100755
--- a/src/ci/docker/host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh
+++ b/src/ci/docker/host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh
@@ -7,7 +7,7 @@ target="x86_64-fortanix-unknown-sgx"
 
 install_prereq() {
     curl https://apt.llvm.org/llvm-snapshot.gpg.key|apt-key add -
-    add-apt-repository -y 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main'
+    add-apt-repository -y 'deb https://apt.llvm.org/focal/ llvm-toolchain-focal-11 main'
     apt-get update
     apt-get install -y --no-install-recommends \
             build-essential \
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh
index fcf869b68be..25f99596099 100755
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh
@@ -22,6 +22,7 @@ cd gcc-$GCC
 # latter host is presented to `wget`! Therefore, we choose to download from the insecure HTTP server
 # instead here.
 #
+# FIXME: use HTTPS (see https://github.com/rust-lang/rust/pull/86586#issuecomment-868355356)
 sed -i'' 's|ftp://gcc\.gnu\.org/|http://gcc.gnu.org/|g' ./contrib/download_prerequisites
 
 ./contrib/download_prerequisites
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
index 7f1a5820e22..ee3cd092f4c 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
@@ -17,7 +17,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   libgl1-mesa-dev \
   llvm-dev \
   libfreetype6-dev \
-  libexpat1-dev
+  libexpat1-dev \
+  tidy
 
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
index 35d274da673..6dcf0bdcba4 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
@@ -12,7 +12,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   cmake \
   libssl-dev \
   sudo \
-  xz-utils
+  xz-utils \
+  tidy
 
 # Install dependencies for chromium browser
 RUN apt-get install -y \
@@ -71,7 +72,7 @@ ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}"
 # https://github.com/puppeteer/puppeteer/issues/375
 #
 # We also specify the version in case we need to update it to go around cache limitations.
-RUN npm install -g browser-ui-test@0.4.0 --unsafe-perm=true
+RUN npm install -g browser-ui-test@0.4.1 --unsafe-perm=true
 
 ENV RUST_CONFIGURE_ARGS \
   --build=x86_64-unknown-linux-gnu \
diff --git a/src/ci/pgo.sh b/src/ci/pgo.sh
index c3c717266db..d2962179eea 100755
--- a/src/ci/pgo.sh
+++ b/src/ci/pgo.sh
@@ -15,14 +15,16 @@ function pgo_perf_benchmark {
     local PERF=1e19fc4c6168d2f7596e512f42f358f245d8f09d
     local github_prefix=https://raw.githubusercontent.com/rust-lang/rustc-perf/$PERF
     local name=$1
+    local edition=$2
     curl -o /tmp/$name.rs $github_prefix/collector/benchmarks/$name/src/lib.rs
 
-    RUSTC_BOOTSTRAP=1 ./build/$PGO_HOST/stage2/bin/rustc --edition=2018 \
+    RUSTC_BOOTSTRAP=1 ./build/$PGO_HOST/stage2/bin/rustc --edition=$edition \
         --crate-type=lib /tmp/$name.rs
 }
 
-pgo_perf_benchmark externs
-pgo_perf_benchmark ctfe-stress-4
+pgo_perf_benchmark externs 2018
+pgo_perf_benchmark ctfe-stress-4 2018
+pgo_perf_benchmark inflate 2015
 
 cp -pri ../src/tools/cargo /tmp/cargo
 
diff --git a/src/ci/shared.sh b/src/ci/shared.sh
index b095afb542d..1f218bc8346 100644
--- a/src/ci/shared.sh
+++ b/src/ci/shared.sh
@@ -7,7 +7,7 @@
 
 export MIRRORS_BASE="https://ci-mirrors.rust-lang.org/rustc"
 
-# See http://unix.stackexchange.com/questions/82598
+# See https://unix.stackexchange.com/questions/82598
 # Duplicated in docker/dist-various-2/shared.sh
 function retry {
   echo "Attempting with retry:" "$@"
diff --git a/src/doc/rustdoc/src/SUMMARY.md b/src/doc/rustdoc/src/SUMMARY.md
index ae94527e2b4..3fa91bb51f0 100644
--- a/src/doc/rustdoc/src/SUMMARY.md
+++ b/src/doc/rustdoc/src/SUMMARY.md
@@ -10,5 +10,6 @@
 - [Lints](lints.md)
 - [Advanced features](advanced-features.md)
 - [Unstable features](unstable-features.md)
+- [Website features](website-features.md)
 - [Passes](passes.md)
 - [References](references.md)
diff --git a/src/doc/rustdoc/src/website-features.md b/src/doc/rustdoc/src/website-features.md
new file mode 100644
index 00000000000..5fade4e84a9
--- /dev/null
+++ b/src/doc/rustdoc/src/website-features.md
@@ -0,0 +1,25 @@
+# Website features
+
+These features are about using the website generated by `rustdoc`.
+
+## Custom search engines
+
+If you find yourself often referencing online Rust docs you might enjoy using a custom search
+engine. This allows you to use the navigation bar directly to search a `rustdoc` website.
+Most browsers support this feature by letting you define a URL template containing `%s`
+which will be substituted for the search term. As an example, for the standard library you could use
+this template:
+
+```text
+https://doc.rust-lang.org/stable/std/?search=%s
+```
+
+Note that this will take you to a results page listing all matches. If you want to navigate to the first
+result right away (which is often the best match) use the following instead:
+
+```text
+https://doc.rust-lang.org/stable/std/?search=%s&go_to_first=true
+```
+
+This URL adds the `go_to_first=true` query parameter which can be appended to any `rustdoc` search URL
+to automatically go to the first result.
diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md
index 03dbf4fb617..2cf6801ad1c 100644
--- a/src/doc/unstable-book/src/library-features/asm.md
+++ b/src/doc/unstable-book/src/library-features/asm.md
@@ -456,7 +456,7 @@ reg_spec := <register class> / "<explicit register>"
 operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_"
 reg_operand := dir_spec "(" reg_spec ")" operand_expr
 operand := reg_operand / "const" const_expr / "sym" path
-option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax"
+option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw"
 options := "options(" option *["," option] [","] ")"
 asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," options] [","] ")"
 ```
@@ -781,6 +781,7 @@ Currently the following options are defined:
 - `noreturn`: The `asm` block never returns, and its return type is defined as `!` (never). Behavior is undefined if execution falls through past the end of the asm code. A `noreturn` asm block behaves just like a function which doesn't return; notably, local variables in scope are not dropped before it is invoked.
 - `nostack`: The `asm` block does not push data to the stack, or write to the stack red-zone (if supported by the target). If this option is *not* used then the stack pointer is guaranteed to be suitably aligned (according to the target ABI) for a function call.
 - `att_syntax`: This option is only valid on x86, and causes the assembler to use the `.att_syntax prefix` mode of the GNU assembler. Register operands are substituted in with a leading `%`.
+- `raw`: This causes the template string to be parsed as a raw assembly string, with no special handling for `{` and `}`. This is primarily useful when including raw assembly code from an external file using `include_str!`.
 
 The compiler performs some additional checks on options:
 - The `nomem` and `readonly` options are mutually exclusive: it is a compile-time error to specify both.
diff --git a/src/doc/unstable-book/src/library-features/try-trait.md b/src/doc/unstable-book/src/library-features/try-trait.md
deleted file mode 100644
index 022640067bd..00000000000
--- a/src/doc/unstable-book/src/library-features/try-trait.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# `try_trait`
-
-The tracking issue for this feature is: [#42327]
-
-[#42327]: https://github.com/rust-lang/rust/issues/42327
-
-------------------------
-
-This introduces a new trait `Try` for extending the `?` operator to types
-other than `Result` (a part of [RFC 1859]).  The trait provides the canonical
-way to _view_ a type in terms of a success/failure dichotomy.  This will
-allow `?` to supplant the `try_opt!` macro on `Option` and the `try_ready!`
-macro on `Poll`, among other things.
-
-[RFC 1859]: https://github.com/rust-lang/rfcs/pull/1859
-
-Here's an example implementation of the trait:
-
-```rust,ignore (cannot-reimpl-Try)
-/// A distinct type to represent the `None` value of an `Option`.
-///
-/// This enables using the `?` operator on `Option`; it's rarely useful alone.
-#[derive(Debug)]
-#[unstable(feature = "try_trait", issue = "42327")]
-pub struct None { _priv: () }
-
-#[unstable(feature = "try_trait", issue = "42327")]
-impl<T> ops::Try for Option<T>  {
-    type Ok = T;
-    type Error = None;
-
-    fn into_result(self) -> Result<T, None> {
-        self.ok_or(None { _priv: () })
-    }
-
-    fn from_ok(v: T) -> Self {
-        Some(v)
-    }
-
-    fn from_error(_: None) -> Self {
-        None
-    }
-}
-```
-
-Note the `Error` associated type here is a new marker.  The `?` operator
-allows interconversion between different `Try` implementers only when
-the error type can be converted `Into` the error type of the enclosing
-function (or catch block).  Having a distinct error type (as opposed to
-just `()`, or similar) restricts this to where it's semantically meaningful.
diff --git a/src/etc/installer/README.md b/src/etc/installer/README.md
index dbefe753bee..cded3bbf7fc 100644
--- a/src/etc/installer/README.md
+++ b/src/etc/installer/README.md
@@ -18,7 +18,7 @@ prefix. You can display these options by running:
 
     $ sudo ./install.sh --help
 
-Read [The Book](http://doc.rust-lang.org/book/index.html) to learn how
+Read [The Book](https://doc.rust-lang.org/book/index.html) to learn how
 to use Rust.
 
 Rust is primarily distributed under the terms of both the MIT license
diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis
index 89280149a03..cf887ffb0c0 100644
--- a/src/etc/natvis/intrinsic.natvis
+++ b/src/etc/natvis/intrinsic.natvis
@@ -15,7 +15,7 @@
       </Synthetic>
     </Expand>
   </Type>
-  <Type Name="slice&lt;*&gt;">
+  <Type Name="slice$&lt;*&gt;">
     <DisplayString>{{ len={length} }}</DisplayString>
     <Expand>
       <Item Name="[len]" ExcludeView="simple">length</Item>
@@ -25,23 +25,23 @@
       </ArrayItems>
     </Expand>
   </Type>
-  <Type Name="tuple&lt;&gt;">
+  <Type Name="tuple$&lt;&gt;">
     <DisplayString>()</DisplayString>
   </Type>
-  <Type Name="tuple&lt;*&gt;">
+  <Type Name="tuple$&lt;*&gt;">
     <DisplayString>({__0})</DisplayString>
     <Expand>
       <Item Name="[0]">__0</Item>
     </Expand>
   </Type>
-  <Type Name="tuple&lt;*,*&gt;">
+  <Type Name="tuple$&lt;*,*&gt;">
     <DisplayString>({__0}, {__1})</DisplayString>
     <Expand>
       <Item Name="[0]">__0</Item>
       <Item Name="[1]">__1</Item>
     </Expand>
   </Type>
-  <Type Name="tuple&lt;*,*,*&gt;">
+  <Type Name="tuple$&lt;*,*,*&gt;">
     <DisplayString>({__0}, {__1}, {__2})</DisplayString>
     <Expand>
       <Item Name="[0]">__0</Item>
@@ -49,7 +49,7 @@
       <Item Name="[2]">__2</Item>
     </Expand>
   </Type>
-  <Type Name="tuple&lt;*,*,*,*&gt;">
+  <Type Name="tuple$&lt;*,*,*,*&gt;">
     <DisplayString>({__0}, {__1}, {__2}, {__3})</DisplayString>
     <Expand>
       <Item Name="[0]">__0</Item>
@@ -58,7 +58,7 @@
       <Item Name="[3]">__3</Item>
     </Expand>
   </Type>
-  <Type Name="tuple&lt;*,*,*,*,*&gt;">
+  <Type Name="tuple$&lt;*,*,*,*,*&gt;">
     <DisplayString>({__0}, {__1}, {__2}, {__3}, {__4})</DisplayString>
     <Expand>
       <Item Name="[0]">__0</Item>
@@ -68,7 +68,7 @@
       <Item Name="[4]">__4</Item>
     </Expand>
   </Type>
-  <Type Name="tuple&lt;*,*,*,*,*,*&gt;">
+  <Type Name="tuple$&lt;*,*,*,*,*,*&gt;">
     <DisplayString>({__0}, {__1}, {__2}, {__3}, {__4}, {__5})</DisplayString>
     <Expand>
       <Item Name="[0]">__0</Item>
@@ -79,7 +79,7 @@
       <Item Name="[5]">__5</Item>
     </Expand>
   </Type>
-  <Type Name="tuple&lt;*,*,*,*,*,*,*&gt;">
+  <Type Name="tuple$&lt;*,*,*,*,*,*,*&gt;">
     <DisplayString>({__0}, {__1}, {__2}, {__3}, {__4}, {__5}, {__6})</DisplayString>
     <Expand>
       <Item Name="[0]">__0</Item>
@@ -91,7 +91,7 @@
       <Item Name="[6]">__6</Item>
     </Expand>
   </Type>
-  <Type Name="tuple&lt;*,*,*,*,*,*,*,*&gt;">
+  <Type Name="tuple$&lt;*,*,*,*,*,*,*,*&gt;">
     <DisplayString>({__0}, {__1}, {__2}, {__3}, {__4}, {__5}, {__6}, {__7})</DisplayString>
     <Expand>
       <Item Name="[0]">__0</Item>
@@ -104,7 +104,7 @@
       <Item Name="[7]">__7</Item>
     </Expand>
   </Type>
-  <Type Name="tuple&lt;*,*,*,*,*,*,*,*,*&gt;">
+  <Type Name="tuple$&lt;*,*,*,*,*,*,*,*,*&gt;">
     <DisplayString>({__0}, {__1}, {__2}, {__3}, {__4}, {__5}, {__6}, {__7}, {__8})</DisplayString>
     <Expand>
       <Item Name="[0]">__0</Item>
@@ -118,7 +118,7 @@
       <Item Name="[8]">__8</Item>
     </Expand>
   </Type>
-  <Type Name="tuple&lt;*,*,*,*,*,*,*,*,*,*&gt;">
+  <Type Name="tuple$&lt;*,*,*,*,*,*,*,*,*,*&gt;">
     <DisplayString>({__0}, {__1}, {__2}, {__3}, {__4}, {__5}, {__6}, {__7}, {__8}, {__9})</DisplayString>
     <Expand>
       <Item Name="[0]">__0</Item>
@@ -133,7 +133,7 @@
       <Item Name="[9]">__9</Item>
     </Expand>
   </Type>
-  <Type Name="tuple&lt;*,*,*,*,*,*,*,*,*,*,*&gt;">
+  <Type Name="tuple$&lt;*,*,*,*,*,*,*,*,*,*,*&gt;">
     <DisplayString>({__0}, {__1}, {__2}, {__3}, {__4}, {__5}, {__6}, {__7}, {__8}, {__9}, ...)</DisplayString>
     <Expand>
       <Item Name="[0]">__0</Item>
diff --git a/src/etc/natvis/libstd.natvis b/src/etc/natvis/libstd.natvis
index 2c05f9d7c12..3ccd2e9c30e 100644
--- a/src/etc/natvis/libstd.natvis
+++ b/src/etc/natvis/libstd.natvis
@@ -41,7 +41,7 @@
           <If Condition="(base.table.table.ctrl.pointer[i] &amp; 0x80) == 0">
             <!-- Bucket is populated -->
             <Exec>n--</Exec>
-            <Item Name="{((tuple&lt;$T1, $T2&gt;*)base.table.table.ctrl.pointer)[-(i + 1)].__0}">((tuple&lt;$T1, $T2&gt;*)base.table.table.ctrl.pointer)[-(i + 1)].__1</Item>
+            <Item Name="{((tuple$&lt;$T1, $T2&gt;*)base.table.table.ctrl.pointer)[-(i + 1)].__0}">((tuple$&lt;$T1, $T2&gt;*)base.table.table.ctrl.pointer)[-(i + 1)].__1</Item>
           </If>
           <Exec>i++</Exec>
         </Loop>
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index a3f63ea1046..ebab3add6c5 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -353,12 +353,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                     let (poly_trait, output) =
                         (data.0.as_ref().expect("as_ref failed").clone(), data.1.as_ref().cloned());
                     let new_ty = match poly_trait.trait_ {
-                        Type::ResolvedPath {
-                            ref path,
-                            ref param_names,
-                            ref did,
-                            ref is_generic,
-                        } => {
+                        Type::ResolvedPath { ref path, ref did, ref is_generic } => {
                             let mut new_path = path.clone();
                             let last_segment =
                                 new_path.segments.pop().expect("segments were empty");
@@ -395,7 +390,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
 
                             Type::ResolvedPath {
                                 path: new_path,
-                                param_names: param_names.clone(),
                                 did: *did,
                                 is_generic: *is_generic,
                             }
@@ -414,7 +408,11 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                 let mut bounds_vec = bounds.into_iter().collect();
                 self.sort_where_bounds(&mut bounds_vec);
 
-                Some(WherePredicate::BoundPredicate { ty, bounds: bounds_vec })
+                Some(WherePredicate::BoundPredicate {
+                    ty,
+                    bounds: bounds_vec,
+                    bound_params: Vec::new(),
+                })
             })
             .chain(
                 lifetime_to_bounds.into_iter().filter(|&(_, ref bounds)| !bounds.is_empty()).map(
@@ -492,7 +490,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
             }
             let p = p.unwrap();
             match p {
-                WherePredicate::BoundPredicate { ty, mut bounds } => {
+                WherePredicate::BoundPredicate { ty, mut bounds, .. } => {
                     // Writing a projection trait bound of the form
                     // <T as Trait>::Name : ?Sized
                     // is illegal, because ?Sized bounds can only
@@ -566,7 +564,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                             match **trait_ {
                                 Type::ResolvedPath {
                                     path: ref trait_path,
-                                    ref param_names,
                                     ref did,
                                     ref is_generic,
                                 } => {
@@ -613,7 +610,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                                         PolyTrait {
                                             trait_: Type::ResolvedPath {
                                                 path: new_trait_path,
-                                                param_names: param_names.clone(),
                                                 did: *did,
                                                 is_generic: *is_generic,
                                             },
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 111827aacdf..829b54f1fc1 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -15,7 +15,9 @@ use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
 
-use crate::clean::{self, Attributes, AttributesExt, FakeDefId, GetDefId, ToSource};
+use crate::clean::{
+    self, Attributes, AttributesExt, FakeDefId, GetDefId, NestedAttributesExt, ToSource, Type,
+};
 use crate::core::DocContext;
 use crate::formats::item_type::ItemType;
 
@@ -420,6 +422,21 @@ crate fn build_impl(
     if trait_.def_id() == tcx.lang_items().deref_trait() {
         super::build_deref_target_impls(cx, &trait_items, ret);
     }
+
+    // Return if the trait itself or any types of the generic parameters are doc(hidden).
+    let mut stack: Vec<&Type> = trait_.iter().collect();
+    stack.push(&for_);
+    while let Some(ty) = stack.pop() {
+        if let Some(did) = ty.def_id() {
+            if cx.tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden) {
+                return;
+            }
+        }
+        if let Some(generics) = ty.generics() {
+            stack.extend(generics);
+        }
+    }
+
     if let Some(trait_did) = trait_.def_id() {
         record_extern_trait(cx, trait_did);
     }
@@ -566,9 +583,11 @@ fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::Item
 fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean::Generics {
     for pred in &mut g.where_predicates {
         match *pred {
-            clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref mut bounds }
-                if *s == kw::SelfUpper =>
-            {
+            clean::WherePredicate::BoundPredicate {
+                ty: clean::Generic(ref s),
+                ref mut bounds,
+                ..
+            } if *s == kw::SelfUpper => {
                 bounds.retain(|bound| match *bound {
                     clean::GenericBound::TraitBound(
                         clean::PolyTrait { trait_: clean::ResolvedPath { did, .. }, .. },
@@ -591,6 +610,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
                     ..
                 },
             ref bounds,
+            ..
         } => !(bounds.is_empty() || *s == kw::SelfUpper && did == trait_did),
         _ => true,
     });
@@ -605,7 +625,7 @@ fn separate_supertrait_bounds(
 ) -> (clean::Generics, Vec<clean::GenericBound>) {
     let mut ty_bounds = Vec::new();
     g.where_predicates.retain(|pred| match *pred {
-        clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds }
+        clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds, .. }
             if *s == kw::SelfUpper =>
         {
             ty_bounds.extend(bounds.iter().cloned());
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index bc04480ab7c..6abe1c7cd61 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -20,7 +20,7 @@ use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
 use rustc_middle::middle::resolve_lifetime as rl;
 use rustc_middle::ty::fold::TypeFolder;
 use rustc_middle::ty::subst::{InternalSubsts, Subst};
-use rustc_middle::ty::{self, AdtKind, Lift, Ty, TyCtxt};
+use rustc_middle::ty::{self, AdtKind, DefIdTree, Lift, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_mir::const_eval::{is_const_fn, is_unstable_const_fn};
 use rustc_span::hygiene::{AstPass, MacroKind};
@@ -180,7 +180,7 @@ impl Clean<Type> for (ty::TraitRef<'_>, &[TypeBinding]) {
 
         debug!("ty::TraitRef\n  subst: {:?}\n", trait_ref.substs);
 
-        ResolvedPath { path, param_names: None, did: trait_ref.def_id, is_generic: false }
+        ResolvedPath { path, did: trait_ref.def_id, is_generic: false }
     }
 }
 
@@ -330,6 +330,7 @@ impl Clean<WherePredicate> for hir::WherePredicate<'_> {
             hir::WherePredicate::BoundPredicate(ref wbp) => WherePredicate::BoundPredicate {
                 ty: wbp.bounded_ty.clean(cx),
                 bounds: wbp.bounds.clean(cx),
+                bound_params: wbp.bound_generic_params.into_iter().map(|x| x.clean(cx)).collect(),
             },
 
             hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate {
@@ -370,6 +371,7 @@ impl<'a> Clean<WherePredicate> for ty::PolyTraitPredicate<'a> {
         WherePredicate::BoundPredicate {
             ty: poly_trait_ref.skip_binder().self_ty().clean(cx),
             bounds: vec![poly_trait_ref.clean(cx)],
+            bound_params: Vec::new(),
         }
     }
 }
@@ -402,6 +404,7 @@ impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty:
         Some(WherePredicate::BoundPredicate {
             ty: ty.clean(cx),
             bounds: vec![GenericBound::Outlives(lt.clean(cx).expect("failed to clean lifetimes"))],
+            bound_params: Vec::new(),
         })
     }
 }
@@ -435,8 +438,23 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
         let (name, kind) = match self.kind {
             ty::GenericParamDefKind::Lifetime => (self.name, GenericParamDefKind::Lifetime),
             ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
-                let default =
-                    if has_default { Some(cx.tcx.type_of(self.def_id).clean(cx)) } else { None };
+                let default = if has_default {
+                    let mut default = cx.tcx.type_of(self.def_id).clean(cx);
+
+                    // We need to reassign the `self_def_id`, if there's a parent (which is the
+                    // `Self` type), so we can properly render `<Self as X>` casts, because the
+                    // information about which type `Self` is, is only present here, but not in
+                    // the cleaning process of the type itself. To resolve this and have the
+                    // `self_def_id` set, we override it here.
+                    // See https://github.com/rust-lang/rust/issues/85454
+                    if let QPath { ref mut self_def_id, .. } = default {
+                        *self_def_id = cx.tcx.parent(self.def_id);
+                    }
+
+                    Some(default)
+                } else {
+                    None
+                };
                 (
                     self.name,
                     GenericParamDefKind::Type {
@@ -567,7 +585,9 @@ impl Clean<Generics> for hir::Generics<'_> {
         // to where predicates when such cases occur.
         for where_pred in &mut generics.where_predicates {
             match *where_pred {
-                WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => {
+                WherePredicate::BoundPredicate {
+                    ty: Generic(ref name), ref mut bounds, ..
+                } => {
                     if bounds.is_empty() {
                         for param in &mut generics.params {
                             match param.kind {
@@ -721,7 +741,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
         // handled in cleaning associated types
         let mut sized_params = FxHashSet::default();
         where_predicates.retain(|pred| match *pred {
-            WP::BoundPredicate { ty: Generic(ref g), ref bounds } => {
+            WP::BoundPredicate { ty: Generic(ref g), ref bounds, .. } => {
                 if bounds.iter().any(|b| b.is_sized_bound(cx)) {
                     sized_params.insert(*g);
                     false
@@ -741,6 +761,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
                 where_predicates.push(WP::BoundPredicate {
                     ty: Type::Generic(tp.name),
                     bounds: vec![GenericBound::maybe_sized(cx)],
+                    bound_params: Vec::new(),
                 })
             }
         }
@@ -1117,6 +1138,7 @@ impl Clean<Item> for ty::AssocItem {
                                 WherePredicate::BoundPredicate {
                                     ty: QPath { ref name, ref self_type, ref trait_, .. },
                                     ref bounds,
+                                    ..
                                 } => (name, self_type, trait_, bounds),
                                 _ => return None,
                             };
@@ -1371,24 +1393,9 @@ impl Clean<Type> for hir::Ty<'_> {
             }
             TyKind::Path(_) => clean_qpath(&self, cx),
             TyKind::TraitObject(ref bounds, ref lifetime, _) => {
-                match bounds[0].clean(cx).trait_ {
-                    ResolvedPath { path, param_names: None, did, is_generic } => {
-                        let mut bounds: Vec<self::GenericBound> = bounds[1..]
-                            .iter()
-                            .map(|bound| {
-                                self::GenericBound::TraitBound(
-                                    bound.clean(cx),
-                                    hir::TraitBoundModifier::None,
-                                )
-                            })
-                            .collect();
-                        if !lifetime.is_elided() {
-                            bounds.push(self::GenericBound::Outlives(lifetime.clean(cx)));
-                        }
-                        ResolvedPath { path, param_names: Some(bounds), did, is_generic }
-                    }
-                    _ => Infer, // shouldn't happen
-                }
+                let bounds = bounds.iter().map(|bound| bound.clean(cx)).collect();
+                let lifetime = if !lifetime.is_elided() { Some(lifetime.clean(cx)) } else { None };
+                DynTrait(bounds, lifetime)
             }
             TyKind::BareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
             TyKind::Infer | TyKind::Err => Infer,
@@ -1471,7 +1478,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                 };
                 inline::record_extern_fqn(cx, did, kind);
                 let path = external_path(cx, cx.tcx.item_name(did), None, false, vec![], substs);
-                ResolvedPath { path, param_names: None, did, is_generic: false }
+                ResolvedPath { path, did, is_generic: false }
             }
             ty::Foreign(did) => {
                 inline::record_extern_fqn(cx, did, ItemType::ForeignType);
@@ -1483,7 +1490,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                     vec![],
                     InternalSubsts::empty(),
                 );
-                ResolvedPath { path, param_names: None, did, is_generic: false }
+                ResolvedPath { path, did, is_generic: false }
             }
             ty::Dynamic(ref obj, ref reg) => {
                 // HACK: pick the first `did` as the `did` of the trait object. Someone
@@ -1501,28 +1508,19 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
 
                 inline::record_extern_fqn(cx, did, ItemType::Trait);
 
-                let mut param_names = vec![];
-                if let Some(b) = reg.clean(cx) {
-                    param_names.push(GenericBound::Outlives(b));
-                }
+                let lifetime = reg.clean(cx);
+                let mut bounds = vec![];
+
                 for did in dids {
                     let empty = cx.tcx.intern_substs(&[]);
                     let path =
                         external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
                     inline::record_extern_fqn(cx, did, ItemType::Trait);
-                    let bound = GenericBound::TraitBound(
-                        PolyTrait {
-                            trait_: ResolvedPath {
-                                path,
-                                param_names: None,
-                                did,
-                                is_generic: false,
-                            },
-                            generic_params: Vec::new(),
-                        },
-                        hir::TraitBoundModifier::None,
-                    );
-                    param_names.push(bound);
+                    let bound = PolyTrait {
+                        trait_: ResolvedPath { path, did, is_generic: false },
+                        generic_params: Vec::new(),
+                    };
+                    bounds.push(bound);
                 }
 
                 let mut bindings = vec![];
@@ -1535,7 +1533,15 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
 
                 let path =
                     external_path(cx, cx.tcx.item_name(did), Some(did), false, bindings, substs);
-                ResolvedPath { path, param_names: Some(param_names), did, is_generic: false }
+                bounds.insert(
+                    0,
+                    PolyTrait {
+                        trait_: ResolvedPath { path, did, is_generic: false },
+                        generic_params: Vec::new(),
+                    },
+                );
+
+                DynTrait(bounds, lifetime)
             }
             ty::Tuple(ref t) => {
                 Tuple(t.iter().map(|t| t.expect_ty()).collect::<Vec<_>>().clean(cx))
@@ -2239,14 +2245,9 @@ impl From<GenericBound> for SimpleBound {
         match bound.clone() {
             GenericBound::Outlives(l) => SimpleBound::Outlives(l),
             GenericBound::TraitBound(t, mod_) => match t.trait_ {
-                Type::ResolvedPath { path, param_names, .. } => SimpleBound::TraitBound(
-                    path.segments,
-                    param_names.map_or_else(Vec::new, |v| {
-                        v.iter().map(|p| SimpleBound::from(p.clone())).collect()
-                    }),
-                    t.generic_params,
-                    mod_,
-                ),
+                Type::ResolvedPath { path, .. } => {
+                    SimpleBound::TraitBound(path.segments, Vec::new(), t.generic_params, mod_)
+                }
                 _ => panic!("Unexpected bound {:?}", bound),
             },
         }
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index d4d0a8ce24c..3ec0a22a2c0 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -24,16 +24,20 @@ use crate::core::DocContext;
 
 crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     // First, partition the where clause into its separate components
-    let mut params: BTreeMap<_, Vec<_>> = BTreeMap::new();
+    let mut params: BTreeMap<_, (Vec<_>, Vec<_>)> = BTreeMap::new();
     let mut lifetimes = Vec::new();
     let mut equalities = Vec::new();
     let mut tybounds = Vec::new();
 
     for clause in clauses {
         match clause {
-            WP::BoundPredicate { ty, bounds } => match ty {
-                clean::Generic(s) => params.entry(s).or_default().extend(bounds),
-                t => tybounds.push((t, bounds)),
+            WP::BoundPredicate { ty, bounds, bound_params } => match ty {
+                clean::Generic(s) => {
+                    let (b, p) = params.entry(s).or_default();
+                    b.extend(bounds);
+                    p.extend(bound_params);
+                }
+                t => tybounds.push((t, (bounds, bound_params))),
             },
             WP::RegionPredicate { lifetime, bounds } => {
                 lifetimes.push((lifetime, bounds));
@@ -54,7 +58,7 @@ crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
             clean::Generic(s) => s,
             _ => return true,
         };
-        let bounds = match params.get_mut(generic) {
+        let (bounds, _) = match params.get_mut(generic) {
             Some(bound) => bound,
             None => return true,
         };
@@ -67,10 +71,16 @@ crate fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     clauses.extend(
         lifetimes.into_iter().map(|(lt, bounds)| WP::RegionPredicate { lifetime: lt, bounds }),
     );
-    clauses.extend(
-        params.into_iter().map(|(k, v)| WP::BoundPredicate { ty: clean::Generic(k), bounds: v }),
-    );
-    clauses.extend(tybounds.into_iter().map(|(ty, bounds)| WP::BoundPredicate { ty, bounds }));
+    clauses.extend(params.into_iter().map(|(k, (bounds, params))| WP::BoundPredicate {
+        ty: clean::Generic(k),
+        bounds,
+        bound_params: params,
+    }));
+    clauses.extend(tybounds.into_iter().map(|(ty, (bounds, bound_params))| WP::BoundPredicate {
+        ty,
+        bounds,
+        bound_params,
+    }));
     clauses.extend(equalities.into_iter().map(|(lhs, rhs)| WP::EqPredicate { lhs, rhs }));
     clauses
 }
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 66f62d97b04..4da2f14ce8a 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1168,7 +1168,7 @@ impl GenericBound {
         inline::record_extern_fqn(cx, did, ItemType::Trait);
         GenericBound::TraitBound(
             PolyTrait {
-                trait_: ResolvedPath { path, param_names: None, did, is_generic: false },
+                trait_: ResolvedPath { path, did, is_generic: false },
                 generic_params: Vec::new(),
             },
             hir::TraitBoundModifier::Maybe,
@@ -1220,7 +1220,7 @@ impl Lifetime {
 
 #[derive(Clone, Debug)]
 crate enum WherePredicate {
-    BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
+    BoundPredicate { ty: Type, bounds: Vec<GenericBound>, bound_params: Vec<Lifetime> },
     RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
     EqPredicate { lhs: Type, rhs: Type },
 }
@@ -1434,11 +1434,12 @@ crate enum Type {
     /// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
     ResolvedPath {
         path: Path,
-        param_names: Option<Vec<GenericBound>>,
         did: DefId,
         /// `true` if is a `T::Name` path for associated types.
         is_generic: bool,
     },
+    /// `dyn for<'a> Trait<'a> + Send + 'static`
+    DynTrait(Vec<PolyTrait>, Option<Lifetime>),
     /// For parameterized types, so the consumer of the JSON don't go
     /// looking for types which don't exist anywhere.
     Generic(Symbol),
@@ -1625,6 +1626,7 @@ impl Type {
     fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
         let t: PrimitiveType = match *self {
             ResolvedPath { did, .. } => return Some(did.into()),
+            DynTrait(ref bounds, _) => return bounds[0].trait_.inner_def_id(cache),
             Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()),
             BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference,
             BorrowedRef { ref type_, .. } => return type_.inner_def_id(cache),
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 706a56fbcbf..f70ccdd63f9 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -2,7 +2,7 @@ use crate::clean::auto_trait::AutoTraitFinder;
 use crate::clean::blanket_impl::BlanketImplFinder;
 use crate::clean::{
     inline, Clean, Crate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime,
-    Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Type, TypeBinding,
+    Path, PathSegment, PolyTrait, Primitive, PrimitiveType, ResolvedPath, Type, TypeBinding,
 };
 use crate::core::DocContext;
 use crate::formats::item_type::ItemType;
@@ -30,7 +30,7 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate {
     cx.cache.owned_box_did = cx.tcx.lang_items().owned_box();
 
     let mut externs = Vec::new();
-    for &cnum in cx.tcx.crates().iter() {
+    for &cnum in cx.tcx.crates(()).iter() {
         externs.push((cnum, cnum.clean(cx)));
         // Analyze doc-reachability for extern items
         LibEmbargoVisitor::new(cx).visit_lib(cnum);
@@ -163,8 +163,18 @@ pub(super) fn external_path(
 
 crate fn strip_type(ty: Type) -> Type {
     match ty {
-        Type::ResolvedPath { path, param_names, did, is_generic } => {
-            Type::ResolvedPath { path: strip_path(&path), param_names, did, is_generic }
+        Type::ResolvedPath { path, did, is_generic } => {
+            Type::ResolvedPath { path: strip_path(&path), did, is_generic }
+        }
+        Type::DynTrait(mut bounds, lt) => {
+            let first = bounds.remove(0);
+            let stripped_trait = strip_type(first.trait_);
+
+            bounds.insert(
+                0,
+                PolyTrait { trait_: stripped_trait, generic_params: first.generic_params },
+            );
+            Type::DynTrait(bounds, lt)
         }
         Type::Tuple(inner_tys) => {
             Type::Tuple(inner_tys.iter().map(|t| strip_type(t.clone())).collect())
@@ -431,7 +441,7 @@ crate fn resolve_type(cx: &mut DocContext<'_>, path: Path, id: hir::HirId) -> Ty
         _ => false,
     };
     let did = register_res(cx, path.res);
-    ResolvedPath { path, param_names: None, did, is_generic }
+    ResolvedPath { path, did, is_generic }
 }
 
 crate fn get_auto_trait_and_blanket_impls(
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index c3d9c4ea7f2..66f4f481292 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -1,12 +1,12 @@
-use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::{self, Lrc};
 use rustc_driver::abort_on_err;
 use rustc_errors::emitter::{Emitter, EmitterWriter};
 use rustc_errors::json::JsonEmitter;
 use rustc_feature::UnstableFeatures;
+use rustc_hir::def::Namespace::TypeNS;
 use rustc_hir::def::Res;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
 use rustc_hir::HirId;
 use rustc_hir::{
     intravisit::{self, NestedVisitorMap, Visitor},
@@ -23,7 +23,7 @@ use rustc_session::DiagnosticOutput;
 use rustc_session::Session;
 use rustc_span::source_map;
 use rustc_span::symbol::sym;
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
 
 use std::cell::RefCell;
 use std::mem;
@@ -300,17 +300,41 @@ crate fn create_config(
 }
 
 crate fn create_resolver<'a>(
+    externs: config::Externs,
     queries: &Queries<'a>,
     sess: &Session,
 ) -> Rc<RefCell<interface::BoxedResolver>> {
-    let parts = abort_on_err(queries.expansion(), sess).peek();
-    let (krate, resolver, _) = &*parts;
-    let resolver = resolver.borrow().clone();
-
-    let mut loader = crate::passes::collect_intra_doc_links::IntraLinkCrateLoader::new(resolver);
-    ast::visit::walk_crate(&mut loader, krate);
+    let extern_names: Vec<String> = externs
+        .iter()
+        .filter(|(_, entry)| entry.add_prelude)
+        .map(|(name, _)| name)
+        .cloned()
+        .collect();
+
+    let (_, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek();
+
+    // Before we actually clone it, let's force all the extern'd crates to
+    // actually be loaded, just in case they're only referred to inside
+    // intra-doc links
+    resolver.borrow_mut().access(|resolver| {
+        sess.time("load_extern_crates", || {
+            for extern_name in &extern_names {
+                debug!("loading extern crate {}", extern_name);
+                if let Err(()) = resolver
+                    .resolve_str_path_error(
+                        DUMMY_SP,
+                        extern_name,
+                        TypeNS,
+                        LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(),
+                  ) {
+                    warn!("unable to resolve external crate {} (do you have an unused `--extern` crate?)", extern_name)
+                  }
+            }
+        });
+    });
 
-    loader.resolver
+    // Now we're good to clone the resolver because everything should be loaded
+    resolver.clone()
 }
 
 crate fn run_global_ctxt(
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 1750f05b4dc..1281f76fd0f 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -112,7 +112,6 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
 
     let res = interface::run_compiler(config, |compiler| {
         compiler.enter(|queries| {
-            let _lower_to_hir = queries.lower_to_hir()?;
             let mut global_ctxt = queries.global_ctxt()?.take();
 
             let collector = global_ctxt.enter(|tcx| {
@@ -942,9 +941,7 @@ impl Tester for Collector {
                 // compiler failures are test failures
                 should_panic: testing::ShouldPanic::No,
                 allow_fail: config.allow_fail,
-                #[cfg(not(bootstrap))]
                 compile_fail: config.compile_fail,
-                #[cfg(not(bootstrap))]
                 no_run,
                 test_type: testing::TestType::DocTest,
             },
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 811f6829201..1e1fc2436aa 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -128,7 +128,6 @@ crate struct Cache {
 /// This struct is used to wrap the `cache` and `tcx` in order to run `DocFolder`.
 struct CacheBuilder<'a, 'tcx> {
     cache: &'a mut Cache,
-    empty_cache: Cache,
     tcx: TyCtxt<'tcx>,
 }
 
@@ -173,7 +172,7 @@ impl Cache {
             self.primitive_locations.insert(prim, def_id);
         }
 
-        krate = CacheBuilder { tcx, cache: self, empty_cache: Cache::default() }.fold_crate(krate);
+        krate = CacheBuilder { tcx, cache: self }.fold_crate(krate);
 
         for (trait_did, dids, impl_) in self.orphan_trait_impls.drain(..) {
             if self.traits.contains_key(&trait_did) {
@@ -302,7 +301,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
                             desc,
                             parent,
                             parent_idx: None,
-                            search_type: get_index_search_type(&item, &self.empty_cache, self.tcx),
+                            search_type: get_index_search_type(&item, self.tcx),
                             aliases: item.attrs.get_doc_aliases(),
                         });
                     }
@@ -403,6 +402,15 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
                         self.cache.parent_stack.push(did);
                         true
                     }
+                    clean::DynTrait(ref bounds, _)
+                    | clean::BorrowedRef { type_: box clean::DynTrait(ref bounds, _), .. } => {
+                        if let Some(did) = bounds[0].trait_.def_id() {
+                            self.cache.parent_stack.push(did);
+                            true
+                        } else {
+                            false
+                        }
+                    }
                     ref t => {
                         let prim_did = t
                             .primitive_type()
@@ -433,6 +441,12 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
                 | clean::BorrowedRef { type_: box clean::ResolvedPath { did, .. }, .. } => {
                     dids.insert(did);
                 }
+                clean::DynTrait(ref bounds, _)
+                | clean::BorrowedRef { type_: box clean::DynTrait(ref bounds, _), .. } => {
+                    if let Some(did) = bounds[0].trait_.def_id() {
+                        dids.insert(did);
+                    }
+                }
                 ref t => {
                     let did = t
                         .primitive_type()
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 58c609cf252..1e08aeb379a 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -250,17 +250,33 @@ crate fn print_where_clause<'a, 'tcx: 'a>(
             }
 
             match pred {
-                clean::WherePredicate::BoundPredicate { ty, bounds } => {
+                clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => {
                     let bounds = bounds;
+                    let for_prefix = match bound_params.len() {
+                        0 => String::new(),
+                        _ if f.alternate() => {
+                            format!(
+                                "for<{:#}> ",
+                                comma_sep(bound_params.iter().map(|lt| lt.print()))
+                            )
+                        }
+                        _ => format!(
+                            "for&lt;{}&gt; ",
+                            comma_sep(bound_params.iter().map(|lt| lt.print()))
+                        ),
+                    };
+
                     if f.alternate() {
                         clause.push_str(&format!(
-                            "{:#}: {:#}",
+                            "{}{:#}: {:#}",
+                            for_prefix,
                             ty.print(cx),
                             print_generic_bounds(bounds, cx)
                         ));
                     } else {
                         clause.push_str(&format!(
-                            "{}: {}",
+                            "{}{}: {}",
+                            for_prefix,
                             ty.print(cx),
                             print_generic_bounds(bounds, cx)
                         ));
@@ -631,18 +647,24 @@ fn primitive_link(
 
 /// Helper to render type parameters
 fn tybounds<'a, 'tcx: 'a>(
-    param_names: &'a Option<Vec<clean::GenericBound>>,
+    bounds: &'a Vec<clean::PolyTrait>,
+    lt: &'a Option<clean::Lifetime>,
     cx: &'a Context<'tcx>,
 ) -> impl fmt::Display + 'a + Captures<'tcx> {
-    display_fn(move |f| match *param_names {
-        Some(ref params) => {
-            for param in params {
+    display_fn(move |f| {
+        for (i, bound) in bounds.iter().enumerate() {
+            if i > 0 {
                 write!(f, " + ")?;
-                fmt::Display::fmt(&param.print(cx), f)?;
             }
-            Ok(())
+
+            fmt::Display::fmt(&bound.print(cx), f)?;
         }
-        None => Ok(()),
+
+        if let Some(lt) = lt {
+            write!(f, " + ")?;
+            fmt::Display::fmt(&lt.print(), f)?;
+        }
+        Ok(())
     })
 }
 
@@ -679,13 +701,13 @@ fn fmt_type<'cx>(
 
     match *t {
         clean::Generic(name) => write!(f, "{}", name),
-        clean::ResolvedPath { did, ref param_names, ref path, is_generic } => {
-            if param_names.is_some() {
-                f.write_str("dyn ")?;
-            }
+        clean::ResolvedPath { did, ref path, is_generic } => {
             // Paths like `T::Output` and `Self::Output` should be rendered with all segments.
-            resolved_path(f, did, path, is_generic, use_absolute, cx)?;
-            fmt::Display::fmt(&tybounds(param_names, cx), f)
+            resolved_path(f, did, path, is_generic, use_absolute, cx)
+        }
+        clean::DynTrait(ref bounds, ref lt) => {
+            f.write_str("dyn ")?;
+            fmt::Display::fmt(&tybounds(bounds, lt, cx), f)
         }
         clean::Infer => write!(f, "_"),
         clean::Primitive(prim) => primitive_link(f, prim, &*prim.as_sym().as_str(), cx),
@@ -820,7 +842,9 @@ fn fmt_type<'cx>(
                         }
                     }
                 }
-                clean::ResolvedPath { param_names: Some(ref v), .. } if !v.is_empty() => {
+                clean::DynTrait(ref bounds, ref trait_lt)
+                    if bounds.len() > 1 || trait_lt.is_some() =>
+                {
                     write!(f, "{}{}{}(", amp, lt, m)?;
                     fmt_type(&ty, f, use_absolute, cx)?;
                     write!(f, ")")
@@ -881,7 +905,7 @@ fn fmt_type<'cx>(
                 //        the ugliness comes from inlining across crates where
                 //        everything comes in as a fully resolved QPath (hard to
                 //        look at).
-                box clean::ResolvedPath { did, ref param_names, .. } => {
+                box clean::ResolvedPath { did, .. } => {
                     match href(did.into(), cx) {
                         Some((ref url, _, ref path)) if !f.alternate() => {
                             write!(
@@ -896,9 +920,6 @@ fn fmt_type<'cx>(
                         }
                         _ => write!(f, "{}", name)?,
                     }
-
-                    // FIXME: `param_names` are not rendered, and this seems bad?
-                    drop(param_names);
                     Ok(())
                 }
                 _ => write!(f, "{}", name),
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 51392ca1191..33b1d98313c 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -413,7 +413,7 @@ impl<'a> Classifier<'a> {
                 },
                 c => c,
             },
-            TokenKind::RawIdent => Class::Ident,
+            TokenKind::RawIdent | TokenKind::UnknownPrefix => Class::Ident,
             TokenKind::Lifetime { .. } => Class::Lifetime,
         };
         // Anything that didn't return above is the simple case where we the
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index 5b3c445013b..0734d2670cc 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -12,7 +12,7 @@ use crate::clean::types::{
 use crate::formats::cache::Cache;
 use crate::formats::item_type::ItemType;
 use crate::html::markdown::short_markdown_summary;
-use crate::html::render::{Generic, IndexItem, IndexItemFunctionType, RenderType, TypeWithKind};
+use crate::html::render::{IndexItem, IndexItemFunctionType, RenderType, TypeWithKind};
 
 /// Indicates where an external crate can be found.
 crate enum ExternalLocation {
@@ -44,7 +44,7 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<
                 desc,
                 parent: Some(did.into()),
                 parent_idx: None,
-                search_type: get_index_search_type(&item, cache, tcx),
+                search_type: get_index_search_type(&item, tcx),
                 aliases: item.attrs.get_doc_aliases(),
             });
         }
@@ -192,7 +192,6 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<
 
 crate fn get_index_search_type<'tcx>(
     item: &clean::Item,
-    cache: &Cache,
     tcx: TyCtxt<'tcx>,
 ) -> Option<IndexItemFunctionType> {
     let (all_types, ret_types) = match *item.kind {
@@ -204,12 +203,12 @@ crate fn get_index_search_type<'tcx>(
 
     let inputs = all_types
         .iter()
-        .map(|(ty, kind)| TypeWithKind::from((get_index_type(&ty, &cache), *kind)))
+        .map(|(ty, kind)| TypeWithKind::from((get_index_type(&ty), *kind)))
         .filter(|a| a.ty.name.is_some())
         .collect();
     let output = ret_types
         .iter()
-        .map(|(ty, kind)| TypeWithKind::from((get_index_type(&ty, &cache), *kind)))
+        .map(|(ty, kind)| TypeWithKind::from((get_index_type(&ty), *kind)))
         .filter(|a| a.ty.name.is_some())
         .collect::<Vec<_>>();
     let output = if output.is_empty() { None } else { Some(output) };
@@ -217,12 +216,10 @@ crate fn get_index_search_type<'tcx>(
     Some(IndexItemFunctionType { inputs, output })
 }
 
-fn get_index_type(clean_type: &clean::Type, cache: &Cache) -> RenderType {
+fn get_index_type(clean_type: &clean::Type) -> RenderType {
     RenderType {
-        ty: clean_type.def_id_full(cache),
-        idx: None,
         name: get_index_type_name(clean_type, true).map(|s| s.as_str().to_ascii_lowercase()),
-        generics: get_generics(clean_type, cache),
+        generics: get_generics(clean_type),
     }
 }
 
@@ -238,6 +235,7 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option
             });
             Some(path_segment.name)
         }
+        clean::DynTrait(ref bounds, _) => get_index_type_name(&bounds[0].trait_, accept_generic),
         clean::Generic(s) if accept_generic => Some(s),
         clean::Primitive(ref p) => Some(p.as_sym()),
         clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_, accept_generic),
@@ -254,16 +252,17 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option
     }
 }
 
-fn get_generics(clean_type: &clean::Type, cache: &Cache) -> Option<Vec<Generic>> {
+/// Return a list of generic parameters for use in the search index.
+///
+/// This function replaces bounds with types, so that `T where T: Debug` just becomes `Debug`.
+/// It does return duplicates, and that's intentional, since search queries like `Result<usize, usize>`
+/// are supposed to match only results where both parameters are `usize`.
+fn get_generics(clean_type: &clean::Type) -> Option<Vec<String>> {
     clean_type.generics().and_then(|types| {
         let r = types
             .iter()
             .filter_map(|t| {
-                get_index_type_name(t, false).map(|name| Generic {
-                    name: name.as_str().to_ascii_lowercase(),
-                    defid: t.def_id_full(cache),
-                    idx: None,
-                })
+                get_index_type_name(t, false).map(|name| name.as_str().to_ascii_lowercase())
             })
             .collect::<Vec<_>>();
         if r.is_empty() { None } else { Some(r) }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index a43a5424f04..0583efa92ff 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -95,31 +95,8 @@ crate struct IndexItem {
 /// A type used for the search index.
 #[derive(Debug)]
 crate struct RenderType {
-    ty: Option<DefId>,
-    idx: Option<usize>,
     name: Option<String>,
-    generics: Option<Vec<Generic>>,
-}
-
-/// A type used for the search index.
-#[derive(Debug)]
-crate struct Generic {
-    name: String,
-    defid: Option<DefId>,
-    idx: Option<usize>,
-}
-
-impl Serialize for Generic {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        if let Some(id) = self.idx {
-            serializer.serialize_some(&id)
-        } else {
-            serializer.serialize_some(&self.name)
-        }
-    }
+    generics: Option<Vec<String>>,
 }
 
 /// Full type of functions/methods in the search index.
@@ -173,7 +150,13 @@ impl Serialize for TypeWithKind {
     where
         S: Serializer,
     {
-        (&self.ty.name, self.kind).serialize(serializer)
+        let mut seq = serializer.serialize_seq(None)?;
+        seq.serialize_element(&self.ty.name)?;
+        seq.serialize_element(&self.kind)?;
+        if let Some(generics) = &self.ty.generics {
+            seq.serialize_element(generics)?;
+        }
+        seq.end()
     }
 }
 
@@ -1694,6 +1677,7 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) {
             write!(
                 buffer,
                 "<div class=\"block version\">\
+                     <div class=\"narrow-helper\"></div>\
                      <p>Version {}</p>\
                  </div>",
                 Escape(version),
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 0174bfec32d..ea141c51048 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -29,6 +29,9 @@ use crate::html::highlight;
 use crate::html::layout::Page;
 use crate::html::markdown::MarkdownSummaryLine;
 
+const ITEM_TABLE_OPEN: &'static str = "<div class=\"item-table\">";
+const ITEM_TABLE_CLOSE: &'static str = "</div>";
+
 pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, page: &Page<'_>) {
     debug_assert!(!item.is_stripped());
     // Write the breadcrumb trail header for the top
@@ -263,14 +266,15 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
             curty = myty;
         } else if myty != curty {
             if curty.is_some() {
-                w.write_str("</table>");
+                w.write_str(ITEM_TABLE_CLOSE);
             }
             curty = myty;
             let (short, name) = item_ty_to_strs(myty.unwrap());
             write!(
                 w,
                 "<h2 id=\"{id}\" class=\"section-header\">\
-                       <a href=\"#{id}\">{name}</a></h2>\n<table>",
+                       <a href=\"#{id}\">{name}</a></h2>\n{}",
+                ITEM_TABLE_OPEN,
                 id = cx.derive_id(short.to_owned()),
                 name = name
             );
@@ -283,14 +287,14 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
                 match *src {
                     Some(ref src) => write!(
                         w,
-                        "<tr><td><code>{}extern crate {} as {};",
+                        "<div class=\"item-left\"><code>{}extern crate {} as {};",
                         myitem.visibility.print_with_space(myitem.def_id, cx),
                         anchor(myitem.def_id.expect_real(), &*src.as_str(), cx),
                         myitem.name.as_ref().unwrap(),
                     ),
                     None => write!(
                         w,
-                        "<tr><td><code>{}extern crate {};",
+                        "<div class=\"item-left\"><code>{}extern crate {};",
                         myitem.visibility.print_with_space(myitem.def_id, cx),
                         anchor(
                             myitem.def_id.expect_real(),
@@ -299,7 +303,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
                         ),
                     ),
                 }
-                w.write_str("</code></td></tr>");
+                w.write_str("</code></div>");
             }
 
             clean::ImportItem(ref import) => {
@@ -326,10 +330,10 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
 
                 write!(
                     w,
-                    "<tr class=\"{stab}{add}import-item\">\
-                         <td><code>{vis}{imp}</code></td>\
-                         <td class=\"docblock-short\">{stab_tags}</td>\
-                     </tr>",
+                    "<div class=\"item-left {stab}{add}import-item\">\
+                         <code>{vis}{imp}</code>\
+                     </div>\
+                     <div class=\"item-right docblock-short\">{stab_tags}</div>",
                     stab = stab.unwrap_or_default(),
                     add = add,
                     vis = myitem.visibility.print_with_space(myitem.def_id, cx),
@@ -358,11 +362,12 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
                 let doc_value = myitem.doc_value().unwrap_or_default();
                 write!(
                     w,
-                    "<tr class=\"{stab}{add}module-item\">\
-                         <td><a class=\"{class}\" href=\"{href}\" \
-                             title=\"{title}\">{name}</a>{unsafety_flag}</td>\
-                         <td class=\"docblock-short\">{stab_tags}{docs}</td>\
-                     </tr>",
+                    "<div class=\"item-left {stab}{add}module-item\">\
+                         <a class=\"{class}\" href=\"{href}\" title=\"{title}\">{name}</a>\
+                             {unsafety_flag}\
+                             {stab_tags}\
+                     </div>\
+                     <div class=\"item-right docblock-short\">{docs}</div>",
                     name = *myitem.name.as_ref().unwrap(),
                     stab_tags = extra_info_tags(myitem, item, cx.tcx()),
                     docs = MarkdownSummaryLine(&doc_value, &myitem.links(cx)).into_string(),
@@ -382,7 +387,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
     }
 
     if curty.is_some() {
-        w.write_str("</table>");
+        w.write_str(ITEM_TABLE_CLOSE);
     }
 }
 
diff --git a/src/librustdoc/html/static/normalize.css b/src/librustdoc/html/static/normalize.css
index 0e042627918..fdb8a8c652e 100644
--- a/src/librustdoc/html/static/normalize.css
+++ b/src/librustdoc/html/static/normalize.css
@@ -1,2 +1,2 @@
 /* ignore-tidy-linelength */
-/*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
+/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 9e1fcb929c5..71123aa9a0e 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -146,9 +146,15 @@ h1.fqn > .in-band > a:hover {
 h2, h3, h4 {
 	border-bottom: 1px solid;
 }
-.impl, .impl-items .method,
-.impl-items .type, .impl-items .associatedconstant,
-.impl-items .associatedtype {
+.impl,
+.impl-items .method,
+.methods .method,
+.impl-items .type,
+.methods .type,
+.impl-items .associatedconstant,
+.methods .associatedconstant,
+.impl-items .associatedtype,
+.methods .associatedtype {
 	flex-basis: 100%;
 	font-weight: 600;
 	margin-top: 16px;
@@ -169,6 +175,7 @@ div.impl-items > div {
 h1, h2, h3, h4,
 .sidebar, a.source, .search-input, .search-results .result-name,
 .content table td:first-child > a,
+.item-left > a,
 div.item-list .out-of-band, span.since,
 #source-sidebar, #sidebar-toggle,
 details.rustdoc-toggle > summary::before,
@@ -199,6 +206,33 @@ summary {
 	outline: none;
 }
 
+/* Fix some style changes due to normalize.css 8 */
+
+td,
+th {
+	padding: 0;
+}
+
+table {
+	border-collapse: collapse;
+}
+
+button,
+input,
+optgroup,
+select,
+textarea {
+	color: inherit;
+	font: inherit;
+	margin: 0;
+}
+
+/* end tweaks for normalize.css 8 */
+
+details:not(.rustdoc-toggle) summary {
+	margin-bottom: .6em;
+}
+
 code, pre, a.test-arrow {
 	font-family: "Source Code Pro", monospace;
 }
@@ -710,6 +744,25 @@ a {
 
 .block a.current.crate { font-weight: 500; }
 
+.item-table {
+	display: grid;
+	column-gap: 1.2rem;
+	row-gap: 0.0rem;
+	grid-template-columns: auto 1fr;
+	/* align content left */
+	justify-items: start;
+}
+
+.item-left, .item-right {
+	display: block;
+}
+.item-left {
+	grid-column: 1;
+}
+.item-right {
+	grid-column: 2;
+}
+
 .search-container {
 	position: relative;
 }
@@ -877,10 +930,6 @@ body.blur > :not(#help) {
 	display: inline;
 }
 
-.stab summary {
-	display: list-item;
-}
-
 .stab .emoji {
 	font-size: 1.5em;
 }
@@ -901,7 +950,7 @@ body.blur > :not(#help) {
 	font-size: 80%;
 	line-height: 1.2;
 	margin-bottom: 0;
-	margin-right: .3em;
+	margin-left: .3em;
 	padding: 2px;
 	vertical-align: text-bottom;
 }
@@ -1599,9 +1648,25 @@ details.undocumented[open] > summary::before {
 	}
 
 	.sidebar > .block.version {
+		overflow: hidden;
 		border-bottom: none;
-		margin-top: 12px;
 		margin-bottom: 0;
+		height: 100%;
+		padding-left: 12px;
+	}
+	.sidebar > .block.version > div.narrow-helper {
+		float: left;
+		width: 1px;
+		height: 100%;
+	}
+	.sidebar > .block.version > p {
+		/* hide Version text if too narrow */
+		margin: 0;
+		min-width: 55px;
+		/* vertically center */
+		display: flex;
+		align-items: center;
+		height: 100%;
 	}
 
 	nav.sub {
@@ -1737,6 +1802,16 @@ details.undocumented[open] > summary::before {
 	#help-button {
 		display: none;
 	}
+
+	/* Display an alternating layout on tablets and phones */
+	.item-table {
+		display: flex;
+		flex-flow: column wrap;
+	}
+	.item-left, .item-right {
+		width: 100%;
+	}
+
 	.search-container > div {
 		width: calc(100% - 32px);
 	}
@@ -1749,7 +1824,7 @@ details.undocumented[open] > summary::before {
 	.search-results .result-name, .search-results div.desc, .search-results .result-description {
 		width: 100%;
 	}
-	.search-results div.desc, .search-results .result-description {
+	.search-results div.desc, .search-results .result-description, .item-right {
 		padding-left: 2em;
 	}
 }
diff --git a/src/librustdoc/html/static/search.js b/src/librustdoc/html/static/search.js
index 617c79a4579..a7fc0b831f4 100644
--- a/src/librustdoc/html/static/search.js
+++ b/src/librustdoc/html/static/search.js
@@ -73,7 +73,7 @@ function removeEmptyStringsFromArray(x) {
  * Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported
  * Full License can be found at http://creativecommons.org/licenses/by-sa/3.0/legalcode
  * This code is an unmodified version of the code written by Marco de Wit
- * and was found at http://stackoverflow.com/a/18514751/745719
+ * and was found at https://stackoverflow.com/a/18514751/745719
  */
 var levenshtein_row2 = [];
 function levenshtein(s1, s2) {
@@ -106,7 +106,7 @@ function levenshtein(s1, s2) {
 window.initSearch = function(rawSearchIndex) {
     var MAX_LEV_DISTANCE = 3;
     var MAX_RESULTS = 200;
-    var GENERICS_DATA = 1;
+    var GENERICS_DATA = 2;
     var NAME = 0;
     var INPUTS_DATA = 0;
     var OUTPUT_DATA = 1;
@@ -306,6 +306,9 @@ window.initSearch = function(rawSearchIndex) {
                     var elems = Object.create(null);
                     var elength = obj[GENERICS_DATA].length;
                     for (var x = 0; x < elength; ++x) {
+                        if (!elems[getObjectNameFromId(obj[GENERICS_DATA][x])]) {
+                            elems[getObjectNameFromId(obj[GENERICS_DATA][x])] = 0;
+                        }
                         elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1;
                     }
                     var total = 0;
@@ -354,10 +357,13 @@ window.initSearch = function(rawSearchIndex) {
                 if (literalSearch) {
                     if (val.generics && val.generics.length !== 0) {
                         if (obj.length > GENERICS_DATA &&
-                              obj[GENERICS_DATA].length >= val.generics.length) {
+                             obj[GENERICS_DATA].length > 0) {
                             var elems = Object.create(null);
                             len = obj[GENERICS_DATA].length;
                             for (x = 0; x < len; ++x) {
+                                if (!elems[getObjectNameFromId(obj[GENERICS_DATA][x])]) {
+                                    elems[getObjectNameFromId(obj[GENERICS_DATA][x])] = 0;
+                                }
                                 elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1;
                             }
 
@@ -375,26 +381,23 @@ window.initSearch = function(rawSearchIndex) {
                             if (allFound) {
                                 return true;
                             }
-                        } else {
-                            return false;
                         }
+                        return false;
                     }
                     return true;
-                }
-                // If the type has generics but don't match, then it won't return at this point.
-                // Otherwise, `checkGenerics` will return 0 and it'll return.
-                if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length !== 0) {
-                    var tmp_lev = checkGenerics(obj, val);
-                    if (tmp_lev <= MAX_LEV_DISTANCE) {
-                        return tmp_lev;
-                    }
                 } else {
-                    return 0;
+                    // If the type has generics but don't match, then it won't return at this point.
+                    // Otherwise, `checkGenerics` will return 0 and it'll return.
+                    if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length !== 0) {
+                        var tmp_lev = checkGenerics(obj, val);
+                        if (tmp_lev <= MAX_LEV_DISTANCE) {
+                            return tmp_lev;
+                        }
+                    }
                 }
-            }
-            // Names didn't match so let's check if one of the generic types could.
-            if (literalSearch) {
-                 if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) {
+            } else if (literalSearch) {
+                if ((!val.generics || val.generics.length === 0) &&
+                      obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) {
                     return obj[GENERICS_DATA].some(
                         function(name) {
                             return name === val.name;
@@ -801,7 +804,8 @@ window.initSearch = function(rawSearchIndex) {
                     results_returned[fullId].lev =
                         Math.min(results_returned[fullId].lev, returned);
                 }
-                if (index !== -1 || lev <= MAX_LEV_DISTANCE) {
+                if (typePassesFilter(typeFilter, ty.ty) &&
+                        (index !== -1 || lev <= MAX_LEV_DISTANCE)) {
                     if (index !== -1 && paths.length < 2) {
                         lev = 0;
                     }
@@ -1058,14 +1062,14 @@ window.initSearch = function(rawSearchIndex) {
         return "<button>" + text + " <div class=\"count\">(" + nbElems + ")</div></button>";
     }
 
-    function showResults(results) {
+    function showResults(results, go_to_first) {
         var search = searchState.outputElement();
-        if (results.others.length === 1
+        if (go_to_first || (results.others.length === 1
             && getSettingValue("go-to-only-result") === "true"
             // By default, the search DOM element is "empty" (meaning it has no children not
             // text content). Once a search has been run, it won't be empty, even if you press
             // ESC or empty the search input (which also "cancels" the search).
-            && (!search.firstChild || search.firstChild.innerText !== searchState.loadingText))
+            && (!search.firstChild || search.firstChild.innerText !== searchState.loadingText)))
         {
             var elem = document.createElement("a");
             elem.href = results.others[0].href;
@@ -1166,7 +1170,48 @@ window.initSearch = function(rawSearchIndex) {
             return ret;
         }
 
-        var queries = query.raw.split(",");
+        // Split search query by ",", while respecting angle bracket nesting.
+        // Since "<" is an alias for the Ord family of traits, it also uses
+        // lookahead to distinguish "<"-as-less-than from "<"-as-angle-bracket.
+        //
+        // tokenizeQuery("A<B, C>, D") == ["A<B, C>", "D"]
+        // tokenizeQuery("A<B, C, D") == ["A<B", "C", "D"]
+        function tokenizeQuery(raw) {
+            var i, matched;
+            var l = raw.length;
+            var depth = 0;
+            var nextAngle = /(<|>)/g;
+            var ret = [];
+            var start = 0;
+            for (i = 0; i < l; ++i) {
+                switch (raw[i]) {
+                    case "<":
+                        nextAngle.lastIndex = i + 1;
+                        matched = nextAngle.exec(raw);
+                        if (matched && matched[1] === '>') {
+                            depth += 1;
+                        }
+                        break;
+                    case ">":
+                        if (depth > 0) {
+                            depth -= 1;
+                        }
+                        break;
+                    case ",":
+                        if (depth === 0) {
+                            ret.push(raw.substring(start, i));
+                            start = i + 1;
+                        }
+                        break;
+                }
+            }
+            if (start !== i) {
+                ret.push(raw.substring(start, i));
+            }
+            return ret;
+        }
+
+        var queries = tokenizeQuery(query.raw);
         var results = {
             "in_args": [],
             "returned": [],
@@ -1242,7 +1287,7 @@ window.initSearch = function(rawSearchIndex) {
         }
 
         var filterCrates = getFilterCrates();
-        showResults(execSearch(query, index, filterCrates));
+        showResults(execSearch(query, index, filterCrates), params.go_to_first);
     }
 
     function buildIndex(rawSearchIndex) {
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 7086dd8c4d2..b89a266a695 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -328,9 +328,10 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
     fn from_tcx(predicate: clean::WherePredicate, tcx: TyCtxt<'_>) -> Self {
         use clean::WherePredicate::*;
         match predicate {
-            BoundPredicate { ty, bounds } => WherePredicate::BoundPredicate {
+            BoundPredicate { ty, bounds, .. } => WherePredicate::BoundPredicate {
                 ty: ty.into_tcx(tcx),
                 bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
+                // FIXME: add `bound_params` to rustdoc-json-params?
             },
             RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate {
                 lifetime: lifetime.0.to_string(),
@@ -372,14 +373,35 @@ impl FromWithTcx<clean::Type> for Type {
     fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
         use clean::Type::*;
         match ty {
-            ResolvedPath { path, param_names, did, is_generic: _ } => Type::ResolvedPath {
+            ResolvedPath { path, did, is_generic: _ } => Type::ResolvedPath {
                 name: path.whole_name(),
                 id: from_def_id(did.into()),
                 args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
-                param_names: param_names
-                    .map(|v| v.into_iter().map(|x| x.into_tcx(tcx)).collect())
-                    .unwrap_or_default(),
+                param_names: Vec::new(),
             },
+            DynTrait(mut bounds, lt) => {
+                let (path, id) = match bounds.remove(0).trait_ {
+                    ResolvedPath { path, did, .. } => (path, did),
+                    _ => unreachable!(),
+                };
+
+                Type::ResolvedPath {
+                    name: path.whole_name(),
+                    id: from_def_id(id.into()),
+                    args: path
+                        .segments
+                        .last()
+                        .map(|args| Box::new(args.clone().args.into_tcx(tcx))),
+                    param_names: bounds
+                        .into_iter()
+                        .map(|t| {
+                            clean::GenericBound::TraitBound(t, rustc_hir::TraitBoundModifier::None)
+                        })
+                        .chain(lt.into_iter().map(|lt| clean::GenericBound::Outlives(lt)))
+                        .map(|bound| bound.into_tcx(tcx))
+                        .collect(),
+                }
+            }
             Generic(s) => Type::Generic(s.to_string()),
             Primitive(p) => Type::Primitive(p.as_sym().to_string()),
             BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))),
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index ee7a716655b..64a9905b33f 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -31,7 +31,6 @@ extern crate tracing;
 // Dependencies listed in Cargo.toml do not need `extern crate`.
 
 extern crate rustc_ast;
-extern crate rustc_ast_lowering;
 extern crate rustc_ast_pretty;
 extern crate rustc_attr;
 extern crate rustc_data_structures;
@@ -714,6 +713,7 @@ fn main_options(options: config::Options) -> MainResult {
     let default_passes = options.default_passes;
     let output_format = options.output_format;
     // FIXME: fix this clone (especially render_options)
+    let externs = options.externs.clone();
     let manual_passes = options.manual_passes.clone();
     let render_options = options.render_options.clone();
     let config = core::create_config(options);
@@ -731,7 +731,7 @@ fn main_options(options: config::Options) -> MainResult {
             // We need to hold on to the complete resolver, so we cause everything to be
             // cloned for the analysis passes to use. Suboptimal, but necessary in the
             // current architecture.
-            let resolver = core::create_resolver(queries, &sess);
+            let resolver = core::create_resolver(externs, queries, &sess);
 
             if sess.has_errors() {
                 sess.fatal("Compilation failed, aborting rustdoc");
diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs
index 376c83b1a6e..49d8d7fb7fb 100644
--- a/src/librustdoc/lint.rs
+++ b/src/librustdoc/lint.rs
@@ -193,7 +193,7 @@ crate fn register_lints(_sess: &Session, lint_store: &mut LintStore) {
     );
     for lint in &*RUSTDOC_LINTS {
         let name = lint.name_lower();
-        lint_store.register_alias(&name.replace("rustdoc::", ""), &name);
+        lint_store.register_renamed(&name.replace("rustdoc::", ""), &name);
     }
     lint_store
         .register_renamed("intra_doc_link_resolution_failure", "rustdoc::broken_intra_doc_links");
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index c7e2ce74019..1113d610128 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -37,9 +37,6 @@ use crate::html::markdown::{markdown_links, MarkdownLink};
 use crate::lint::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS};
 use crate::passes::Pass;
 
-mod early;
-crate use early::IntraLinkCrateLoader;
-
 crate const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
     name: "collect-intra-doc-links",
     run: collect_intra_doc_links,
diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs
deleted file mode 100644
index 7cba2523d1a..00000000000
--- a/src/librustdoc/passes/collect_intra_doc_links/early.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-use rustc_ast as ast;
-use rustc_hir::def::Namespace::TypeNS;
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
-use rustc_interface::interface;
-
-use std::cell::RefCell;
-use std::mem;
-use std::rc::Rc;
-
-// Letting the resolver escape at the end of the function leads to inconsistencies between the
-// crates the TyCtxt sees and the resolver sees (because the resolver could load more crates
-// after escaping). Hopefully `IntraLinkCrateLoader` gets all the crates we need ...
-crate struct IntraLinkCrateLoader {
-    current_mod: DefId,
-    crate resolver: Rc<RefCell<interface::BoxedResolver>>,
-}
-
-impl IntraLinkCrateLoader {
-    crate fn new(resolver: Rc<RefCell<interface::BoxedResolver>>) -> Self {
-        let crate_id = LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id();
-        Self { current_mod: crate_id, resolver }
-    }
-}
-
-impl ast::visit::Visitor<'_> for IntraLinkCrateLoader {
-    fn visit_attribute(&mut self, attr: &ast::Attribute) {
-        use crate::html::markdown::markdown_links;
-        use crate::passes::collect_intra_doc_links::preprocess_link;
-
-        if let Some(doc) = attr.doc_str() {
-            for link in markdown_links(&doc.as_str()) {
-                let path_str = if let Some(Ok(x)) = preprocess_link(&link) {
-                    x.path_str
-                } else {
-                    continue;
-                };
-                self.resolver.borrow_mut().access(|resolver| {
-                    let _ = resolver.resolve_str_path_error(
-                        attr.span,
-                        &path_str,
-                        TypeNS,
-                        self.current_mod,
-                    );
-                });
-            }
-        }
-        ast::visit::walk_attribute(self, attr);
-    }
-
-    fn visit_item(&mut self, item: &ast::Item) {
-        use rustc_ast_lowering::ResolverAstLowering;
-
-        if let ast::ItemKind::Mod(..) = item.kind {
-            let new_mod =
-                self.resolver.borrow_mut().access(|resolver| resolver.local_def_id(item.id));
-            let old_mod = mem::replace(&mut self.current_mod, new_mod.to_def_id());
-            ast::visit::walk_item(self, item);
-            self.current_mod = old_mod;
-        } else {
-            ast::visit::walk_item(self, item);
-        }
-    }
-}
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 6d7c45f6eea..8280bbf0858 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -29,7 +29,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
 
     let mut new_items = Vec::new();
 
-    for &cnum in cx.tcx.crates().iter() {
+    for &cnum in cx.tcx.crates(()).iter() {
         for &(did, _) in cx.tcx.all_trait_implementations(cnum).iter() {
             cx.tcx.sess.prof.generic_activity("build_extern_trait_impl").run(|| {
                 inline::build_impl(cx, None, did, None, &mut new_items);
@@ -85,7 +85,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
         }
     });
 
-    // `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations`
+    // `tcx.crates(())` doesn't include the local crate, and `tcx.all_trait_implementations`
     // doesn't work with it anyway, so pull them from the HIR map instead
     let mut extra_attrs = Vec::new();
     for &trait_did in cx.tcx.all_traits(()).iter() {
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 0e86fe45640..390ab1694a0 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -30,7 +30,7 @@ crate use self::unindent_comments::UNINDENT_COMMENTS;
 mod propagate_doc_cfg;
 crate use self::propagate_doc_cfg::PROPAGATE_DOC_CFG;
 
-crate mod collect_intra_doc_links;
+mod collect_intra_doc_links;
 crate use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS;
 
 mod doc_test_lints;
diff --git a/src/stage0.txt b/src/stage0.txt
index 1027057f385..e9d0b73e94d 100644
--- a/src/stage0.txt
+++ b/src/stage0.txt
@@ -12,7 +12,7 @@
 # stable release's version number. `date` is the date where the release we're
 # bootstrapping off was released.
 
-date: 2021-05-23
+date: 2021-06-23
 rustc: beta
 
 # We use a nightly rustfmt to format the source because it solves some
diff --git a/src/test/assembly/asm/mips-types.rs b/src/test/assembly/asm/mips-types.rs
index 60cfebdd992..9ec7ba83c42 100644
--- a/src/test/assembly/asm/mips-types.rs
+++ b/src/test/assembly/asm/mips-types.rs
@@ -2,8 +2,9 @@
 // revisions: mips32 mips64
 // assembly-output: emit-asm
 //[mips32] compile-flags: --target mips-unknown-linux-gnu
+//[mips32] needs-llvm-components: mips
 //[mips64] compile-flags: --target mips64-unknown-linux-gnuabi64
-// needs-llvm-components: mips
+//[mips64] needs-llvm-components: mips
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd)]
 #![crate_type = "rlib"]
diff --git a/src/test/assembly/asm/powerpc-types.rs b/src/test/assembly/asm/powerpc-types.rs
index 742e4ddaed6..1e263649e86 100644
--- a/src/test/assembly/asm/powerpc-types.rs
+++ b/src/test/assembly/asm/powerpc-types.rs
@@ -2,8 +2,9 @@
 // revisions: powerpc powerpc64
 // assembly-output: emit-asm
 //[powerpc] compile-flags: --target powerpc-unknown-linux-gnu
+//[powerpc] needs-llvm-components: powerpc
 //[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
-// needs-llvm-components: powerpc
+//[powerpc64] needs-llvm-components: powerpc
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd)]
 #![crate_type = "rlib"]
diff --git a/src/test/assembly/asm/riscv-types.rs b/src/test/assembly/asm/riscv-types.rs
index 1ba73fcac9d..e62a6197b9a 100644
--- a/src/test/assembly/asm/riscv-types.rs
+++ b/src/test/assembly/asm/riscv-types.rs
@@ -2,9 +2,10 @@
 // revisions: riscv64 riscv32
 // assembly-output: emit-asm
 //[riscv64] compile-flags: --target riscv64imac-unknown-none-elf
+//[riscv64] needs-llvm-components: riscv
 //[riscv32] compile-flags: --target riscv32imac-unknown-none-elf
+//[riscv32] needs-llvm-components: riscv
 // compile-flags: -C target-feature=+d
-// needs-llvm-components: riscv
 // min-system-llvm-version: 12.0
 
 #![feature(no_core, lang_items, rustc_attrs)]
diff --git a/src/test/assembly/asm/x86-modifiers.rs b/src/test/assembly/asm/x86-modifiers.rs
index da2dc51d69e..c926fd7b3f5 100644
--- a/src/test/assembly/asm/x86-modifiers.rs
+++ b/src/test/assembly/asm/x86-modifiers.rs
@@ -3,7 +3,9 @@
 // assembly-output: emit-asm
 // compile-flags: -O
 //[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
+//[x86_64] needs-llvm-components: x86
 //[i686] compile-flags: --target i686-unknown-linux-gnu
+//[i686] needs-llvm-components: x86
 // compile-flags: -C llvm-args=--x86-asm-syntax=intel
 // compile-flags: -C target-feature=+avx512bw
 
diff --git a/src/test/assembly/asm/x86-types.rs b/src/test/assembly/asm/x86-types.rs
index b65b727d225..d25f3a03777 100644
--- a/src/test/assembly/asm/x86-types.rs
+++ b/src/test/assembly/asm/x86-types.rs
@@ -2,7 +2,9 @@
 // revisions: x86_64 i686
 // assembly-output: emit-asm
 //[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
+//[x86_64] needs-llvm-components: x86
 //[i686] compile-flags: --target i686-unknown-linux-gnu
+//[i686] needs-llvm-components: x86
 // compile-flags: -C llvm-args=--x86-asm-syntax=intel
 // compile-flags: -C target-feature=+avx512bw
 
diff --git a/src/test/assembly/static-relocation-model.rs b/src/test/assembly/static-relocation-model.rs
index 2cd74a01c84..b331d45668a 100644
--- a/src/test/assembly/static-relocation-model.rs
+++ b/src/test/assembly/static-relocation-model.rs
@@ -1,10 +1,12 @@
 // min-llvm-version: 12.0.0
-// needs-llvm-components: aarch64 x86 powerpc
 // revisions: x64 A64 ppc64le
 // assembly-output: emit-asm
 // [x64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=static
+// [x64] needs-llvm-components: x86
 // [A64] compile-flags: --target aarch64-unknown-linux-gnu -Crelocation-model=static
+// [A64] needs-llvm-components: aarch64
 // [ppc64le] compile-flags: --target powerpc64le-unknown-linux-gnu -Crelocation-model=static
+// [ppc64le] needs-llvm-components: powerpc
 
 #![feature(no_core, lang_items)]
 #![no_core]
diff --git a/src/test/codegen/abi-efiapi.rs b/src/test/codegen/abi-efiapi.rs
index 613b0bf50e5..b4fda5f8c84 100644
--- a/src/test/codegen/abi-efiapi.rs
+++ b/src/test/codegen/abi-efiapi.rs
@@ -1,13 +1,16 @@
 // Checks if the correct annotation for the efiapi ABI is passed to llvm.
 
 // revisions:x86_64 i686 aarch64 arm riscv
-// needs-llvm-components: aarch64 arm riscv
-
 //[x86_64] compile-flags: --target x86_64-unknown-uefi
+//[x86_64] needs-llvm-components: aarch64 arm riscv
 //[i686] compile-flags: --target i686-unknown-linux-musl
+//[i686] needs-llvm-components: aarch64 arm riscv
 //[aarch64] compile-flags: --target aarch64-unknown-none
+//[aarch64] needs-llvm-components: aarch64 arm riscv
 //[arm] compile-flags: --target armv7r-none-eabi
+//[arm] needs-llvm-components: aarch64 arm riscv
 //[riscv] compile-flags: --target riscv64gc-unknown-none-elf
+//[riscv] needs-llvm-components: aarch64 arm riscv
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/asm-options.rs b/src/test/codegen/asm-options.rs
index 70391661b0c..28df0f9b852 100644
--- a/src/test/codegen/asm-options.rs
+++ b/src/test/codegen/asm-options.rs
@@ -94,3 +94,10 @@ pub unsafe fn dont_remove_nonpure() {
     asm!("", options(nomem));
     asm!("", options(readonly));
 }
+
+// CHECK-LABEL: @raw
+// CHECK: call void asm sideeffect inteldialect "{} {}", ""()
+#[no_mangle]
+pub unsafe fn raw() {
+    asm!("{} {}", options(nostack, nomem, preserves_flags, raw));
+}
diff --git a/src/test/codegen/asm-sanitize-llvm.rs b/src/test/codegen/asm-sanitize-llvm.rs
index fe09caa6973..135177016bf 100644
--- a/src/test/codegen/asm-sanitize-llvm.rs
+++ b/src/test/codegen/asm-sanitize-llvm.rs
@@ -1,5 +1,6 @@
-// FIXME(nagisa): remove the flags here once all targets support `asm!`.
+// FIXME(nagisa): remove the flags below once all targets support `asm!`.
 // compile-flags: --target x86_64-unknown-linux-gnu
+// needs-llvm-components: x86
 
 // Verify we sanitize the special tokens for the LLVM inline-assembly, ensuring people won't
 // inadvertently rely on the LLVM-specific syntax and features.
diff --git a/src/test/codegen/async-fn-debug-msvc.rs b/src/test/codegen/async-fn-debug-msvc.rs
index e410180bfff..8efa1b15b3f 100644
--- a/src/test/codegen/async-fn-debug-msvc.rs
+++ b/src/test/codegen/async-fn-debug-msvc.rs
@@ -17,7 +17,7 @@ async fn async_fn_test() {
 // FIXME: No way to reliably check the filename.
 
 // CHECK-DAG:  [[ASYNC_FN:!.*]] = !DINamespace(name: "async_fn_test"
-// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0"
+// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator$0"
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
 // For brevity, we only check the struct name and members of the last variant.
 // CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
diff --git a/src/test/codegen/async-fn-debug.rs b/src/test/codegen/async-fn-debug.rs
index 7de115f7e91..39319a3ea72 100644
--- a/src/test/codegen/async-fn-debug.rs
+++ b/src/test/codegen/async-fn-debug.rs
@@ -17,7 +17,7 @@ async fn async_fn_test() {
 // FIXME: No way to reliably check the filename.
 
 // CHECK-DAG:  [[ASYNC_FN:!.*]] = !DINamespace(name: "async_fn_test"
-// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[ASYNC_FN]]
+// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{generator#0}", scope: [[ASYNC_FN]]
 // CHECK:      [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[ASYNC_FN]],
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: discriminator: [[DISC:![0-9]*]]
diff --git a/src/test/codegen/default-requires-uwtable.rs b/src/test/codegen/default-requires-uwtable.rs
index d4c4200c5d2..5d77d3f14bb 100644
--- a/src/test/codegen/default-requires-uwtable.rs
+++ b/src/test/codegen/default-requires-uwtable.rs
@@ -1,8 +1,9 @@
 // revisions: WINDOWS ANDROID
-// needs-llvm-components: x86 arm
 // compile-flags: -C panic=abort
 // [WINDOWS] compile-flags: --target=x86_64-pc-windows-msvc
+// [WINDOWS] needs-llvm-components: x86
 // [ANDROID] compile-flags: --target=armv7-linux-androideabi
+// [ANDROID] needs-llvm-components: arm
 
 #![feature(no_core, lang_items)]
 #![crate_type = "lib"]
diff --git a/src/test/codegen/fn-impl-trait-self.rs b/src/test/codegen/fn-impl-trait-self.rs
index f9113d50197..4bd811bed10 100644
--- a/src/test/codegen/fn-impl-trait-self.rs
+++ b/src/test/codegen/fn-impl-trait-self.rs
@@ -1,7 +1,8 @@
 // compile-flags: -g
 //
 // CHECK-LABEL: @main
-// CHECK: {{.*}}DIDerivedType(tag: DW_TAG_pointer_type, name: "fn() -> <recursive_type>",{{.*}}
+// MSVC: {{.*}}DIDerivedType(tag: DW_TAG_pointer_type, name: "recursive_type$ (*)()",{{.*}}
+// NONMSVC: {{.*}}DIDerivedType(tag: DW_TAG_pointer_type, name: "fn() -> <recursive_type>",{{.*}}
 //
 // CHECK: {{.*}}DISubroutineType{{.*}}
 // CHECK: {{.*}}DIBasicType(name: "<recur_type>", encoding: DW_ATE_unsigned)
diff --git a/src/test/codegen/frame-pointer.rs b/src/test/codegen/frame-pointer.rs
new file mode 100644
index 00000000000..367591dcb96
--- /dev/null
+++ b/src/test/codegen/frame-pointer.rs
@@ -0,0 +1,35 @@
+// compile-flags: --crate-type=rlib
+// revisions: aarch64-apple aarch64-linux force x64-apple x64-linux
+// [aarch64-apple] needs-llvm-components: aarch64
+// [aarch64-apple] compile-flags: --target=aarch64-apple-darwin
+// [aarch64-linux] needs-llvm-components: aarch64
+// [aarch64-linux] compile-flags: --target=aarch64-unknown-linux-gnu
+// [force] needs-llvm-components: x86
+// [force] compile-flags: --target=x86_64-unknown-linux-gnu -Cforce-frame-pointers=yes
+// [x64-apple] needs-llvm-components: x86
+// [x64-apple] compile-flags: --target=x86_64-apple-darwin
+// [x64-linux] needs-llvm-components: x86
+// [x64-linux] compile-flags: --target=x86_64-unknown-linux-gnu
+
+#![feature(no_core, lang_items)]
+#![no_core]
+#[lang="sized"]
+trait Sized { }
+#[lang="copy"]
+trait Copy { }
+
+
+
+// CHECK: define i32 @peach{{.*}}[[PEACH_ATTRS:\#[0-9]+]] {
+#[no_mangle]
+pub fn peach(x: u32) -> u32 {
+    x
+}
+
+// CHECK: attributes [[PEACH_ATTRS]] = {
+// x64-linux-NOT: {{.*}}"frame-pointer"{{.*}}
+// aarch64-linux-NOT: {{.*}}"frame-pointer"{{.*}}
+// x64-apple-SAME: {{.*}}"frame-pointer"="all"
+// force-SAME: {{.*}}"frame-pointer"="all"
+// aarch64-apple-SAME: {{.*}}"frame-pointer"="non-leaf"
+// CHECK-SAME: }
diff --git a/src/test/codegen/generator-debug-msvc.rs b/src/test/codegen/generator-debug-msvc.rs
index 7edb07d224c..e2ba4ad3089 100644
--- a/src/test/codegen/generator-debug-msvc.rs
+++ b/src/test/codegen/generator-debug-msvc.rs
@@ -21,7 +21,7 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
 // FIXME: No way to reliably check the filename.
 
 // CHECK-DAG:  [[GEN_FN:!.*]] = !DINamespace(name: "generator_test"
-// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator-0"
+// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator$0"
 // CHECK:      {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
 // For brevity, we only check the struct name and members of the last variant.
 // CHECK-SAME: file: [[FILE:![0-9]*]], line: 14,
diff --git a/src/test/codegen/generator-debug.rs b/src/test/codegen/generator-debug.rs
index 8b87a2f0646..ea324695c15 100644
--- a/src/test/codegen/generator-debug.rs
+++ b/src/test/codegen/generator-debug.rs
@@ -21,7 +21,7 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
 // FIXME: No way to reliably check the filename.
 
 // CHECK-DAG:  [[GEN_FN:!.*]] = !DINamespace(name: "generator_test"
-// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[GEN_FN]]
+// CHECK-DAG:  [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{generator#0}", scope: [[GEN_FN]]
 // CHECK:      [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[GEN_FN]],
 // CHECK-NOT:  flags: DIFlagArtificial
 // CHECK-SAME: discriminator: [[DISC:![0-9]*]]
diff --git a/src/test/codegen/i686-macosx-deployment-target.rs b/src/test/codegen/i686-macosx-deployment-target.rs
index dad376d6677..17258a264a5 100644
--- a/src/test/codegen/i686-macosx-deployment-target.rs
+++ b/src/test/codegen/i686-macosx-deployment-target.rs
@@ -3,6 +3,7 @@
 // See issue #60235.
 
 // compile-flags: -O --target=i686-apple-darwin --crate-type=rlib
+// needs-llvm-components: x86
 // rustc-env:MACOSX_DEPLOYMENT_TARGET=10.9
 #![feature(no_core, lang_items)]
 #![no_core]
diff --git a/src/test/codegen/i686-no-macosx-deployment-target.rs b/src/test/codegen/i686-no-macosx-deployment-target.rs
index 1cebc49236f..043040a95e3 100644
--- a/src/test/codegen/i686-no-macosx-deployment-target.rs
+++ b/src/test/codegen/i686-no-macosx-deployment-target.rs
@@ -3,6 +3,7 @@
 // See issue #60235.
 
 // compile-flags: -O --target=i686-apple-darwin --crate-type=rlib
+// needs-llvm-components: x86
 // unset-rustc-env:MACOSX_DEPLOYMENT_TARGET
 #![feature(no_core, lang_items)]
 #![no_core]
diff --git a/src/test/codegen/sparc-struct-abi.rs b/src/test/codegen/sparc-struct-abi.rs
index 78e5b14a212..f228d7c5500 100644
--- a/src/test/codegen/sparc-struct-abi.rs
+++ b/src/test/codegen/sparc-struct-abi.rs
@@ -1,9 +1,8 @@
-//
 // Checks that we correctly codegen extern "C" functions returning structs.
 // See issue #52638.
 
-// only-sparc64
 // compile-flags: -O --target=sparc64-unknown-linux-gnu --crate-type=rlib
+// needs-llvm-components: sparc
 #![feature(no_core, lang_items)]
 #![no_core]
 
diff --git a/src/test/codegen/x86_64-macosx-deployment-target.rs b/src/test/codegen/x86_64-macosx-deployment-target.rs
index 8e291b7b298..8e673d11d98 100644
--- a/src/test/codegen/x86_64-macosx-deployment-target.rs
+++ b/src/test/codegen/x86_64-macosx-deployment-target.rs
@@ -3,6 +3,7 @@
 // See issue #60235.
 
 // compile-flags: -O --target=x86_64-apple-darwin --crate-type=rlib
+// needs-llvm-components: x86
 // rustc-env:MACOSX_DEPLOYMENT_TARGET=10.9
 #![feature(no_core, lang_items)]
 #![no_core]
diff --git a/src/test/codegen/x86_64-no-macosx-deployment-target.rs b/src/test/codegen/x86_64-no-macosx-deployment-target.rs
index c5ac73b54e1..25ae6924de0 100644
--- a/src/test/codegen/x86_64-no-macosx-deployment-target.rs
+++ b/src/test/codegen/x86_64-no-macosx-deployment-target.rs
@@ -3,6 +3,7 @@
 // See issue #60235.
 
 // compile-flags: -O --target=x86_64-apple-darwin --crate-type=rlib
+// needs-llvm-components: x86
 // unset-rustc-env:MACOSX_DEPLOYMENT_TARGET
 #![feature(no_core, lang_items)]
 #![no_core]
diff --git a/src/test/debuginfo/basic-types.rs b/src/test/debuginfo/basic-types.rs
index 3721b87678d..c35c3255498 100644
--- a/src/test/debuginfo/basic-types.rs
+++ b/src/test/debuginfo/basic-types.rs
@@ -6,9 +6,8 @@
 
 // min-lldb-version: 310
 
-// This fails on lldb 6.0.1 on x86-64 Fedora 28; so mark it macOS-only
-// for now.
-// only-macos
+// This fails on lldb 6.0.1 on x86-64 Fedora 28; so ignore Linux for now.
+// ignore-linux
 
 // compile-flags:-g
 
@@ -44,6 +43,9 @@
 // gdb-check:$13 = 2.5
 // gdb-command:print f64
 // gdb-check:$14 = 3.5
+// gdb-command:print s
+// gdbg-check:$15 = {data_ptr = [...] "Hello, World!", length = 13}
+// gdbr-check:$15 = "Hello, World!"
 
 
 // === LLDB TESTS ==================================================================================
@@ -94,6 +96,41 @@
 // lldbg-check:[...]$12 = 3.5
 // lldbr-check:(f64) f64 = 3.5
 
+
+// === CDB TESTS ===================================================================================
+
+// cdb-command:g
+// cdb-command:dx b
+// cdb-check:b                : false [Type: bool]
+// cdb-command:dx i
+// cdb-check:i                : -1 [Type: [...]]
+// The variable 'c' doesn't appear for some reason...
+// cdb-command:dx i8
+// cdb-check:i8               : 68 [Type: char]
+// cdb-command:dx i16
+// cdb-check:i16              : -16 [Type: short]
+// cdb-command:dx i32
+// cdb-check:i32              : -32 [Type: int]
+// cdb-command:dx i64
+// cdb-check:i64              : -64 [Type: __int64]
+// cdb-command:dx u
+// cdb-check:u                : 0x1 [Type: [...]]
+// cdb-command:dx u8
+// cdb-check:u8               : 0x64 [Type: unsigned char]
+// cdb-command:dx u16
+// cdb-check:u16              : 0x10 [Type: unsigned short]
+// cdb-command:dx u32
+// cdb-check:u32              : 0x20 [Type: unsigned int]
+// cdb-command:dx u64
+// cdb-check:u64              : 0x40 [Type: unsigned __int64]
+// cdb-command:dx f32
+// cdb-check:f32              : 2.500000 [Type: float]
+// cdb-command:dx f64
+// cdb-check:f64              : 3.500000 [Type: double]
+// cdb-command:.enable_unicode 1
+// cdb-command:dx  s
+// cdb-check:s                : "Hello, World!" [Type: str]
+
 #![allow(unused_variables)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
@@ -113,6 +150,7 @@ fn main() {
     let u64: u64 = 64;
     let f32: f32 = 2.5;
     let f64: f64 = 3.5;
+    let s: &str = "Hello, World!";
     _zzz(); // #break
 }
 
diff --git a/src/test/debuginfo/fixed-sized-array.rs b/src/test/debuginfo/fixed-sized-array.rs
new file mode 100644
index 00000000000..d8899224d28
--- /dev/null
+++ b/src/test/debuginfo/fixed-sized-array.rs
@@ -0,0 +1,39 @@
+// Testing the display of fixed sized arrays in cdb.
+
+// cdb-only
+// min-cdb-version: 10.0.18317.1001
+// compile-flags:-g
+
+// === CDB TESTS ==================================================================================
+
+// cdb-command: g
+
+// cdb-command: dx xs,d
+// cdb-check:xs,d             [Type: int [5]]
+// cdb-check:    [0]              : 1 [Type: int]
+// cdb-check:    [1]              : 2 [Type: int]
+// cdb-check:    [2]              : 3 [Type: int]
+// cdb-check:    [3]              : 4 [Type: int]
+// cdb-check:    [4]              : 5 [Type: int]
+
+// cdb-command: dx ys,d
+// cdb-check:ys,d             [Type: int [3]]
+// cdb-check:    [0]              : 0 [Type: int]
+// cdb-check:    [1]              : 0 [Type: int]
+// cdb-check:    [2]              : 0 [Type: int]
+
+fn main() {
+    // Fixed-size array (type signature is superfluous)
+    let xs: [i32; 5] = [1, 2, 3, 4, 5];
+
+    // All elements can be initialized to the same value
+    let ys: [i32; 3] = [0; 3];
+
+    // Indexing starts at 0
+    println!("first element of the array: {}", xs[0]);
+    println!("second element of the array: {}", xs[1]);
+
+    zzz(); // #break
+}
+
+fn zzz() { () }
diff --git a/src/test/debuginfo/function-names.rs b/src/test/debuginfo/function-names.rs
new file mode 100644
index 00000000000..26317f5c3ff
--- /dev/null
+++ b/src/test/debuginfo/function-names.rs
@@ -0,0 +1,175 @@
+// Function names are formatted differently in old versions of GDB
+// min-gdb-version: 9.2
+
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// Top-level function
+// gdb-command:info functions -q function_names::main
+// gdb-check:[...]static fn function_names::main();
+// gdb-command:info functions -q function_names::generic_func<*
+// gdb-check:[...]static fn function_names::generic_func(i32) -> i32;
+
+// Implementations
+// gdb-command:info functions -q function_names::.*::impl_function.*
+// gdb-check:[...]static fn function_names::GenericStruct<T1,T2>::impl_function();
+// gdb-check:[...]static fn function_names::Mod1::TestStruct2::impl_function();
+// gdb-check:[...]static fn function_names::TestStruct1::impl_function();
+
+// Trait implementations
+// gdb-command:info functions -q function_names::.*::trait_function.*
+// gdb-check:[...]static fn <function_names::GenericStruct<T,i32> as function_names::TestTrait1>::trait_function();
+// gdb-check:[...]static fn <function_names::GenericStruct<[T; N],f32> as function_names::TestTrait1>::trait_function();
+// gdb-check:[...]static fn <function_names::Mod1::TestStruct2 as function_names::Mod1::TestTrait2>::trait_function();
+// gdb-check:[...]static fn <function_names::TestStruct1 as function_names::TestTrait1>::trait_function();
+
+// Closure
+// gdb-command:info functions -q function_names::.*::{{closure.*
+// gdb-check:[...]static fn function_names::GenericStruct<T1,T2>::impl_function::{{closure}}(*mut function_names::{impl#2}::impl_function::{closure#0});
+// gdb-check:[...]static fn function_names::generic_func::{{closure}}(*mut function_names::generic_func::{closure#0});
+// gdb-check:[...]static fn function_names::main::{{closure}}(*mut function_names::main::{closure#0});
+
+// Generator
+// Generators don't seem to appear in GDB's symbol table.
+
+// === CDB TESTS ===================================================================================
+
+// Top-level function
+// cdb-command:x a!function_names::main
+// cdb-check:[...] a!function_names::main (void)
+// cdb-command:x a!function_names::generic_func<*
+// cdb-check:[...] a!function_names::generic_func<i32> (int)
+
+// Implementations
+// cdb-command:x a!function_names::*::impl_function*
+// cdb-check:[...] a!function_names::Mod1::TestStruct2::impl_function (void)
+// cdb-check:[...] a!function_names::TestStruct1::impl_function (void)
+// cdb-check:[...] a!function_names::GenericStruct<i32, i32>::impl_function<i32, i32> (void)
+
+// Trait implementations
+// cdb-command:x a!function_names::*::trait_function*
+// cdb-check:[...] a!function_names::impl$6::trait_function<i32, 0x1> (void)
+// cdb-check:[...] a!function_names::impl$3::trait_function<i32> (void)
+// cdb-check:[...] a!function_names::impl$1::trait_function (void)
+// cdb-check:[...] a!function_names::impl$5::trait_function3<function_names::TestStruct1> (void)
+// cdb-check:[...] a!function_names::Mod1::impl$1::trait_function (void)
+
+// Closure
+// cdb-command:x a!function_names::*::closure*
+// cdb-check:[...] a!function_names::main::closure$0 (void)
+// cdb-check:[...] a!function_names::generic_func::closure$0<i32> (void)
+// cdb-check:[...] a!function_names::impl$2::impl_function::closure$0<i32, i32> (void)
+
+// Generator
+// cdb-command:x a!function_names::*::generator*
+// cdb-check:[...] a!function_names::main::generator$1 (void)
+
+#![allow(unused_variables)]
+#![feature(omit_gdb_pretty_printer_section)]
+#![omit_gdb_pretty_printer_section]
+#![feature(generators, generator_trait)]
+
+use Mod1::TestTrait2;
+use std::ops::Generator;
+use std::pin::Pin;
+
+fn main() {
+    // Implementations
+    TestStruct1::impl_function();
+    Mod1::TestStruct2::impl_function();
+    GenericStruct::<i32, i32>::impl_function();
+
+    // Trait implementations
+    TestStruct1::trait_function();
+    Mod1::TestStruct2::trait_function();
+    GenericStruct::<i32, i32>::trait_function();
+    GenericStruct::<[i32; 1], f32>::trait_function();
+    GenericStruct::<TestStruct1, usize>::trait_function3();
+
+    // Generic function
+    let _ = generic_func(42);
+
+    // Closure
+    let closure = || { TestStruct1 };
+    closure();
+
+    // Generator
+    let mut generator = || { yield; return; };
+    Pin::new(&mut generator).resume(());
+}
+
+struct TestStruct1;
+trait TestTrait1 {
+    fn trait_function();
+}
+
+// Implementation
+impl TestStruct1 {
+    pub fn impl_function() {}
+}
+
+// Implementation for a trait
+impl TestTrait1 for TestStruct1 {
+    fn trait_function() {}
+}
+
+// Implementation and implementation within a mod
+mod Mod1 {
+    pub struct TestStruct2;
+    pub trait TestTrait2 {
+        fn trait_function();
+    }
+
+    impl TestStruct2 {
+        pub fn impl_function() {}
+    }
+
+    impl TestTrait2 for TestStruct2 {
+        fn trait_function() {}
+    }
+}
+
+struct GenericStruct<T1, T2>(std::marker::PhantomData<(T1, T2)>);
+
+// Generic implementation
+impl<T1, T2> GenericStruct<T1, T2> {
+    pub fn impl_function() {
+        // Closure in a generic implementation
+        let closure = || { TestStruct1 };
+        closure();
+    }
+}
+
+// Generic trait implementation
+impl<T> TestTrait1 for GenericStruct<T, i32> {
+    fn trait_function() {}
+}
+
+// Implementation based on associated type
+trait TestTrait3 {
+    type AssocType;
+    fn trait_function3();
+}
+impl TestTrait3 for TestStruct1 {
+    type AssocType = usize;
+    fn trait_function3() {}
+}
+impl<T: TestTrait3> TestTrait3 for GenericStruct<T, T::AssocType> {
+    type AssocType = T::AssocType;
+    fn trait_function3() {}
+}
+
+// Generic trait implementation with const generics
+impl<T, const N: usize> TestTrait1 for GenericStruct<[T; N], f32> {
+    fn trait_function() {}
+}
+
+// Generic function
+fn generic_func<T>(value: T) -> T {
+    // Closure in a generic function
+    let closure = || { TestStruct1 };
+    closure();
+
+    value
+}
diff --git a/src/test/debuginfo/generator-objects.rs b/src/test/debuginfo/generator-objects.rs
index 1beed1c835d..7ac3304aa96 100644
--- a/src/test/debuginfo/generator-objects.rs
+++ b/src/test/debuginfo/generator-objects.rs
@@ -11,31 +11,31 @@
 
 // gdb-command:run
 // gdb-command:print b
-// gdb-check:$1 = generator_objects::main::generator-0::Unresumed(0x[...])
+// gdb-check:$1 = generator_objects::main::{generator#0}::Unresumed(0x[...])
 // gdb-command:continue
 // gdb-command:print b
-// gdb-check:$2 = generator_objects::main::generator-0::Suspend0{c: 6, d: 7, __0: 0x[...]}
+// gdb-check:$2 = generator_objects::main::{generator#0}::Suspend0{c: 6, d: 7, __0: 0x[...]}
 // gdb-command:continue
 // gdb-command:print b
-// gdb-check:$3 = generator_objects::main::generator-0::Suspend1{c: 7, d: 8, __0: 0x[...]}
+// gdb-check:$3 = generator_objects::main::{generator#0}::Suspend1{c: 7, d: 8, __0: 0x[...]}
 // gdb-command:continue
 // gdb-command:print b
-// gdb-check:$4 = generator_objects::main::generator-0::Returned(0x[...])
+// gdb-check:$4 = generator_objects::main::{generator#0}::Returned(0x[...])
 
 // === LLDB TESTS ==================================================================================
 
 // lldb-command:run
 // lldb-command:print b
-// lldbg-check:(generator_objects::main::generator-0) $0 =
+// lldbg-check:(generator_objects::main::{generator#0}) $0 =
 // lldb-command:continue
 // lldb-command:print b
-// lldbg-check:(generator_objects::main::generator-0) $1 =
+// lldbg-check:(generator_objects::main::{generator#0}) $1 =
 // lldb-command:continue
 // lldb-command:print b
-// lldbg-check:(generator_objects::main::generator-0) $2 =
+// lldbg-check:(generator_objects::main::{generator#0}) $2 =
 // lldb-command:continue
 // lldb-command:print b
-// lldbg-check:(generator_objects::main::generator-0) $3 =
+// lldbg-check:(generator_objects::main::{generator#0}) $3 =
 
 #![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
 #![omit_gdb_pretty_printer_section]
diff --git a/src/test/debuginfo/generic-struct.rs b/src/test/debuginfo/generic-struct.rs
index 170a610c621..c0135de1219 100644
--- a/src/test/debuginfo/generic-struct.rs
+++ b/src/test/debuginfo/generic-struct.rs
@@ -39,6 +39,27 @@
 // lldbg-check:[...]$3 = AGenericStruct<f64, generic_struct::AGenericStruct<i32, f64>> { key: 6.5, value: AGenericStruct<i32, f64> { key: 7, value: 8.5 } }
 // lldbr-check:(generic_struct::AGenericStruct<f64, generic_struct::AGenericStruct<i32, f64>>) float_int_float = AGenericStruct<f64, generic_struct::AGenericStruct<i32, f64>> { key: 6.5, value: AGenericStruct<i32, f64> { key: 7, value: 8.5 } }
 
+// === CDB TESTS ===================================================================================
+
+// cdb-command:g
+
+// cdb-command:dx int_int
+// cdb-check:int_int          [Type: generic_struct::AGenericStruct<i32, i32>]
+// cdb-check:[...]key              : 0 [Type: int]
+// cdb-check:[...]value            : 1 [Type: int]
+// cdb-command:dx int_float
+// cdb-check:int_float        [Type: generic_struct::AGenericStruct<i32, f64>]
+// cdb-check:[...]key              : 2 [Type: int]
+// cdb-check:[...]value            : 3.500000 [Type: double]
+// cdb-command:dx float_int
+// cdb-check:float_int        [Type: generic_struct::AGenericStruct<f64, i32>]
+// cdb-check:[...]key              : 4.500000 [Type: double]
+// cdb-check:[...]value            : 5 [Type: int]
+// cdb-command:dx float_int_float
+// cdb-check:float_int_float  [Type: generic_struct::AGenericStruct<f64, generic_struct::AGenericStruct<i32, f64> >]
+// cdb-check:[...]key              : 6.500000 [Type: double]
+// cdb-check:[...]value            [Type: generic_struct::AGenericStruct<i32, f64>]
+
 
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
diff --git a/src/test/debuginfo/issue-57822.rs b/src/test/debuginfo/issue-57822.rs
index 6b2b12edda5..f6d2146fe11 100644
--- a/src/test/debuginfo/issue-57822.rs
+++ b/src/test/debuginfo/issue-57822.rs
@@ -11,20 +11,20 @@
 // gdb-command:run
 
 // gdb-command:print g
-// gdb-check:$1 = issue_57822::main::closure-1 (issue_57822::main::closure-0 (1))
+// gdb-check:$1 = issue_57822::main::{closure#1} (issue_57822::main::{closure#0} (1))
 
 // gdb-command:print b
-// gdb-check:$2 = issue_57822::main::generator-3::Unresumed(issue_57822::main::generator-2::Unresumed(2))
+// gdb-check:$2 = issue_57822::main::{generator#3}::Unresumed(issue_57822::main::{generator#2}::Unresumed(2))
 
 // === LLDB TESTS ==================================================================================
 
 // lldb-command:run
 
 // lldb-command:print g
-// lldbg-check:(issue_57822::main::closure-1) $0 = { 0 = { 0 = 1 } }
+// lldbg-check:(issue_57822::main::{closure#1}) $0 = { 0 = { 0 = 1 } }
 
 // lldb-command:print b
-// lldbg-check:(issue_57822::main::generator-3) $1 =
+// lldbg-check:(issue_57822::main::{generator#3}) $1 =
 
 #![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
 #![omit_gdb_pretty_printer_section]
diff --git a/src/test/debuginfo/msvc-pretty-enums.rs b/src/test/debuginfo/msvc-pretty-enums.rs
index 550cc66f389..cf3be2e7196 100644
--- a/src/test/debuginfo/msvc-pretty-enums.rs
+++ b/src/test/debuginfo/msvc-pretty-enums.rs
@@ -1,5 +1,4 @@
 // only-cdb
-// ignore-tidy-linelength
 // compile-flags:-g
 
 // cdb-command: g
@@ -8,16 +7,16 @@
 //       so the best we can do is to make sure we are generating the right debuginfo
 
 // cdb-command: dx -r2 a,!
-// cdb-check:a,!              [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum>>, 2, 16, Some>]
-// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum>>, 2, 16, Some>::Some]
+// cdb-check:a,!              [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>]
+// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>::Some]
 // cdb-check:        [+0x000] __0              : Low (0x2) [Type: msvc_pretty_enums::CStyleEnum]
-// cdb-check:    [+0x000] discriminant     : 0x2 [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum>>, 2, 16, Some>::Discriminant$]
+// cdb-check:    [+0x000] discriminant     : 0x2 [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>::Discriminant$]
 
 // cdb-command: dx -r2 b,!
-// cdb-check:b,!              [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum>>, 2, 16, Some>]
-// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum>>, 2, 16, Some>::Some]
+// cdb-check:b,!              [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>]
+// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>::Some]
 // cdb-check:        [+0x000] __0              : 0x11 [Type: msvc_pretty_enums::CStyleEnum]
-// cdb-check:    [+0x000] discriminant     : None (0x11) [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum>>, 2, 16, Some>::Discriminant$]
+// cdb-check:    [+0x000] discriminant     : None (0x11) [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>::Discriminant$]
 
 // cdb-command: dx -r2 c,!
 // cdb-check:c,!              [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>]
@@ -38,24 +37,24 @@
 // cdb-check:    [+0x000] discriminant     : Tag2 (0x13) [Type: enum$<msvc_pretty_enums::NicheLayoutEnum, 2, 16, Data>::Discriminant$]
 
 // cdb-command: dx -r2 f,!
-// cdb-check:f,!              [Type: enum$<core::option::Option<u32*>, 1, [...], Some>]
-// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<u32*>, 1, [...], Some>::Some]
+// cdb-check:f,!              [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
+// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Some]
 // cdb-check:        [+0x000] __0              : 0x[...] : 0x1 [Type: unsigned int *]
-// cdb-check:    [+0x000] discriminant     : 0x[...] [Type: enum$<core::option::Option<u32*>, 1, [...], Some>::Discriminant$]
+// cdb-check:    [+0x000] discriminant     : 0x[...] [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Discriminant$]
 
 // cdb-command: dx -r2 g,!
-// cdb-check:g,!              [Type: enum$<core::option::Option<u32*>, 1, [...], Some>]
-// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<u32*>, 1, [...], Some>::Some]
+// cdb-check:g,!              [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>]
+// cdb-check:    [+0x000] dataful_variant  [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Some]
 // cdb-check:        [+0x000] __0              : 0x0 [Type: unsigned int *]
-// cdb-check:    [+0x000] discriminant     : None (0x0) [Type: enum$<core::option::Option<u32*>, 1, [...], Some>::Discriminant$]
+// cdb-check:    [+0x000] discriminant     : None (0x0) [Type: enum$<core::option::Option<ref$<u32> >, 1, [...], Some>::Discriminant$]
 
 // cdb-command: dx h
-// cdb-check:h                : Some [Type: enum$<core::option::Option<u32>>]
+// cdb-check:h                : Some [Type: enum$<core::option::Option<u32> >]
 // cdb-check:    [+0x000] variant$         : Some (0x1) [Type: core::option::Option]
 // cdb-check:    [+0x004] __0              : 0xc [Type: unsigned int]
 
 // cdb-command: dx i
-// cdb-check:i                : None [Type: enum$<core::option::Option<u32>>]
+// cdb-check:i                : None [Type: enum$<core::option::Option<u32> >]
 // cdb-check:    [+0x000] variant$         : None (0x0) [Type: core::option::Option]
 
 // cdb-command: dx j
diff --git a/src/test/debuginfo/mutable-locs.rs b/src/test/debuginfo/mutable-locs.rs
new file mode 100644
index 00000000000..428a7e8d9c0
--- /dev/null
+++ b/src/test/debuginfo/mutable-locs.rs
@@ -0,0 +1,51 @@
+// Testing the display of Cell, RefCell, and RefMut in cdb.
+
+// cdb-only
+// min-cdb-version: 10.0.18317.1001
+// compile-flags:-g
+
+// === CDB TESTS ==================================================================================
+
+// cdb-command: g
+
+// cdb-command:dx static_c,d
+// cdb-check:static_c,d       [Type: core::cell::Cell<i32>]
+// cdb-check:    [...] value            [Type: core::cell::UnsafeCell<i32>]
+
+// cdb-command: dx static_c.value,d
+// cdb-check:static_c.value,d [Type: core::cell::UnsafeCell<i32>]
+// cdb-check:    [...] value            : 10 [Type: int]
+
+// cdb-command:  dx dynamic_c,d
+// cdb-check:dynamic_c,d      [Type: core::cell::RefCell<i32>]
+// cdb-check:    [...] borrow           [Type: core::cell::Cell<isize>]
+// cdb-check:    [...] value            [Type: core::cell::UnsafeCell<i32>]
+
+// cdb-command: dx dynamic_c.value,d
+// cdb-check:dynamic_c.value,d [Type: core::cell::UnsafeCell<i32>]
+// cdb-check:    [...] value            : 15 [Type: int]
+
+// cdb-command: dx b,d
+// cdb-check:b,d              [Type: core::cell::RefMut<i32>]
+// cdb-check:    [...] value            : [...] : 42 [Type: int *]
+// cdb-check:    [...] borrow           [Type: core::cell::BorrowRefMut]
+
+#![allow(unused_variables)]
+
+use std::cell::{Cell, RefCell};
+
+fn main() {
+    let static_c = Cell::new(5);
+    static_c.set(10);
+
+    let dynamic_c = RefCell::new(5);
+    dynamic_c.replace(15);
+
+    let dynamic_c_0 = RefCell::new(15);
+    let mut b = dynamic_c_0.borrow_mut();
+    *b = 42;
+
+    zzz(); // #break
+}
+
+fn zzz() {()}
diff --git a/src/test/debuginfo/mutex.rs b/src/test/debuginfo/mutex.rs
new file mode 100644
index 00000000000..40bea30f125
--- /dev/null
+++ b/src/test/debuginfo/mutex.rs
@@ -0,0 +1,38 @@
+// Testing the display of Mutex and MutexGuard in cdb.
+
+// cdb-only
+// min-cdb-version: 10.0.21287.1005
+// compile-flags:-g
+
+// === CDB TESTS ==================================================================================
+//
+// cdb-command:g
+//
+// cdb-command:dx m,d
+// cdb-check:m,d              [Type: std::sync::mutex::Mutex<i32>]
+// cdb-check:    [...] inner            [Type: std::sys_common::mutex::MovableMutex]
+// cdb-check:    [...] poison           [Type: std::sync::poison::Flag]
+// cdb-check:    [...] data             [Type: core::cell::UnsafeCell<i32>]
+
+//
+// cdb-command:dx m.data,d
+// cdb-check:m.data,d         [Type: core::cell::UnsafeCell<i32>]
+// cdb-check:    [...] value            : 0 [Type: int]
+
+//
+// cdb-command:dx lock,d
+// cdb-check:lock,d           : Ok [Type: enum$<core::result::Result<std::sync::mutex::MutexGuard<i32>, enum$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> >, 0, 1, Poisoned> > >]
+// cdb-check:    [...] variant$         : Ok (0) [Type: core::result::Result]
+// cdb-check:    [...] __0              [Type: std::sync::mutex::MutexGuard<i32>]
+
+use std::sync::Mutex;
+
+#[allow(unused_variables)]
+fn main()
+{
+    let m = Mutex::new(0);
+    let lock = m.try_lock();
+    zzz(); // #break
+}
+
+fn zzz() {}
diff --git a/src/test/debuginfo/pretty-std-collections-hash.rs b/src/test/debuginfo/pretty-std-collections-hash.rs
index 7115aec1041..ede15578712 100644
--- a/src/test/debuginfo/pretty-std-collections-hash.rs
+++ b/src/test/debuginfo/pretty-std-collections-hash.rs
@@ -77,6 +77,8 @@
 // cdb-command: dx hash_map,d
 // cdb-check:    ["0xe"]          : 14 [Type: unsigned __int64]
 
+// cdb-command: dx x
+
 #![allow(unused_variables)]
 use std::collections::HashSet;
 use std::collections::HashMap;
@@ -95,6 +97,9 @@ fn main() {
         hash_map.insert(i as u64, i as u64);
     }
 
+    let x = &(123u64, 456u64);
+    let string = "awefawefawe".to_string();
+
     zzz(); // #break
 }
 
diff --git a/src/test/debuginfo/pretty-std.rs b/src/test/debuginfo/pretty-std.rs
index 68e73b5f38d..a7f384c0500 100644
--- a/src/test/debuginfo/pretty-std.rs
+++ b/src/test/debuginfo/pretty-std.rs
@@ -1,10 +1,10 @@
 // ignore-freebsd: gdb package too new
 // only-cdb // "Temporarily" ignored on GDB/LLDB due to debuginfo tests being disabled, see PR 47155
 // ignore-android: FIXME(#10381)
-// ignore-tidy-linelength
 // compile-flags:-g
 // min-gdb-version: 7.7
 // min-lldb-version: 310
+// min-cdb-version: 10.0.18317.1001
 
 // === GDB TESTS ===================================================================================
 
@@ -71,8 +71,12 @@
 // cdb-command: g
 
 // cdb-command: dx slice,d
-// cdb-check:slice,d [...]
-// NOTE: While slices have a .natvis entry that works in VS & VS Code, it fails in CDB 10.0.18362.1
+// cdb-check:slice,d          : { len=4 } [Type: slice$<i32>]
+// cdb-check:    [len]            : 4 [Type: [...]]
+// cdb-check:    [0]              : 0 [Type: int]
+// cdb-check:    [1]              : 1 [Type: int]
+// cdb-check:    [2]              : 2 [Type: int]
+// cdb-check:    [3]              : 3 [Type: int]
 
 // cdb-command: dx vec,d
 // cdb-check:vec,d [...] : { len=4 } [Type: [...]::Vec<u64, alloc::alloc::Global>]
@@ -84,8 +88,7 @@
 // cdb-check:    [3]              : 7 [Type: unsigned __int64]
 
 // cdb-command: dx str_slice
-// cdb-check:str_slice [...]
-// NOTE: While string slices have a .natvis entry that works in VS & VS Code, it fails in CDB
+// cdb-check:str_slice        : "IAMA string slice!" [Type: str]
 
 // cdb-command: dx string
 // cdb-check:string           : "IAMA string!" [Type: [...]::String]
@@ -112,10 +115,16 @@
 // NOTE: OsString doesn't have a .natvis entry yet.
 
 // cdb-command: dx some
-// cdb-check:some             : Some [Type: enum$<core::option::Option<i16>>]
+// cdb-check:some             : Some [Type: enum$<core::option::Option<i16> >]
+// cdb-check:    [...] variant$         : Some (0x1) [Type: core::option::Option]
+// cdb-check:    [...] __0              : 8 [Type: short]
+
 // cdb-command: dx none
-// cdb-check:none             : None [Type: enum$<core::option::Option<i64>>]
+// cdb-check:none             : None [Type: enum$<core::option::Option<i64> >]
+// cdb-check:    [...] variant$         : None (0x0) [Type: core::option::Option]
+
 // cdb-command: dx some_string
+// NOTE: cdb fails to interpret debug info of Option enums on i686.
 // cdb-check:some_string      [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>]
 
 #![allow(unused_variables)]
diff --git a/src/test/debuginfo/range-types.rs b/src/test/debuginfo/range-types.rs
new file mode 100644
index 00000000000..c0288b6ba80
--- /dev/null
+++ b/src/test/debuginfo/range-types.rs
@@ -0,0 +1,47 @@
+// Testing the display of range types in cdb.
+
+// cdb-only
+// min-cdb-version: 10.0.18317.1001
+// compile-flags:-g
+
+// === CDB TESTS ==================================================================================
+
+// cdb-command: g
+
+// cdb-command: dx r1,d
+// cdb-check:r1,d             [Type: core::ops::range::Range<i32>]
+// cdb-check:    [...] start            : 3 [Type: int]
+// cdb-check:    [...] end              : 5 [Type: int]
+
+// cdb-command: dx r2,d
+// cdb-check:r2,d             [Type: core::ops::range::RangeFrom<i32>]
+// cdb-check:    [...] start            : 2 [Type: int]
+
+// cdb-command: dx r3,d
+// cdb-check:r3,d             [Type: core::ops::range::RangeInclusive<i32>]
+// cdb-check:    [...] start            : 1 [Type: int]
+// cdb-check:    [...] end              : 4 [Type: int]
+// cdb-check:    [...] exhausted        : false [Type: bool]
+
+// cdb-command: dx r4,d
+// cdb-check:r4,d             [Type: core::ops::range::RangeToInclusive<i32>]
+// cdb-check:    [...] end              : 3 [Type: int]
+
+// cdb-command: dx r5,d
+// cdb-check:r5,d             [Type: core::ops::range::RangeFull]
+
+#[allow(unused_variables)]
+
+use std::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeToInclusive};
+
+fn main()
+{
+    let r1 = Range{start: 3, end: 5};
+    let r2 = RangeFrom{start: 2};
+    let r3 = RangeInclusive::new(1, 4);
+    let r4 = RangeToInclusive{end: 3};
+    let r5 = RangeFull{};
+    zzz(); // #break
+}
+
+fn zzz() { () }
diff --git a/src/test/debuginfo/rc_arc.rs b/src/test/debuginfo/rc_arc.rs
index 87bc79ea794..6e558bd3c13 100644
--- a/src/test/debuginfo/rc_arc.rs
+++ b/src/test/debuginfo/rc_arc.rs
@@ -1,7 +1,8 @@
-// ignore-windows pretty-printers are not loaded
+// pretty-printers are not loaded
 // compile-flags:-g
 
 // min-gdb-version: 8.1
+// min-cdb-version: 10.0.18317.1001
 
 // === GDB TESTS ==================================================================================
 
@@ -22,6 +23,29 @@
 // lldb-command:print a
 // lldb-check:[...]$1 = strong=2, weak=1 { data = 42 }
 
+// === CDB TESTS ==================================================================================
+
+// cdb-command:g
+
+// cdb-command:dx r,d
+// cdb-check:r,d              : 42 [Type: alloc::rc::Rc<i32>]
+
+// cdb-command:dx r1,d
+// cdb-check:r1,d             : 42 [Type: alloc::rc::Rc<i32>]
+
+// cdb-command:dx w1,d
+// cdb-check:w1,d             [Type: alloc::rc::Weak<i32>]
+// cdb-check:    [...] ptr              : [...] [Type: core::ptr::non_null::NonNull<alloc::rc::RcBox<i32> >]
+
+// cdb-command:dx a,d
+// cdb-check:a,d              : 42 [Type: alloc::sync::Arc<i32>]
+
+// cdb-command:dx a1,d
+// cdb-check:a1,d             : 42 [Type: alloc::sync::Arc<i32>]
+
+// cdb-command:dx w2,d
+// cdb-check:w2,d             : 42 [Type: alloc::sync::Weak<i32>]
+
 use std::rc::Rc;
 use std::sync::Arc;
 
diff --git a/src/test/debuginfo/result-types.rs b/src/test/debuginfo/result-types.rs
new file mode 100644
index 00000000000..a075c437c46
--- /dev/null
+++ b/src/test/debuginfo/result-types.rs
@@ -0,0 +1,28 @@
+// cdb-only
+// min-cdb-version: 10.0.18317.1001
+// compile-flags:-g
+
+// === CDB TESTS ==================================================================================
+
+// cdb-command: g
+
+// cdb-command: dx x,d
+// cdb-check:x,d              : Ok [Type: enum$<core::result::Result<i32, str> >]
+// cdb-check:    [...] __0              : -3 [Type: int]
+
+// cdb-command: dx y
+// cdb-check:y                : Err [Type: enum$<core::result::Result<i32, str> >]
+// cdb-check:    [...] __0              : "Some error message" [Type: str]
+
+fn main()
+{
+    let x: Result<i32, &str> = Ok(-3);
+    assert_eq!(x.is_ok(), true);
+
+    let y: Result<i32, &str> = Err("Some error message");
+    assert_eq!(y.is_ok(), false);
+
+    zzz(); // #break.
+}
+
+fn zzz() { () }
diff --git a/src/test/debuginfo/rwlock-read.rs b/src/test/debuginfo/rwlock-read.rs
new file mode 100644
index 00000000000..ac652c8ccf4
--- /dev/null
+++ b/src/test/debuginfo/rwlock-read.rs
@@ -0,0 +1,35 @@
+// Testing the display of RwLock and RwLockReadGuard in cdb.
+
+// cdb-only
+// min-cdb-version: 10.0.18317.1001
+// compile-flags:-g
+
+// === CDB TESTS ==================================================================================
+//
+// cdb-command:g
+//
+// cdb-command:dx l
+// cdb-check:l                [Type: std::sync::rwlock::RwLock<i32>]
+// cdb-check:    [...] poison           [Type: std::sync::poison::Flag]
+// cdb-check:    [...] data             [Type: core::cell::UnsafeCell<i32>]
+//
+// cdb-command:dx r
+// cdb-check:r                [Type: std::sync::rwlock::RwLockReadGuard<i32>]
+// cdb-check:    [...] lock             : [...] [Type: std::sync::rwlock::RwLock<i32> *]
+//
+// cdb-command:dx r.lock->data,d
+// cdb-check:r.lock->data,d   [Type: core::cell::UnsafeCell<i32>]
+// cdb-check:    [...] value            : 0 [Type: int]
+
+#[allow(unused_variables)]
+
+use std::sync::RwLock;
+
+fn main()
+{
+    let l = RwLock::new(0);
+    let r = l.read().unwrap();
+    zzz(); // #break
+}
+
+fn zzz() {}
diff --git a/src/test/debuginfo/rwlock-write.rs b/src/test/debuginfo/rwlock-write.rs
new file mode 100644
index 00000000000..8decf54c177
--- /dev/null
+++ b/src/test/debuginfo/rwlock-write.rs
@@ -0,0 +1,27 @@
+// Testing the display of RwLockWriteGuard.
+
+// cdb-only
+// min-cdb-version: 10.0.18317.1001
+// compile-flags:-g
+
+// === CDB TESTS ==================================================================================
+//
+// cdb-command:g
+//
+// cdb-command:dx w
+// cdb-check:w                [Type: std::sync::rwlock::RwLockWriteGuard<i32>]
+// cdb-check:    [...] lock             : [...] [Type: std::sync::rwlock::RwLock<i32> *]
+// cdb-check:    [...] poison           [Type: std::sync::poison::Guard]
+
+#[allow(unused_variables)]
+
+use std::sync::RwLock;
+
+fn main()
+{
+    let l = RwLock::new(0);
+    let w = l.write().unwrap();
+    zzz(); // #break
+}
+
+fn zzz() {}
diff --git a/src/test/debuginfo/simple-tuple.rs b/src/test/debuginfo/simple-tuple.rs
index b7fcfeef090..0807cfedce0 100644
--- a/src/test/debuginfo/simple-tuple.rs
+++ b/src/test/debuginfo/simple-tuple.rs
@@ -129,38 +129,38 @@
 // cdb-command: g
 
 // cdb-command:dx noPadding8,d
-// cdb-check:noPadding8,d [...]: (-100, 100) [Type: tuple<i8, u8>]
+// cdb-check:noPadding8,d [...]: (-100, 100) [Type: tuple$<i8,u8>]
 // cdb-check:[...][0]              : -100 [Type: [...]]
 // cdb-check:[...][1]              : 100 [Type: [...]]
 // cdb-command:dx noPadding16,d
-// cdb-check:noPadding16,d [...]: (0, 1, 2) [Type: tuple<i16, i16, u16>]
+// cdb-check:noPadding16,d [...]: (0, 1, 2) [Type: tuple$<i16,i16,u16>]
 // cdb-check:[...][0]              : 0 [Type: [...]]
 // cdb-check:[...][1]              : 1 [Type: [...]]
 // cdb-check:[...][2]              : 2 [Type: [...]]
 // cdb-command:dx noPadding32,d
-// cdb-check:noPadding32,d [...]: (3, 4.5[...], 5) [Type: tuple<i32, f32, u32>]
+// cdb-check:noPadding32,d [...]: (3, 4.5[...], 5) [Type: tuple$<i32,f32,u32>]
 // cdb-check:[...][0]              : 3 [Type: [...]]
 // cdb-check:[...][1]              : 4.5[...] [Type: [...]]
 // cdb-check:[...][2]              : 5 [Type: [...]]
 // cdb-command:dx noPadding64,d
-// cdb-check:noPadding64,d [...]: (6, 7.5[...], 8) [Type: tuple<i64, f64, u64>]
+// cdb-check:noPadding64,d [...]: (6, 7.5[...], 8) [Type: tuple$<i64,f64,u64>]
 // cdb-check:[...][0]              : 6 [Type: [...]]
 // cdb-check:[...][1]              : 7.500000 [Type: [...]]
 // cdb-check:[...][2]              : 8 [Type: [...]]
 
 // cdb-command:dx internalPadding1,d
-// cdb-check:internalPadding1,d [...]: (9, 10) [Type: tuple<i16, i32>]
+// cdb-check:internalPadding1,d [...]: (9, 10) [Type: tuple$<i16,i32>]
 // cdb-check:[...][0]              : 9 [Type: short]
 // cdb-check:[...][1]              : 10 [Type: int]
 // cdb-command:dx internalPadding2,d
-// cdb-check:internalPadding2,d [...]: (11, 12, 13, 14) [Type: tuple<i16, i32, u32, u64>]
+// cdb-check:internalPadding2,d [...]: (11, 12, 13, 14) [Type: tuple$<i16,i32,u32,u64>]
 // cdb-check:[...][0]              : 11 [Type: [...]]
 // cdb-check:[...][1]              : 12 [Type: [...]]
 // cdb-check:[...][2]              : 13 [Type: [...]]
 // cdb-check:[...][3]              : 14 [Type: [...]]
 
 // cdb-command:dx paddingAtEnd,d
-// cdb-check:paddingAtEnd,d [...]: (15, 16) [Type: tuple<i32, i16>]
+// cdb-check:paddingAtEnd,d [...]: (15, 16) [Type: tuple$<i32,i16>]
 // cdb-check:[...][0]              : 15 [Type: [...]]
 // cdb-check:[...][1]              : 16 [Type: [...]]
 
diff --git a/src/test/debuginfo/thread.rs b/src/test/debuginfo/thread.rs
new file mode 100644
index 00000000000..531c37a3421
--- /dev/null
+++ b/src/test/debuginfo/thread.rs
@@ -0,0 +1,31 @@
+// Testing the the display of JoinHandle and Thread in cdb.
+
+// cdb-only
+// min-cdb-version: 10.0.18317.1001
+// compile-flags:-g
+
+// === CDB TESTS ==================================================================================
+//
+// cdb-command:g
+//
+// cdb-command:dx join_handle,d
+// cdb-check:join_handle,d    [Type: std::thread::JoinHandle<tuple$<> >]
+// cdb-check:    [...] __0              [Type: std::thread::JoinInner<tuple$<> >]
+//
+// cdb-command:dx t,d
+// cdb-check:t,d              : [...] [Type: std::thread::Thread *]
+// cdb-check:    [...] inner            : {...} [Type: alloc::sync::Arc<std::thread::Inner>]
+
+use std::thread;
+
+#[allow(unused_variables)]
+fn main()
+{
+    let join_handle = thread::spawn(|| {
+        println!("Initialize a thread");
+    });
+    let t = join_handle.thread();
+    zzz(); // #break
+}
+
+fn zzz() {}
diff --git a/src/test/debuginfo/tuple-in-tuple.rs b/src/test/debuginfo/tuple-in-tuple.rs
index 0447d8e9dde..578db74e9ee 100644
--- a/src/test/debuginfo/tuple-in-tuple.rs
+++ b/src/test/debuginfo/tuple-in-tuple.rs
@@ -65,64 +65,64 @@
 // cdb-command: g
 
 // cdb-command:dx no_padding1,d
-// cdb-check:no_padding1,d [...]: ((0, 1), 2, 3) [Type: tuple<tuple<u32, u32>, u32, u32>]
-// cdb-check:[...][0]              : (0, 1) [Type: tuple<u32, u32>]
+// cdb-check:no_padding1,d [...]: ((0, 1), 2, 3) [Type: tuple$<tuple$<u32,u32>,u32,u32>]
+// cdb-check:[...][0]              : (0, 1) [Type: tuple$<u32,u32>]
 // cdb-check:[...][1]              : 2 [Type: [...]]
 // cdb-check:[...][2]              : 3 [Type: [...]]
 // cdb-command:dx no_padding1.__0,d
-// cdb-check:no_padding1.__0,d [...]: (0, 1) [Type: tuple<u32, u32>]
+// cdb-check:no_padding1.__0,d [...]: (0, 1) [Type: tuple$<u32,u32>]
 // cdb-check:[...][0]              : 0 [Type: [...]]
 // cdb-check:[...][1]              : 1 [Type: [...]]
 // cdb-command:dx no_padding2,d
-// cdb-check:no_padding2,d [...]: (4, (5, 6), 7) [Type: tuple<u32, tuple<u32, u32>, u32>]
+// cdb-check:no_padding2,d [...]: (4, (5, 6), 7) [Type: tuple$<u32,tuple$<u32,u32>,u32>]
 // cdb-check:[...][0]              : 4 [Type: [...]]
-// cdb-check:[...][1]              : (5, 6) [Type: tuple<u32, u32>]
+// cdb-check:[...][1]              : (5, 6) [Type: tuple$<u32,u32>]
 // cdb-check:[...][2]              : 7 [Type: [...]]
 // cdb-command:dx no_padding2.__1,d
-// cdb-check:no_padding2.__1,d [...]: (5, 6) [Type: tuple<u32, u32>]
+// cdb-check:no_padding2.__1,d [...]: (5, 6) [Type: tuple$<u32,u32>]
 // cdb-check:[...][0]              : 5 [Type: [...]]
 // cdb-check:[...][1]              : 6 [Type: [...]]
 // cdb-command:dx no_padding3,d
-// cdb-check:no_padding3,d [...]: (8, 9, (10, 11)) [Type: tuple<u32, u32, tuple<u32, u32>>]
+// cdb-check:no_padding3,d [...]: (8, 9, (10, 11)) [Type: tuple$<u32,u32,tuple$<u32,u32> >]
 // cdb-check:[...][0]              : 8 [Type: [...]]
 // cdb-check:[...][1]              : 9 [Type: [...]]
-// cdb-check:[...][2]              : (10, 11) [Type: tuple<u32, u32>]
+// cdb-check:[...][2]              : (10, 11) [Type: tuple$<u32,u32>]
 // cdb-command:dx no_padding3.__2,d
-// cdb-check:no_padding3.__2,d [...]: (10, 11) [Type: tuple<u32, u32>]
+// cdb-check:no_padding3.__2,d [...]: (10, 11) [Type: tuple$<u32,u32>]
 // cdb-check:[...][0]              : 10 [Type: [...]]
 // cdb-check:[...][1]              : 11 [Type: [...]]
 
 // cdb-command:dx internal_padding1,d
-// cdb-check:internal_padding1,d [...]: (12, (13, 14)) [Type: tuple<i16, tuple<i32, i32>>]
+// cdb-check:internal_padding1,d [...]: (12, (13, 14)) [Type: tuple$<i16,tuple$<i32,i32> >]
 // cdb-check:[...][0]              : 12 [Type: [...]]
-// cdb-check:[...][1]              : (13, 14) [Type: tuple<i32, i32>]
+// cdb-check:[...][1]              : (13, 14) [Type: tuple$<i32,i32>]
 // cdb-command:dx internal_padding1.__1,d
-// cdb-check:internal_padding1.__1,d [...]: (13, 14) [Type: tuple<i32, i32>]
+// cdb-check:internal_padding1.__1,d [...]: (13, 14) [Type: tuple$<i32,i32>]
 // cdb-check:[...][0]              : 13 [Type: [...]]
 // cdb-check:[...][1]              : 14 [Type: [...]]
 // cdb-command:dx internal_padding2,d
-// cdb-check:internal_padding2,d [...]: (15, (16, 17)) [Type: tuple<i16, tuple<i16, i32>>]
+// cdb-check:internal_padding2,d [...]: (15, (16, 17)) [Type: tuple$<i16,tuple$<i16,i32> >]
 // cdb-check:[...][0]              : 15 [Type: [...]]
-// cdb-check:[...][1]              : (16, 17) [Type: tuple<i16, i32>]
+// cdb-check:[...][1]              : (16, 17) [Type: tuple$<i16,i32>]
 // cdb-command:dx internal_padding2.__1,d
-// cdb-check:internal_padding2.__1,d [...]: (16, 17) [Type: tuple<i16, i32>]
+// cdb-check:internal_padding2.__1,d [...]: (16, 17) [Type: tuple$<i16,i32>]
 // cdb-check:[...][0]              : 16 [Type: [...]]
 // cdb-check:[...][1]              : 17 [Type: [...]]
 
 // cdb-command:dx padding_at_end1,d
-// cdb-check:padding_at_end1,d [...]: (18, (19, 20)) [Type: tuple<i32, tuple<i32, i16>>]
+// cdb-check:padding_at_end1,d [...]: (18, (19, 20)) [Type: tuple$<i32,tuple$<i32,i16> >]
 // cdb-check:[...][0]              : 18 [Type: [...]]
-// cdb-check:[...][1]              : (19, 20) [Type: tuple<i32, i16>]
+// cdb-check:[...][1]              : (19, 20) [Type: tuple$<i32,i16>]
 // cdb-command:dx padding_at_end1.__1,d
-// cdb-check:padding_at_end1.__1,d [...][Type: tuple<i32, i16>]
+// cdb-check:padding_at_end1.__1,d [...][Type: tuple$<i32,i16>]
 // cdb-check:[...][0]              : 19 [Type: [...]]
 // cdb-check:[...][1]              : 20 [Type: [...]]
 // cdb-command:dx padding_at_end2,d
-// cdb-check:padding_at_end2,d [...]: ((21, 22), 23) [Type: tuple<tuple<i32, i16>, i32>]
-// cdb-check:[...][0]              : (21, 22) [Type: tuple<i32, i16>]
+// cdb-check:padding_at_end2,d [...]: ((21, 22), 23) [Type: tuple$<tuple$<i32,i16>,i32>]
+// cdb-check:[...][0]              : (21, 22) [Type: tuple$<i32,i16>]
 // cdb-check:[...][1]              : 23 [Type: [...]]
 // cdb-command:dx padding_at_end2.__0,d
-// cdb-check:padding_at_end2.__0,d [...]: (21, 22) [Type: tuple<i32, i16>]
+// cdb-check:padding_at_end2.__0,d [...]: (21, 22) [Type: tuple$<i32,i16>]
 // cdb-check:[...][0]              : 21 [Type: [...]]
 // cdb-check:[...][1]              : 22 [Type: [...]]
 
diff --git a/src/test/debuginfo/type-names.cdb.js b/src/test/debuginfo/type-names.cdb.js
new file mode 100644
index 00000000000..8f8b20bfaeb
--- /dev/null
+++ b/src/test/debuginfo/type-names.cdb.js
@@ -0,0 +1,17 @@
+// Helper functions for running the type-names.rs test under CDB
+
+// CDB exposes an "object model" via JavaScript that allows you to inspect debugging info - in this
+// case we want to ask the object model for the return and parameter types for a local variable
+// that is a function pointer to make sure that we are emitting the function pointer type in such a
+// way that CDB understands how to parse it.
+
+"use strict";
+
+function getFunctionDetails(name)
+{
+    var localVariable = host.currentThread.Stack.Frames[0].LocalVariables[name];
+    var functionPointerType = localVariable.targetType.genericArguments[0];
+    var functionType = functionPointerType.baseType;
+    host.diagnostics.debugLog("Return Type: ", functionType.functionReturnType, "\n");
+    host.diagnostics.debugLog("Parameter Types: ", functionType.functionParameterTypes, "\n");
+}
diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs
index cc4a4476d16..d1f322fa76c 100644
--- a/src/test/debuginfo/type-names.rs
+++ b/src/test/debuginfo/type-names.rs
@@ -1,208 +1,268 @@
 // ignore-lldb
-// ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155
+
+// GDB changed the way that it formatted Foreign types
+// min-gdb-version: 9.2
 
 // compile-flags:-g
 
+// === GDB TESTS ===================================================================================
+
 // gdb-command:run
 
 // STRUCTS
 // gdb-command:whatis simple_struct
-// gdbg-check:type = struct Struct1
-// gdbr-check:type = type_names::Struct1
+// gdb-check:type = type_names::Struct1
 
 // gdb-command:whatis generic_struct1
-// gdbg-check:type = struct GenericStruct<type_names::mod1::Struct2, type_names::mod1::mod2::Struct3>
-// gdbr-check:type = type_names::GenericStruct<type_names::mod1::Struct2, type_names::mod1::mod2::Struct3>
+// gdb-check:type = type_names::GenericStruct<type_names::mod1::Struct2, type_names::mod1::mod2::Struct3>
 
 // gdb-command:whatis generic_struct2
-// gdbg-check:type = struct GenericStruct<type_names::Struct1, extern "fastcall" fn(isize) -> usize>
-// gdbr-check:type = type_names::GenericStruct<type_names::Struct1, extern "fastcall" fn(isize) -> usize>
+// gdb-check:type = type_names::GenericStruct<type_names::Struct1, extern "fastcall" fn(isize) -> usize>
 
 // gdb-command:whatis mod_struct
-// gdbg-check:type = struct Struct2
-// gdbr-check:type = type_names::mod1::Struct2
+// gdb-check:type = type_names::mod1::Struct2
 
 // ENUMS
 // gdb-command:whatis simple_enum_1
-// gdbg-check:type = union Enum1
-// gdbr-check:type = type_names::Enum1
+// gdb-check:type = type_names::Enum1
 
 // gdb-command:whatis simple_enum_2
-// gdbg-check:type = union Enum1
-// gdbr-check:type = type_names::Enum1
+// gdb-check:type = type_names::Enum1
 
 // gdb-command:whatis simple_enum_3
-// gdbg-check:type = union Enum2
-// gdbr-check:type = type_names::mod1::Enum2
+// gdb-check:type = type_names::mod1::Enum2
 
 // gdb-command:whatis generic_enum_1
-// gdbg-check:type = union Enum3<type_names::mod1::Struct2>
-// gdbr-check:type = type_names::mod1::mod2::Enum3<type_names::mod1::Struct2>
+// gdb-check:type = type_names::mod1::mod2::Enum3
 
 // gdb-command:whatis generic_enum_2
-// gdbg-check:type = union Enum3<type_names::Struct1>
-// gdbr-check:type = type_names::mod1::mod2::Enum3<type_names::Struct1>
+// gdb-check:type = type_names::mod1::mod2::Enum3
 
 // TUPLES
 // gdb-command:whatis tuple1
-// gdbg-check:type = struct (u32, type_names::Struct1, type_names::mod1::mod2::Enum3<type_names::mod1::Struct2>)
-// gdbr-check:type = (u32, type_names::Struct1, type_names::mod1::mod2::Enum3<type_names::mod1::Struct2>)
+// gdb-check:type = (u32, type_names::Struct1, type_names::mod1::mod2::Enum3<type_names::mod1::Struct2>)
 
 // gdb-command:whatis tuple2
-// gdbg-check:type = struct ((type_names::Struct1, type_names::mod1::mod2::Struct3), type_names::mod1::Enum2, char)
-// gdbr-check:type = ((type_names::Struct1, type_names::mod1::mod2::Struct3), type_names::mod1::Enum2, char)
+// gdb-check:type = ((type_names::Struct1, type_names::mod1::mod2::Struct3), type_names::mod1::Enum2, char)
 
 // BOX
 // gdb-command:whatis box1
-// gdbg-check:type = struct (alloc::boxed::Box<f32>, i32)
-// gdbr-check:type = (alloc::boxed::Box<f32>, i32)
+// gdb-check:type = (alloc::boxed::Box<f32, alloc::alloc::Global>, i32)
 
 // gdb-command:whatis box2
-// gdbg-check:type = struct (alloc::boxed::Box<type_names::mod1::mod2::Enum3<f32>>, i32)
-// gdbr-check:type = (alloc::boxed::Box<type_names::mod1::mod2::Enum3<f32>>, i32)
+// gdb-check:type = (alloc::boxed::Box<type_names::mod1::mod2::Enum3<f32>, alloc::alloc::Global>, i32)
 
 // REFERENCES
 // gdb-command:whatis ref1
-// gdbg-check:type = struct (&type_names::Struct1, i32)
-// gdbr-check:type = (&type_names::Struct1, i32)
+// gdb-check:type = (&type_names::Struct1, i32)
 
 // gdb-command:whatis ref2
-// gdbg-check:type = struct (&type_names::GenericStruct<char, type_names::Struct1>, i32)
-// gdbr-check:type = (&type_names::GenericStruct<char, type_names::Struct1>, i32)
+// gdb-check:type = (&type_names::GenericStruct<char, type_names::Struct1>, i32)
 
 // gdb-command:whatis mut_ref1
-// gdbg-check:type = struct (&mut type_names::Struct1, i32)
-// gdbr-check:type = (&mut type_names::Struct1, i32)
+// gdb-check:type = (&mut type_names::Struct1, i32)
 
 // gdb-command:whatis mut_ref2
-// gdbg-check:type = struct (&mut type_names::GenericStruct<type_names::mod1::Enum2, f64>, i32)
-// gdbr-check:type = (&mut type_names::GenericStruct<type_names::mod1::Enum2, f64>, i32)
+// gdb-check:type = (&mut type_names::GenericStruct<type_names::mod1::Enum2, f64>, i32)
 
 // RAW POINTERS
 // gdb-command:whatis mut_ptr1
-// gdbg-check:type = struct (*mut type_names::Struct1, isize)
-// gdbr-check:type = (*mut type_names::Struct1, isize)
+// gdb-check:type = (*mut type_names::Struct1, isize)
 
 // gdb-command:whatis mut_ptr2
-// gdbg-check:type = struct (*mut isize, isize)
-// gdbr-check:type = (*mut isize, isize)
+// gdb-check:type = (*mut isize, isize)
 
 // gdb-command:whatis mut_ptr3
-// gdbg-check:type = struct (*mut type_names::mod1::mod2::Enum3<type_names::Struct1>, isize)
-// gdbr-check:type = (*mut type_names::mod1::mod2::Enum3<type_names::Struct1>, isize)
+// gdb-check:type = (*mut type_names::mod1::mod2::Enum3<type_names::Struct1>, isize)
 
 // gdb-command:whatis const_ptr1
-// gdbg-check:type = struct (*const type_names::Struct1, isize)
-// gdbr-check:type = (*const type_names::Struct1, isize)
+// gdb-check:type = (*const type_names::Struct1, isize)
 
 // gdb-command:whatis const_ptr2
-// gdbg-check:type = struct (*const isize, isize)
-// gdbr-check:type = (*const isize, isize)
+// gdb-check:type = (*const isize, isize)
 
 // gdb-command:whatis const_ptr3
-// gdbg-check:type = struct (*const type_names::mod1::mod2::Enum3<type_names::Struct1>, isize)
-// gdbr-check:type = (*const type_names::mod1::mod2::Enum3<type_names::Struct1>, isize)
+// gdb-check:type = (*const type_names::mod1::mod2::Enum3<type_names::Struct1>, isize)
 
 // VECTORS
 // gdb-command:whatis fixed_size_vec1
-// gdbg-check:type = struct ([type_names::Struct1; 3], i16)
-// gdbr-check:type = ([type_names::Struct1; 3], i16)
+// gdb-check:type = ([type_names::Struct1; 3], i16)
 
 // gdb-command:whatis fixed_size_vec2
-// gdbg-check:type = struct ([usize; 3], i16)
-// gdbr-check:type = ([usize; 3], i16)
+// gdb-check:type = ([usize; 3], i16)
 
 // gdb-command:whatis slice1
-// gdbg-check:type = struct &[usize]
-// gdbr-check:type = &[usize]
+// gdb-check:type = &[usize]
 
 // gdb-command:whatis slice2
-// gdbg-check:type = struct &[type_names::mod1::Enum2]
-// gdbr-check:type = &[type_names::mod1::Enum2]
+// gdb-check:type = &[type_names::mod1::Enum2]
 
 // TRAITS
 // gdb-command:whatis box_trait
-// gdbg-check:type = struct Box<Trait1>
-// gdbr-check:type = type_names::Box<Trait1>
+// gdb-check:type = alloc::boxed::Box<dyn type_names::Trait1, alloc::alloc::Global>
 
 // gdb-command:whatis ref_trait
-// gdbg-check:type = struct &Trait1
-// gdbr-check:type = type_names::&Trait1
+// gdb-check:type = &dyn type_names::Trait1
 
 // gdb-command:whatis mut_ref_trait
-// gdbg-check:type = struct &mut Trait1
-// gdbr-check:type = type_names::&mut Trait1
+// gdb-check:type = &mut dyn type_names::Trait1
 
 // gdb-command:whatis generic_box_trait
-// gdbg-check:type = struct Box<Trait2<i32, type_names::mod1::Struct2>>
-// gdbr-check:type = type_names::Box<Trait2<i32, type_names::mod1::Struct2>>
+// gdb-check:type = alloc::boxed::Box<dyn type_names::Trait2<i32, type_names::mod1::Struct2>, alloc::alloc::Global>
 
 // gdb-command:whatis generic_ref_trait
-// gdbg-check:type = struct &Trait2<type_names::Struct1, type_names::Struct1>
-// gdbr-check:type = type_names::&Trait2<type_names::Struct1, type_names::Struct1>
+// gdb-check:type = &dyn type_names::Trait2<type_names::Struct1, type_names::Struct1>
 
 // gdb-command:whatis generic_mut_ref_trait
-// gdbg-check:type = struct &mut Trait2<type_names::mod1::mod2::Struct3, type_names::GenericStruct<usize, isize>>
-// gdbr-check:type = type_names::&mut Trait2<type_names::mod1::mod2::Struct3, type_names::GenericStruct<usize, isize>>
+// gdb-check:type = &mut dyn type_names::Trait2<type_names::mod1::mod2::Struct3, type_names::GenericStruct<usize, isize>>
+
+// gdb-command:whatis no_principal_trait
+// gdb-check:type = alloc::boxed::Box<dyn core::marker::Send + core::marker::Sync, alloc::alloc::Global>
 
 // BARE FUNCTIONS
 // gdb-command:whatis rust_fn
-// gdbg-check:type = struct (fn(core::option::Option<isize>, core::option::Option<&type_names::mod1::Struct2>), usize)
-// gdbr-check:type = (fn(core::option::Option<isize>, core::option::Option<&type_names::mod1::Struct2>), usize)
+// gdb-check:type = (fn(core::option::Option<isize>, core::option::Option<&type_names::mod1::Struct2>), usize)
 
 // gdb-command:whatis extern_c_fn
-// gdbg-check:type = struct (extern "C" fn(isize), usize)
-// gdbr-check:type = (extern "C" fn(isize), usize)
+// gdb-check:type = (extern "C" fn(isize), usize)
 
 // gdb-command:whatis unsafe_fn
-// gdbg-check:type = struct (unsafe fn(core::result::Result<char, f64>), usize)
-// gdbr-check:type = (unsafe fn(core::result::Result<char, f64>), usize)
-
-// gdb-command:whatis extern_stdcall_fn
-// gdbg-check:type = struct (extern "stdcall" fn(), usize)
-// gdbr-check:type = (extern "stdcall" fn(), usize)
+// gdb-check:type = (unsafe fn(core::result::Result<char, f64>), usize)
 
 // gdb-command:whatis rust_fn_with_return_value
-// gdbg-check:type = struct (fn(f64) -> usize, usize)
-// gdbr-check:type = (fn(f64) -> usize, usize)
+// gdb-check:type = (fn(f64) -> usize, usize)
 
 // gdb-command:whatis extern_c_fn_with_return_value
-// gdbg-check:type = struct (extern "C" fn() -> type_names::Struct1, usize)
-// gdbr-check:type = (extern "C" fn() -> type_names::Struct1, usize)
+// gdb-check:type = (extern "C" fn() -> type_names::Struct1, usize)
 
 // gdb-command:whatis unsafe_fn_with_return_value
-// gdbg-check:type = struct (unsafe fn(type_names::GenericStruct<u16, u8>) -> type_names::mod1::Struct2, usize)
-// gdbr-check:type = (unsafe fn(type_names::GenericStruct<u16, u8>) -> type_names::mod1::Struct2, usize)
-
-// gdb-command:whatis extern_stdcall_fn_with_return_value
-// gdbg-check:type = struct (extern "stdcall" fn(alloc::boxed::Box<isize>) -> usize, usize)
-// gdbr-check:type = (extern "stdcall" fn(alloc::boxed::Box<isize>) -> usize, usize)
+// gdb-check:type = (unsafe fn(type_names::GenericStruct<u16, u8>) -> type_names::mod1::Struct2, usize)
 
 // gdb-command:whatis generic_function_int
-// gdbg-check:type = struct (fn(isize) -> isize, usize)
-// gdbr-check:type = (fn(isize) -> isize, usize)
+// gdb-check:type = (fn(isize) -> isize, usize)
 
 // gdb-command:whatis generic_function_struct3
-// gdbg-check:type = struct (fn(type_names::mod1::mod2::Struct3) -> type_names::mod1::mod2::Struct3, usize)
-// gdbr-check:type = (fn(type_names::mod1::mod2::Struct3) -> type_names::mod1::mod2::Struct3, usize)
+// gdb-check:type = (fn(type_names::mod1::mod2::Struct3) -> type_names::mod1::mod2::Struct3, usize)
 
 // gdb-command:whatis variadic_function
-// gdbg-check:type = struct (unsafe extern "C" fn(*const u8, ...) -> isize, usize)
-// gdbr-check:type = (unsafe extern "C" fn(*const u8, ...) -> isize, usize)
+// gdb-check:type = (unsafe extern "C" fn(*const u8, ...) -> isize, usize)
 
 // CLOSURES
 // gdb-command:whatis closure1
-// gdbg-check:type = struct (closure, usize)
-// gdbr-check:type = (closure, usize)
+// gdb-check:type = (type_names::main::{closure#0}, usize)
 
 // gdb-command:whatis closure2
-// gdbg-check:type = struct (closure, usize)
-// gdbr-check:type = (closure, usize)
+// gdb-check:type = (type_names::main::{closure#1}, usize)
+
+// FOREIGN TYPES
+// gdb-command:whatis foreign1
+// gdb-check:type = *mut ForeignType1
+
+// gdb-command:whatis foreign2
+// gdb-check:type = *mut ForeignType2
+
+// === CDB TESTS ==================================================================================
+
+// cdb-command: g
+
+// STRUCTS
+// 0-sized structs appear to be optimized away in some cases, so only check the structs that do
+// actually appear.
+// cdb-command:dv /t *_struct
+// cdb-check:struct type_names::GenericStruct<enum$<type_names::mod1::Enum2>, f64> mut_generic_struct = [...]
+
+// ENUMS
+// cdb-command:dv /t *_enum_*
+// cdb-check:union enum$<type_names::Enum1> simple_enum_1 = [...]
+// cdb-check:union enum$<type_names::Enum1> simple_enum_2 = [...]
+// cdb-check:type_names::mod1::Enum2 simple_enum_3 = [...]
+// cdb-check:type_names::mod1::mod2::Enum3 generic_enum_1 = [...]
+// cdb-check:type_names::mod1::mod2::Enum3 generic_enum_2 = [...]
+
+// TUPLES
+// cdb-command:dv /t tuple*
+// cdb-check:struct tuple$<u32,type_names::Struct1,enum$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > > tuple1 = [...]
+// cdb-check:struct tuple$<tuple$<type_names::Struct1,type_names::mod1::mod2::Struct3>,enum$<type_names::mod1::Enum2>,char> tuple2 = [...]
+
+// BOX
+// cdb-command:dv /t box*
+// cdb-check:struct tuple$<alloc::boxed::Box<f32, alloc::alloc::Global>,i32> box1 = [...]
+// cdb-check:struct tuple$<alloc::boxed::Box<enum$<type_names::mod1::mod2::Enum3<f32> >, alloc::alloc::Global>,i32> box2 = [...]
+
+// REFERENCES
+// cdb-command:dv /t *ref*
+// cdb-check:struct tuple$<ref$<type_names::Struct1>,i32> ref1 = [...]
+// cdb-check:struct tuple$<ref$<type_names::GenericStruct<char, type_names::Struct1> >,i32> ref2 = [...]
+// cdb-check:struct tuple$<ref_mut$<type_names::Struct1>,i32> mut_ref1 = [...]
+// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum$<type_names::mod1::Enum2>, f64> >,i32> mut_ref2 = [...]
+
+// RAW POINTERS
+// cdb-command:dv /t *_ptr*
+// cdb-check:struct tuple$<ptr_mut$<type_names::Struct1>,isize> mut_ptr1 = [...]
+// cdb-check:struct tuple$<ptr_mut$<isize>,isize> mut_ptr2 = [...]
+// cdb-check:struct tuple$<ptr_mut$<enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> mut_ptr3 = [...]
+// cdb-check:struct tuple$<ptr_const$<type_names::Struct1>,isize> const_ptr1 = [...]
+// cdb-check:struct tuple$<ptr_const$<isize>,isize> const_ptr2 = [...]
+// cdb-check:struct tuple$<ptr_const$<enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > >,isize> const_ptr3 = [...]
+
+// VECTORS
+// cdb-command:dv /t *vec*
+// cdb-check:struct tuple$<array$<type_names::Struct1,3>,i16> fixed_size_vec1 = [...]
+// cdb-check:struct tuple$<array$<usize,3>,i16> fixed_size_vec2 = [...]
+// cdb-check:struct alloc::vec::Vec<usize, alloc::alloc::Global> vec1 = [...]
+// cdb-check:struct alloc::vec::Vec<enum$<type_names::mod1::Enum2>, alloc::alloc::Global> vec2 = [...]
+// cdb-command:dv /t slice*
+// cdb-check:struct slice$<usize> slice1 = [...]
+// cdb-check:struct slice$<enum$<type_names::mod1::Enum2> > slice2 = [...]
+
+// TRAITS
+// cdb-command:dv /t *_trait
+// cdb-check:struct ref_mut$<dyn$<type_names::Trait2<type_names::mod1::mod2::Struct3, type_names::GenericStruct<usize, isize> > > > generic_mut_ref_trait = [...]
+// cdb-check:struct ref$<dyn$<type_names::Trait2<type_names::Struct1, type_names::Struct1> > > generic_ref_trait = [...]
+// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait2<i32, type_names::mod1::Struct2> >, alloc::alloc::Global> generic_box_trait = [...]
+// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait1>, alloc::alloc::Global> box_trait = [...]
+// cdb-check:struct ref$<dyn$<type_names::Trait1> > ref_trait = [...]
+// cdb-check:struct ref_mut$<dyn$<type_names::Trait1> > mut_ref_trait = [...]
+// cdb-check:struct alloc::boxed::Box<dyn$<core::marker::Send, core::marker::Sync>, alloc::alloc::Global> no_principal_trait = [...]
+// cdb-check:struct ref$<dyn$<type_names::Trait3> > has_associated_type_trait = struct ref$<dyn$<type_names::Trait3> >
+
+// BARE FUNCTIONS
+// cdb-command:dv /t *_fn*
+// cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16, u8>),usize> unsafe_fn_with_return_value = [...]
+// cdb-check:struct tuple$<type_names::Struct1 (*)(),usize> extern_c_fn_with_return_value = [...]
+// cdb-check:struct tuple$<usize (*)(f64),usize> rust_fn_with_return_value = [...]
+// cdb-check:struct tuple$<void (*)(enum$<core::result::Result<char, f64> >),usize> unsafe_fn = [...]
+// cdb-check:struct tuple$<void (*)(isize),usize> extern_c_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum$<core::option::Option<isize> >, enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>),usize> rust_fn = [...]
+// cdb-command:dv /t *_function*
+// cdb-check:struct tuple$<isize (*)(ptr_const$<u8>, ...),usize> variadic_function = [...]
+// cdb-check:struct tuple$<type_names::mod1::mod2::Struct3 (*)(type_names::mod1::mod2::Struct3),usize> generic_function_struct3 = [...]
+// cdb-check:struct tuple$<isize (*)(isize),usize> generic_function_int = [...]
+// cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn")
+// cdb-check:Return Type: void
+// cdb-check:Parameter Types: enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>
+// cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("rust_fn_with_return_value")
+// cdb-check:Return Type: usize
+// cdb-check:Parameter Types: f64
+// cdb-command:dx Debugger.State.Scripts.@"type-names.cdb".Contents.getFunctionDetails("extern_c_fn_with_return_value")
+// cdb-check:Return Type: type_names::Struct1
+// cdb-check:Parameter Types:
+
+// CLOSURES
+// cdb-command:dv /t closure*
+// cdb-check:struct tuple$<type_names::main::closure$1,usize> closure2 = [...]
+// cdb-check:struct tuple$<type_names::main::closure$0,usize> closure1 = [...]
+
+// FOREIGN TYPES
+// cdb-command:dv /t foreign*
+// cdb-check:struct ForeignType2 * foreign2 = [...]
+// cdb-check:struct ForeignType1 * foreign1 = [...]
 
 #![feature(box_syntax)]
 #![allow(unused_variables)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
+#![feature(extern_types)]
 
 use self::Enum1::{Variant1, Variant2};
 use std::marker::PhantomData;
@@ -216,6 +276,8 @@ enum Enum1 {
     Variant2(isize),
 }
 
+extern { type ForeignType1; }
+
 mod mod1 {
     pub use self::Enum2::{Variant1, Variant2};
     pub struct Struct2;
@@ -234,6 +296,8 @@ mod mod1 {
             Variant2(T),
         }
     }
+
+    extern { pub type ForeignType2; }
 }
 
 trait Trait1 {
@@ -242,14 +306,20 @@ trait Trait1 {
 trait Trait2<T1, T2> {
     fn dummy(&self, _: T1, _: T2) {}
 }
+trait Trait3 {
+    type AssocType;
+    fn dummy(&self) {}
+}
 
 impl Trait1 for isize {}
 impl<T1, T2> Trait2<T1, T2> for isize {}
+impl Trait3 for isize {
+    type AssocType = isize;
+}
 
 fn rust_fn(_: Option<isize>, _: Option<&mod1::Struct2>) {}
 extern "C" fn extern_c_fn(_: isize) {}
 unsafe fn unsafe_fn(_: Result<char, f64>) {}
-extern "stdcall" fn extern_stdcall_fn() {}
 
 fn rust_fn_with_return_value(_: f64) -> usize {
     4
@@ -260,9 +330,6 @@ extern "C" fn extern_c_fn_with_return_value() -> Struct1 {
 unsafe fn unsafe_fn_with_return_value(_: GenericStruct<u16, u8>) -> mod1::Struct2 {
     mod1::Struct2
 }
-extern "stdcall" fn extern_stdcall_fn_with_return_value(_: Box<isize>) -> usize {
-    0
-}
 
 fn generic_function<T>(x: T) -> T {
     x
@@ -333,28 +400,28 @@ fn main() {
     let slice2 = &*vec2;
 
     // Trait Objects
-    let box_trait = (box 0_isize) as Box<Trait1>;
-    let ref_trait = &0_isize as &Trait1;
+    let box_trait = (box 0_isize) as Box<dyn Trait1>;
+    let ref_trait = &0_isize as &dyn Trait1;
     let mut mut_int1 = 0_isize;
-    let mut_ref_trait = (&mut mut_int1) as &mut Trait1;
+    let mut_ref_trait = (&mut mut_int1) as &mut dyn Trait1;
+    let no_principal_trait = (box 0_isize) as Box<dyn Send + Sync>;
+    let has_associated_type_trait = &0_isize as &dyn Trait3<AssocType = isize>;
 
-    let generic_box_trait = (box 0_isize) as Box<Trait2<i32, mod1::Struct2>>;
-    let generic_ref_trait = (&0_isize) as &Trait2<Struct1, Struct1>;
+    let generic_box_trait = (box 0_isize) as Box<dyn Trait2<i32, mod1::Struct2>>;
+    let generic_ref_trait = (&0_isize) as &dyn Trait2<Struct1, Struct1>;
 
     let mut generic_mut_ref_trait_impl = 0_isize;
     let generic_mut_ref_trait = (&mut generic_mut_ref_trait_impl)
-        as &mut Trait2<mod1::mod2::Struct3, GenericStruct<usize, isize>>;
+        as &mut dyn Trait2<mod1::mod2::Struct3, GenericStruct<usize, isize>>;
 
     // Bare Functions
     let rust_fn = (rust_fn, 0_usize);
     let extern_c_fn = (extern_c_fn, 0_usize);
     let unsafe_fn = (unsafe_fn, 0_usize);
-    let extern_stdcall_fn = (extern_stdcall_fn, 0_usize);
 
     let rust_fn_with_return_value = (rust_fn_with_return_value, 0_usize);
     let extern_c_fn_with_return_value = (extern_c_fn_with_return_value, 0_usize);
     let unsafe_fn_with_return_value = (unsafe_fn_with_return_value, 0_usize);
-    let extern_stdcall_fn_with_return_value = (extern_stdcall_fn_with_return_value, 0_usize);
 
     let generic_function_int = (generic_function::<isize>, 0_usize);
     let generic_function_struct3 = (generic_function::<mod1::mod2::Struct3>, 0_usize);
@@ -370,6 +437,10 @@ fn main() {
     let closure1 = (|x: isize| {}, 0_usize);
     let closure2 = (|x: i8, y: f32| (x as f32) + y, 0_usize);
 
+    // Foreign Types
+    let foreign1 = unsafe{ 0 as *const ForeignType1 };
+    let foreign2 = unsafe{ 0 as *const mod1::ForeignType2 };
+
     zzz(); // #break
 }
 
diff --git a/src/test/debuginfo/var-captured-in-nested-closure.rs b/src/test/debuginfo/var-captured-in-nested-closure.rs
index 695cdc4f41f..a2778fc6090 100644
--- a/src/test/debuginfo/var-captured-in-nested-closure.rs
+++ b/src/test/debuginfo/var-captured-in-nested-closure.rs
@@ -108,7 +108,7 @@
 // cdb-command: dx closure_local
 // cdb-check:closure_local    : 8 [Type: [...]]
 // cdb-command: dx nested_closure
-// cdb-check:nested_closure   [Type: var_captured_in_nested_closure::main::{{closure}}::closure-0]
+// cdb-check:nested_closure   [Type: var_captured_in_nested_closure::main::closure$0::closure$0]
 
 // cdb-command: g
 
diff --git a/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
new file mode 100644
index 00000000000..373be9f174b
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
@@ -0,0 +1,106 @@
+// MIR for `main` after SimplifyCfg-after-uninhabited-enum-branching
+
+fn main() -> () {
+    let mut _0: ();                      // return place in scope 0 at $DIR/uninhabited_enum_branching2.rs:18:11: 18:11
+    let _1: Plop;                        // in scope 0 at $DIR/uninhabited_enum_branching2.rs:19:9: 19:13
+    let mut _2: Test1;                   // in scope 0 at $DIR/uninhabited_enum_branching2.rs:19:38: 19:46
+    let _3: &str;                        // in scope 0 at $DIR/uninhabited_enum_branching2.rs:21:5: 26:6
+    let mut _4: &Test1;                  // in scope 0 at $DIR/uninhabited_enum_branching2.rs:21:11: 21:22
+    let mut _5: isize;                   // in scope 0 at $DIR/uninhabited_enum_branching2.rs:22:9: 22:20
+    let _6: &str;                        // in scope 0 at $DIR/uninhabited_enum_branching2.rs:23:24: 23:34
+    let _7: &str;                        // in scope 0 at $DIR/uninhabited_enum_branching2.rs:24:21: 24:24
+    let _8: &str;                        // in scope 0 at $DIR/uninhabited_enum_branching2.rs:25:21: 25:24
+    let _9: &str;                        // in scope 0 at $DIR/uninhabited_enum_branching2.rs:28:5: 33:6
+    let mut _10: isize;                  // in scope 0 at $DIR/uninhabited_enum_branching2.rs:29:9: 29:20
+    let _11: &str;                       // in scope 0 at $DIR/uninhabited_enum_branching2.rs:30:24: 30:34
+    let _12: &str;                       // in scope 0 at $DIR/uninhabited_enum_branching2.rs:31:21: 31:24
+    let _13: &str;                       // in scope 0 at $DIR/uninhabited_enum_branching2.rs:32:21: 32:24
+    scope 1 {
+        debug plop => _1;                // in scope 1 at $DIR/uninhabited_enum_branching2.rs:19:9: 19:13
+    }
+
+    bb0: {
+        StorageLive(_1);                 // scope 0 at $DIR/uninhabited_enum_branching2.rs:19:9: 19:13
+        StorageLive(_2);                 // scope 0 at $DIR/uninhabited_enum_branching2.rs:19:38: 19:46
+        discriminant(_2) = 2;            // scope 0 at $DIR/uninhabited_enum_branching2.rs:19:38: 19:46
+        (_1.0: u32) = const 51_u32;      // scope 0 at $DIR/uninhabited_enum_branching2.rs:19:16: 19:48
+        (_1.1: Test1) = move _2;         // scope 0 at $DIR/uninhabited_enum_branching2.rs:19:16: 19:48
+        StorageDead(_2);                 // scope 0 at $DIR/uninhabited_enum_branching2.rs:19:47: 19:48
+        StorageLive(_3);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:21:5: 26:6
+        StorageLive(_4);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:21:11: 21:22
+        _4 = &(_1.1: Test1);             // scope 1 at $DIR/uninhabited_enum_branching2.rs:21:11: 21:22
+        _5 = discriminant((*_4));        // scope 1 at $DIR/uninhabited_enum_branching2.rs:22:9: 22:20
+        switchInt(move _5) -> [2_isize: bb2, otherwise: bb1]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:22:9: 22:20
+    }
+
+    bb1: {
+        StorageLive(_8);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:21: 25:24
+        _8 = const "D";                  // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:21: 25:24
+                                         // ty::Const
+                                         // + ty: &str
+                                         // + val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 })
+                                         // mir::Constant
+                                         // + span: $DIR/uninhabited_enum_branching2.rs:25:21: 25:24
+                                         // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) }
+        _3 = &(*_8);                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:21: 25:24
+        StorageDead(_8);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:23: 25:24
+        goto -> bb3;                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:21:5: 26:6
+    }
+
+    bb2: {
+        StorageLive(_7);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:21: 24:24
+        _7 = const "C";                  // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:21: 24:24
+                                         // ty::Const
+                                         // + ty: &str
+                                         // + val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 })
+                                         // mir::Constant
+                                         // + span: $DIR/uninhabited_enum_branching2.rs:24:21: 24:24
+                                         // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) }
+        _3 = &(*_7);                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:21: 24:24
+        StorageDead(_7);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:23: 24:24
+        goto -> bb3;                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:21:5: 26:6
+    }
+
+    bb3: {
+        StorageDead(_4);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:26:6: 26:7
+        StorageDead(_3);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:26:6: 26:7
+        StorageLive(_9);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:28:5: 33:6
+        _10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:29:9: 29:20
+        switchInt(move _10) -> [2_isize: bb5, otherwise: bb4]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:29:9: 29:20
+    }
+
+    bb4: {
+        StorageLive(_13);                // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:21: 32:24
+        _13 = const "D";                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:21: 32:24
+                                         // ty::Const
+                                         // + ty: &str
+                                         // + val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 })
+                                         // mir::Constant
+                                         // + span: $DIR/uninhabited_enum_branching2.rs:32:21: 32:24
+                                         // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) }
+        _9 = &(*_13);                    // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:21: 32:24
+        StorageDead(_13);                // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:23: 32:24
+        goto -> bb6;                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:28:5: 33:6
+    }
+
+    bb5: {
+        StorageLive(_12);                // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:21: 31:24
+        _12 = const "C";                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:21: 31:24
+                                         // ty::Const
+                                         // + ty: &str
+                                         // + val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 })
+                                         // mir::Constant
+                                         // + span: $DIR/uninhabited_enum_branching2.rs:31:21: 31:24
+                                         // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) }
+        _9 = &(*_12);                    // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:21: 31:24
+        StorageDead(_12);                // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:23: 31:24
+        goto -> bb6;                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:28:5: 33:6
+    }
+
+    bb6: {
+        StorageDead(_9);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:33:6: 33:7
+        _0 = const ();                   // scope 0 at $DIR/uninhabited_enum_branching2.rs:18:11: 34:2
+        StorageDead(_1);                 // scope 0 at $DIR/uninhabited_enum_branching2.rs:34:1: 34:2
+        return;                          // scope 0 at $DIR/uninhabited_enum_branching2.rs:34:2: 34:2
+    }
+}
diff --git a/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff
new file mode 100644
index 00000000000..f9488bae4c8
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff
@@ -0,0 +1,160 @@
+- // MIR for `main` before UninhabitedEnumBranching
++ // MIR for `main` after UninhabitedEnumBranching
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/uninhabited_enum_branching2.rs:18:11: 18:11
+      let _1: Plop;                        // in scope 0 at $DIR/uninhabited_enum_branching2.rs:19:9: 19:13
+      let mut _2: Test1;                   // in scope 0 at $DIR/uninhabited_enum_branching2.rs:19:38: 19:46
+      let _3: &str;                        // in scope 0 at $DIR/uninhabited_enum_branching2.rs:21:5: 26:6
+      let mut _4: &Test1;                  // in scope 0 at $DIR/uninhabited_enum_branching2.rs:21:11: 21:22
+      let mut _5: isize;                   // in scope 0 at $DIR/uninhabited_enum_branching2.rs:22:9: 22:20
+      let _6: &str;                        // in scope 0 at $DIR/uninhabited_enum_branching2.rs:23:24: 23:34
+      let _7: &str;                        // in scope 0 at $DIR/uninhabited_enum_branching2.rs:24:21: 24:24
+      let _8: &str;                        // in scope 0 at $DIR/uninhabited_enum_branching2.rs:25:21: 25:24
+      let _9: &str;                        // in scope 0 at $DIR/uninhabited_enum_branching2.rs:28:5: 33:6
+      let mut _10: isize;                  // in scope 0 at $DIR/uninhabited_enum_branching2.rs:29:9: 29:20
+      let _11: &str;                       // in scope 0 at $DIR/uninhabited_enum_branching2.rs:30:24: 30:34
+      let _12: &str;                       // in scope 0 at $DIR/uninhabited_enum_branching2.rs:31:21: 31:24
+      let _13: &str;                       // in scope 0 at $DIR/uninhabited_enum_branching2.rs:32:21: 32:24
+      scope 1 {
+          debug plop => _1;                // in scope 1 at $DIR/uninhabited_enum_branching2.rs:19:9: 19:13
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/uninhabited_enum_branching2.rs:19:9: 19:13
+          StorageLive(_2);                 // scope 0 at $DIR/uninhabited_enum_branching2.rs:19:38: 19:46
+          discriminant(_2) = 2;            // scope 0 at $DIR/uninhabited_enum_branching2.rs:19:38: 19:46
+          (_1.0: u32) = const 51_u32;      // scope 0 at $DIR/uninhabited_enum_branching2.rs:19:16: 19:48
+          (_1.1: Test1) = move _2;         // scope 0 at $DIR/uninhabited_enum_branching2.rs:19:16: 19:48
+          StorageDead(_2);                 // scope 0 at $DIR/uninhabited_enum_branching2.rs:19:47: 19:48
+          StorageLive(_3);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:21:5: 26:6
+          StorageLive(_4);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:21:11: 21:22
+          _4 = &(_1.1: Test1);             // scope 1 at $DIR/uninhabited_enum_branching2.rs:21:11: 21:22
+          _5 = discriminant((*_4));        // scope 1 at $DIR/uninhabited_enum_branching2.rs:22:9: 22:20
+-         switchInt(move _5) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, otherwise: bb1]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:22:9: 22:20
++         switchInt(move _5) -> [2_isize: bb4, otherwise: bb1]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:22:9: 22:20
+      }
+  
+      bb1: {
+          StorageLive(_8);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:21: 25:24
+          _8 = const "D";                  // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:21: 25:24
+                                           // ty::Const
+                                           // + ty: &str
+                                           // + val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 })
+                                           // mir::Constant
+                                           // + span: $DIR/uninhabited_enum_branching2.rs:25:21: 25:24
+                                           // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) }
+          _3 = &(*_8);                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:21: 25:24
+          StorageDead(_8);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:23: 25:24
+          goto -> bb5;                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:21:5: 26:6
+      }
+  
+      bb2: {
+          _3 = const "A(Empty)";           // scope 1 at $DIR/uninhabited_enum_branching2.rs:22:24: 22:34
+                                           // ty::Const
+                                           // + ty: &str
+                                           // + val: Value(Slice { data: Allocation { bytes: [65, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 })
+                                           // mir::Constant
+                                           // + span: $DIR/uninhabited_enum_branching2.rs:22:24: 22:34
+                                           // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [65, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 }) }
+          goto -> bb5;                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:21:5: 26:6
+      }
+  
+      bb3: {
+          StorageLive(_6);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:23:24: 23:34
+          _6 = const "B(Empty)";           // scope 1 at $DIR/uninhabited_enum_branching2.rs:23:24: 23:34
+                                           // ty::Const
+                                           // + ty: &str
+                                           // + val: Value(Slice { data: Allocation { bytes: [66, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 })
+                                           // mir::Constant
+                                           // + span: $DIR/uninhabited_enum_branching2.rs:23:24: 23:34
+                                           // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [66, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 }) }
+          _3 = &(*_6);                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:23:24: 23:34
+          StorageDead(_6);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:23:33: 23:34
+          goto -> bb5;                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:21:5: 26:6
+      }
+  
+      bb4: {
+          StorageLive(_7);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:21: 24:24
+          _7 = const "C";                  // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:21: 24:24
+                                           // ty::Const
+                                           // + ty: &str
+                                           // + val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 })
+                                           // mir::Constant
+                                           // + span: $DIR/uninhabited_enum_branching2.rs:24:21: 24:24
+                                           // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) }
+          _3 = &(*_7);                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:21: 24:24
+          StorageDead(_7);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:23: 24:24
+          goto -> bb5;                     // scope 1 at $DIR/uninhabited_enum_branching2.rs:21:5: 26:6
+      }
+  
+      bb5: {
+          StorageDead(_4);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:26:6: 26:7
+          StorageDead(_3);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:26:6: 26:7
+          StorageLive(_9);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:28:5: 33:6
+          _10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:29:9: 29:20
+-         switchInt(move _10) -> [0_isize: bb7, 1_isize: bb8, 2_isize: bb9, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:29:9: 29:20
++         switchInt(move _10) -> [2_isize: bb9, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:29:9: 29:20
+      }
+  
+      bb6: {
+          StorageLive(_13);                // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:21: 32:24
+          _13 = const "D";                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:21: 32:24
+                                           // ty::Const
+                                           // + ty: &str
+                                           // + val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 })
+                                           // mir::Constant
+                                           // + span: $DIR/uninhabited_enum_branching2.rs:32:21: 32:24
+                                           // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) }
+          _9 = &(*_13);                    // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:21: 32:24
+          StorageDead(_13);                // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:23: 32:24
+          goto -> bb10;                    // scope 1 at $DIR/uninhabited_enum_branching2.rs:28:5: 33:6
+      }
+  
+      bb7: {
+          _9 = const "A(Empty)";           // scope 1 at $DIR/uninhabited_enum_branching2.rs:29:24: 29:34
+                                           // ty::Const
+                                           // + ty: &str
+                                           // + val: Value(Slice { data: Allocation { bytes: [65, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 })
+                                           // mir::Constant
+                                           // + span: $DIR/uninhabited_enum_branching2.rs:29:24: 29:34
+                                           // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [65, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 }) }
+          goto -> bb10;                    // scope 1 at $DIR/uninhabited_enum_branching2.rs:28:5: 33:6
+      }
+  
+      bb8: {
+          StorageLive(_11);                // scope 1 at $DIR/uninhabited_enum_branching2.rs:30:24: 30:34
+          _11 = const "B(Empty)";          // scope 1 at $DIR/uninhabited_enum_branching2.rs:30:24: 30:34
+                                           // ty::Const
+                                           // + ty: &str
+                                           // + val: Value(Slice { data: Allocation { bytes: [66, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 })
+                                           // mir::Constant
+                                           // + span: $DIR/uninhabited_enum_branching2.rs:30:24: 30:34
+                                           // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [66, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 }) }
+          _9 = &(*_11);                    // scope 1 at $DIR/uninhabited_enum_branching2.rs:30:24: 30:34
+          StorageDead(_11);                // scope 1 at $DIR/uninhabited_enum_branching2.rs:30:33: 30:34
+          goto -> bb10;                    // scope 1 at $DIR/uninhabited_enum_branching2.rs:28:5: 33:6
+      }
+  
+      bb9: {
+          StorageLive(_12);                // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:21: 31:24
+          _12 = const "C";                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:21: 31:24
+                                           // ty::Const
+                                           // + ty: &str
+                                           // + val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 })
+                                           // mir::Constant
+                                           // + span: $DIR/uninhabited_enum_branching2.rs:31:21: 31:24
+                                           // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) }
+          _9 = &(*_12);                    // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:21: 31:24
+          StorageDead(_12);                // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:23: 31:24
+          goto -> bb10;                    // scope 1 at $DIR/uninhabited_enum_branching2.rs:28:5: 33:6
+      }
+  
+      bb10: {
+          StorageDead(_9);                 // scope 1 at $DIR/uninhabited_enum_branching2.rs:33:6: 33:7
+          _0 = const ();                   // scope 0 at $DIR/uninhabited_enum_branching2.rs:18:11: 34:2
+          StorageDead(_1);                 // scope 0 at $DIR/uninhabited_enum_branching2.rs:34:1: 34:2
+          return;                          // scope 0 at $DIR/uninhabited_enum_branching2.rs:34:2: 34:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/uninhabited_enum_branching2.rs b/src/test/mir-opt/uninhabited_enum_branching2.rs
new file mode 100644
index 00000000000..e22e94314d9
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_enum_branching2.rs
@@ -0,0 +1,34 @@
+enum Empty { }
+
+// test matching an enum with uninhabited variants
+enum Test1 {
+    A(Empty),
+    B(Empty),
+    C,
+    D,
+}
+
+struct Plop {
+    xx: u32,
+    test1: Test1,
+}
+
+// EMIT_MIR uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff
+// EMIT_MIR uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
+fn main() {
+    let plop = Plop { xx: 51, test1: Test1::C };
+
+    match &plop.test1 {
+        Test1::A(_) => "A(Empty)",
+        Test1::B(_) => "B(Empty)",
+        Test1::C => "C",
+        Test1::D => "D",
+    };
+
+    match plop.test1 {
+        Test1::A(_) => "A(Empty)",
+        Test1::B(_) => "B(Empty)",
+        Test1::C => "C",
+        Test1::D => "D",
+    };
+}
diff --git a/src/test/pretty/ast-stmt-expr-attr.rs b/src/test/pretty/ast-stmt-expr-attr.rs
index a32903a6409..32d1da390c5 100644
--- a/src/test/pretty/ast-stmt-expr-attr.rs
+++ b/src/test/pretty/ast-stmt-expr-attr.rs
@@ -39,7 +39,7 @@ fn syntax() {
                     #![attr]
                 };
     let _ =
-        #[attr] loop  {
+        #[attr] loop {
                     #![attr]
                 };
     let _ =
diff --git a/src/test/pretty/block-comment-wchar.pp b/src/test/pretty/block-comment-wchar.pp
index 2bfcdd75e15..2d0a10d4c27 100644
--- a/src/test/pretty/block-comment-wchar.pp
+++ b/src/test/pretty/block-comment-wchar.pp
@@ -90,7 +90,7 @@ fn f() {
 }
 
 fn main() {
-    // Taken from http://www.unicode.org/Public/UNIDATA/PropList.txt
+    // Taken from https://www.unicode.org/Public/UNIDATA/PropList.txt
     let chars =
         ['\x0A', '\x0B', '\x0C', '\x0D', '\x20', '\u{85}', '\u{A0}',
          '\u{1680}', '\u{2000}', '\u{2001}', '\u{2002}', '\u{2003}',
diff --git a/src/test/pretty/block-comment-wchar.rs b/src/test/pretty/block-comment-wchar.rs
index 93373c5da65..075230196e3 100644
--- a/src/test/pretty/block-comment-wchar.rs
+++ b/src/test/pretty/block-comment-wchar.rs
@@ -86,7 +86,7 @@ fn f() {
 }
 
 fn main() {
-    // Taken from http://www.unicode.org/Public/UNIDATA/PropList.txt
+    // Taken from https://www.unicode.org/Public/UNIDATA/PropList.txt
     let chars =
         ['\x0A', '\x0B', '\x0C', '\x0D', '\x20', '\u{85}', '\u{A0}',
          '\u{1680}', '\u{2000}', '\u{2001}', '\u{2002}', '\u{2003}',
diff --git a/src/test/pretty/hir-pretty-loop.pp b/src/test/pretty/hir-pretty-loop.pp
new file mode 100644
index 00000000000..19b3a1775cf
--- /dev/null
+++ b/src/test/pretty/hir-pretty-loop.pp
@@ -0,0 +1,9 @@
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+// pretty-compare-only
+// pretty-mode:hir
+// pp-exact:hir-pretty-loop.pp
+
+pub fn foo() { loop { break ; } }
diff --git a/src/test/pretty/hir-pretty-loop.rs b/src/test/pretty/hir-pretty-loop.rs
new file mode 100644
index 00000000000..87a3ef8b8f9
--- /dev/null
+++ b/src/test/pretty/hir-pretty-loop.rs
@@ -0,0 +1,9 @@
+// pretty-compare-only
+// pretty-mode:hir
+// pp-exact:hir-pretty-loop.pp
+
+pub fn foo(){
+    loop{
+        break;
+    }
+}
diff --git a/src/test/pretty/stmt_expr_attributes.rs b/src/test/pretty/stmt_expr_attributes.rs
index 231351433c8..e4a3acade87 100644
--- a/src/test/pretty/stmt_expr_attributes.rs
+++ b/src/test/pretty/stmt_expr_attributes.rs
@@ -166,9 +166,8 @@ fn _11() {
         #[rustc_dummy] for _ in 0..0 {
                            #![rustc_dummy]
                        };
-    // FIXME: pp bug, two spaces after the loop
     let _ =
-        #[rustc_dummy] loop  {
+        #[rustc_dummy] loop {
                            #![rustc_dummy]
                        };
     let _ =
diff --git a/src/test/run-make-fulldeps/core-no-fp-fmt-parse/Makefile b/src/test/run-make-fulldeps/core-no-fp-fmt-parse/Makefile
new file mode 100644
index 00000000000..bc4562bef3a
--- /dev/null
+++ b/src/test/run-make-fulldeps/core-no-fp-fmt-parse/Makefile
@@ -0,0 +1,4 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) --edition=2018 --crate-type=rlib ../../../../library/core/src/lib.rs --cfg no_fp_fmt_parse
diff --git a/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c
index 52af3dceb10..c89f8272b1e 100644
--- a/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c
+++ b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c
@@ -1,4 +1,4 @@
-// Pragma needed cause of gcc bug on windows: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991
+// Pragma needed cause of gcc bug on windows: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991
 
 #include <assert.h>
 
diff --git a/src/test/run-make/track-path-dep-info/Makefile b/src/test/run-make/track-path-dep-info/Makefile
new file mode 100644
index 00000000000..465d3744789
--- /dev/null
+++ b/src/test/run-make/track-path-dep-info/Makefile
@@ -0,0 +1,13 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC`
+# instead of hardcoding them everywhere they're needed.
+ifeq ($(IS_MUSL_HOST),1)
+ADDITIONAL_ARGS := $(RUSTFLAGS)
+endif
+
+all:
+	# Proc macro
+	$(BARE_RUSTC) $(ADDITIONAL_ARGS) --out-dir $(TMPDIR) macro_def.rs
+	EXISTING_PROC_MACRO_ENV=1 $(RUSTC) --emit dep-info macro_use.rs
+	$(CGREP) "emojis.txt:" < $(TMPDIR)/macro_use.d
diff --git a/src/test/run-make/track-path-dep-info/emojis.txt b/src/test/run-make/track-path-dep-info/emojis.txt
new file mode 100644
index 00000000000..e1a728461f3
--- /dev/null
+++ b/src/test/run-make/track-path-dep-info/emojis.txt
@@ -0,0 +1 @@
+👾👾👾👾👾👾
diff --git a/src/test/run-make/track-path-dep-info/macro_def.rs b/src/test/run-make/track-path-dep-info/macro_def.rs
new file mode 100644
index 00000000000..8777ce21f8b
--- /dev/null
+++ b/src/test/run-make/track-path-dep-info/macro_def.rs
@@ -0,0 +1,11 @@
+#![feature(track_path)]
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro]
+pub fn access_tracked_paths(_: TokenStream) -> TokenStream {
+    tracked_path::path("emojis.txt");
+    TokenStream::new()
+}
diff --git a/src/test/run-make/track-path-dep-info/macro_use.rs b/src/test/run-make/track-path-dep-info/macro_use.rs
new file mode 100644
index 00000000000..3c49fd05dd9
--- /dev/null
+++ b/src/test/run-make/track-path-dep-info/macro_use.rs
@@ -0,0 +1,6 @@
+#[macro_use]
+extern crate macro_def;
+
+access_tracked_paths!();
+
+fn main() {}
diff --git a/src/test/rustdoc-gui/font-weight.goml b/src/test/rustdoc-gui/font-weight.goml
index 80618112103..84e898660fa 100644
--- a/src/test/rustdoc-gui/font-weight.goml
+++ b/src/test/rustdoc-gui/font-weight.goml
@@ -5,3 +5,16 @@ assert-css: ("//*[@class='structfield small-section-header']//a[text()='Alias']"
 assert-css: ("#method\.a_method > code", {"font-weight": "600"})
 assert-css: ("#associatedtype\.X > code", {"font-weight": "600"})
 assert-css: ("#associatedconstant\.Y > code", {"font-weight": "600"})
+
+goto: file://|DOC_PATH|/test_docs/type.SomeType.html
+assert-css: (".top-doc .docblock p", {"font-weight": "400"}, ALL)
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+assert-css: (".impl-items .method", {"font-weight": "600"}, ALL)
+
+goto: file://|DOC_PATH|/lib2/trait.Trait.html
+assert-count: (".methods .type", 1)
+assert-css: (".methods .type", {"font-weight": "600"})
+assert-count: (".methods .constant", 1)
+assert-css: (".methods .constant", {"font-weight": "600"})
+assert-css: (".methods .method", {"font-weight": "600"})
diff --git a/src/test/rustdoc-gui/label-next-to-symbol.goml b/src/test/rustdoc-gui/label-next-to-symbol.goml
new file mode 100644
index 00000000000..4fef4e655fd
--- /dev/null
+++ b/src/test/rustdoc-gui/label-next-to-symbol.goml
@@ -0,0 +1,36 @@
+// These tests verify that labels like "UNIX" and "Deprecated" stay on the same line as their symbol.
+// It also verifies the staggered layout on mobile.
+goto: file://|DOC_PATH|/test_docs/index.html
+
+// Desktop view
+size: (1080, 600)
+assert: (".stab.deprecated")
+assert: (".stab.portability")
+
+// make sure that deprecated and portability are different colours
+assert-css: (".item-table .item-left .stab.deprecated", { "background-color": "rgb(255, 196, 196)" })
+assert-css: (".item-table .item-left .stab.portability", { "background-color": "rgb(243, 223, 255)" })
+
+// table like view
+assert-css: (".item-right.docblock-short", { "padding-left": "0px" })
+compare-elements-position-near: ("//*[@class='item-left module-item']//a[text()='replaced_function']", ".item-left .stab.deprecated", {"y": 2})
+compare-elements-position: (".item-left .stab.deprecated", ".item-left .stab.portability", ("y"))
+
+// Ensure no wrap
+compare-elements-position-near: ("//*[@class='item-left module-item']//a[text()='replaced_function']", "//*[@class='item-right docblock-short']//p[text()='a thing with a label']", {"y": 2})
+// compare parent elements
+compare-elements-position: ("//*[@class='item-left module-item']//a[text()='replaced_function']/..", "//*[@class='item-right docblock-short']//p[text()='a thing with a label']/..", ("y"))
+
+
+// Mobile view
+size: (600, 600)
+// staggered layout with 2em spacing
+assert-css: (".item-right.docblock-short", { "padding-left": "32px" })
+compare-elements-position-near: ("//*[@class='item-left module-item']//a[text()='replaced_function']", ".item-left .stab.deprecated", {"y": 1})
+compare-elements-position: (".item-left .stab.deprecated", ".item-left .stab.portability", ("y"))
+
+// Ensure wrap
+compare-elements-position-near-false: ("//*[@class='item-left module-item']//a[text()='replaced_function']", "//*[@class='item-right docblock-short']//p[text()='a thing with a label']", {"y": 12})
+// compare parent elements
+compare-elements-position-false: ("//*[@class='item-left module-item']//a[text()='replaced_function']/..", "//*[@class='item-right docblock-short']//p[text()='a thing with a label']/..", ("y"))
+compare-elements-position-false: (".item-left .stab.deprecated", "//*[@class='item-right docblock-short']//p[text()='a thing with a label']", ("y"))
diff --git a/src/test/rustdoc-gui/sidebar.goml b/src/test/rustdoc-gui/sidebar.goml
index 4f6b3aded18..c8ebb8c56f5 100644
--- a/src/test/rustdoc-gui/sidebar.goml
+++ b/src/test/rustdoc-gui/sidebar.goml
@@ -13,8 +13,8 @@ assert-text: (".sidebar-elems > .items > ul > li:nth-child(4)", "Traits")
 assert-text: (".sidebar-elems > .items > ul > li:nth-child(5)", "Functions")
 assert-text: (".sidebar-elems > .items > ul > li:nth-child(6)", "Type Definitions")
 assert-text: (".sidebar-elems > .items > ul > li:nth-child(7)", "Keywords")
-assert-text: ("#structs + table td > a", "Foo")
-click: "#structs + table td > a"
+assert-text: ("#structs + .item-table .item-left > a", "Foo")
+click: "#structs + .item-table .item-left > a"
 
 // PAGE: struct.Foo.html
 assert-count: (".sidebar .location", 2)
@@ -35,8 +35,8 @@ assert-text: (".sidebar-elems > .items > ul > li:nth-child(2)", "Structs")
 assert-text: (".sidebar-elems > .items > ul > li:nth-child(3)", "Traits")
 assert-text: (".sidebar-elems > .items > ul > li:nth-child(4)", "Functions")
 assert-text: (".sidebar-elems > .items > ul > li:nth-child(5)", "Type Definitions")
-assert-text: ("#functions + table td > a", "foobar")
-click: "#functions + table td > a"
+assert-text: ("#functions + .item-table .item-left > a", "foobar")
+click: "#functions + .item-table .item-left > a"
 
 // PAGE: fn.foobar.html
 // In items containing no items (like functions or constants) and in modules, we have one
@@ -57,4 +57,4 @@ assert-text: (".sidebar > .location", "Module sub_sub_module")
 // We check that we don't have the crate list.
 assert-false: ".sidebar-elems > .crate"
 assert-text: (".sidebar-elems > .items > ul > li:nth-child(1)", "Functions")
-assert-text: ("#functions + table td > a", "foo")
+assert-text: ("#functions + .item-table .item-left > a", "foo")
diff --git a/src/test/rustdoc-gui/src/lib.rs b/src/test/rustdoc-gui/src/lib.rs
index 5141b6d1920..3e753cb4de8 100644
--- a/src/test/rustdoc-gui/src/lib.rs
+++ b/src/test/rustdoc-gui/src/lib.rs
@@ -3,6 +3,7 @@
 
 #![crate_name = "test_docs"]
 #![feature(doc_keyword)]
+#![feature(doc_cfg)]
 
 use std::fmt;
 
@@ -90,6 +91,11 @@ pub trait AnotherOne {
 /// ```
 pub fn check_list_code_block() {}
 
+/// a thing with a label
+#[deprecated(since = "1.0.0", note = "text why this deprecated")]
+#[doc(cfg(unix))]
+pub fn replaced_function() {}
+
 pub enum AnEnum {
     WithVariants { and: usize, sub: usize, variants: usize },
 }
diff --git a/src/test/rustdoc-gui/src/lib2.rs b/src/test/rustdoc-gui/src/lib2.rs
index 6fa1b36b29b..77d384f3113 100644
--- a/src/test/rustdoc-gui/src/lib2.rs
+++ b/src/test/rustdoc-gui/src/lib2.rs
@@ -23,6 +23,8 @@ impl Foo {
 pub trait Trait {
     type X;
     const Y: u32;
+
+    fn foo() {}
 }
 
 impl Trait for Foo {
diff --git a/src/test/rustdoc-gui/type-weight.rs b/src/test/rustdoc-gui/type-weight.rs
deleted file mode 100644
index 8b6518e7f31..00000000000
--- a/src/test/rustdoc-gui/type-weight.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-goto: file://|DOC_PATH|/test_docs/type.SomeType.html
-assert-all: (".top-block .docblock p", {"font-weight": "400"})
diff --git a/src/test/rustdoc-js-std/alias-4.js b/src/test/rustdoc-js-std/alias-4.js
new file mode 100644
index 00000000000..bf2bb4d2981
--- /dev/null
+++ b/src/test/rustdoc-js-std/alias-4.js
@@ -0,0 +1,7 @@
+const QUERY = '<';
+
+const EXPECTED = {
+    'others': [
+        { 'name': 'Ord' },
+    ],
+};
diff --git a/src/test/rustdoc-js-std/typed-query.js b/src/test/rustdoc-js-std/typed-query.js
new file mode 100644
index 00000000000..f656aa72986
--- /dev/null
+++ b/src/test/rustdoc-js-std/typed-query.js
@@ -0,0 +1,12 @@
+// exact-check
+
+const QUERY = 'macro:print';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'std', 'name': 'print' },
+        { 'path': 'std', 'name': 'eprint' },
+        { 'path': 'std', 'name': 'println' },
+        { 'path': 'std', 'name': 'eprintln' },
+    ],
+};
diff --git a/src/test/rustdoc-js/generics-trait.js b/src/test/rustdoc-js/generics-trait.js
new file mode 100644
index 00000000000..7876622435b
--- /dev/null
+++ b/src/test/rustdoc-js/generics-trait.js
@@ -0,0 +1,23 @@
+const QUERY = [
+    'Result<SomeTrait>',
+    'OtherThingxxxxxxxx',
+];
+
+const EXPECTED = [
+    {
+        'in_args': [
+            { 'path': 'generics_trait', 'name': 'beta' },
+        ],
+        'returned': [
+            { 'path': 'generics_trait', 'name': 'bet' },
+        ],
+    },
+    {
+        'in_args': [
+            { 'path': 'generics_trait', 'name': 'alpha' },
+        ],
+        'returned': [
+            { 'path': 'generics_trait', 'name': 'alef' },
+        ],
+    },
+];
diff --git a/src/test/rustdoc-js/generics-trait.rs b/src/test/rustdoc-js/generics-trait.rs
new file mode 100644
index 00000000000..20db117ccd5
--- /dev/null
+++ b/src/test/rustdoc-js/generics-trait.rs
@@ -0,0 +1,8 @@
+pub trait SomeTrait {}
+pub trait OtherThingxxxxxxxx {}
+
+pub fn alef<T: OtherThingxxxxxxxx>() -> Result<T, ()> { loop {} }
+pub fn bet<T: SomeTrait>() -> Result<T, ()> { loop {} }
+
+pub fn alpha<T: OtherThingxxxxxxxx>(_param: Result<T, ()>) { loop {} }
+pub fn beta<T: SomeTrait>(_param: Result<T, ()>) { loop {} }
diff --git a/src/test/rustdoc-js/generics.js b/src/test/rustdoc-js/generics.js
new file mode 100644
index 00000000000..49a80ae2360
--- /dev/null
+++ b/src/test/rustdoc-js/generics.js
@@ -0,0 +1,44 @@
+// exact-check
+
+const QUERY = [
+  '"R<P>"',
+  '"P"',
+  'P',
+  '"ExtraCreditStructMulti<ExtraCreditInnerMulti, ExtraCreditInnerMulti>"',
+];
+
+const EXPECTED = [
+    {
+        'returned': [
+            { 'path': 'generics', 'name': 'alef' },
+        ],
+        'in_args': [
+            { 'path': 'generics', 'name': 'alpha' },
+        ],
+    },
+    {
+        'others': [
+            { 'path': 'generics', 'name': 'P' },
+        ],
+        'returned': [
+            { 'path': 'generics', 'name': 'alef' },
+        ],
+        'in_args': [
+            { 'path': 'generics', 'name': 'alpha' },
+        ],
+    },
+    {
+        'returned': [
+            { 'path': 'generics', 'name': 'alef' },
+        ],
+        'in_args': [
+            { 'path': 'generics', 'name': 'alpha' },
+        ],
+    },
+    {
+        'in_args': [
+            { 'path': 'generics', 'name': 'extracreditlabhomework' },
+        ],
+        'returned': [],
+    },
+];
diff --git a/src/test/rustdoc-js/generics.rs b/src/test/rustdoc-js/generics.rs
new file mode 100644
index 00000000000..a0dc086e9f9
--- /dev/null
+++ b/src/test/rustdoc-js/generics.rs
@@ -0,0 +1,21 @@
+pub struct P;
+pub struct Q;
+pub struct R<T>(T);
+
+// returns test
+pub fn alef() -> R<P> { loop {} }
+pub fn bet() -> R<Q> { loop {} }
+
+// in_args test
+pub fn alpha(_x: R<P>) { loop {} }
+pub fn beta(_x: R<Q>) { loop {} }
+
+// test case with multiple appearances of the same type
+pub struct ExtraCreditStructMulti<T, U> { t: T, u: U }
+pub struct ExtraCreditInnerMulti {}
+pub fn extracreditlabhomework(
+    _param: ExtraCreditStructMulti<ExtraCreditInnerMulti, ExtraCreditInnerMulti>
+) { loop {} }
+pub fn redherringmatchforextracredit(
+    _param: ExtraCreditStructMulti<ExtraCreditInnerMulti, ()>
+) { loop {} }
diff --git a/src/test/rustdoc-ui/auxiliary/panic-item.rs b/src/test/rustdoc-ui/auxiliary/panic-item.rs
deleted file mode 100644
index 17b26850d4d..00000000000
--- a/src/test/rustdoc-ui/auxiliary/panic-item.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// no-prefer-dynamic
-#![crate_type = "lib"]
-#![no_std]
-#![feature(lang_items)]
-
-use core::panic::PanicInfo;
-use core::sync::atomic::{self, Ordering};
-
-#[panic_handler]
-fn panic(_info: &PanicInfo) -> ! {
-    loop {
-        atomic::compiler_fence(Ordering::SeqCst);
-    }
-}
-
-#[lang = "eh_personality"]
-fn foo() {}
diff --git a/src/test/rustdoc-ui/renamed-lint-still-applies.rs b/src/test/rustdoc-ui/renamed-lint-still-applies.rs
index 05a32d3cc31..a4d3a4b4971 100644
--- a/src/test/rustdoc-ui/renamed-lint-still-applies.rs
+++ b/src/test/rustdoc-ui/renamed-lint-still-applies.rs
@@ -1,7 +1,6 @@
 // compile-args: --crate-type lib
 #![deny(broken_intra_doc_links)]
-// FIXME: the old names for rustdoc lints should warn by default once `rustdoc::` makes it to the
-// stable channel.
+//~^ WARNING renamed to `rustdoc::broken_intra_doc_links`
 //! [x]
 //~^ ERROR unresolved link
 
diff --git a/src/test/rustdoc-ui/renamed-lint-still-applies.stderr b/src/test/rustdoc-ui/renamed-lint-still-applies.stderr
index 3040cad532c..8e2a2cdd759 100644
--- a/src/test/rustdoc-ui/renamed-lint-still-applies.stderr
+++ b/src/test/rustdoc-ui/renamed-lint-still-applies.stderr
@@ -1,13 +1,19 @@
+warning: lint `broken_intra_doc_links` has been renamed to `rustdoc::broken_intra_doc_links`
+  --> $DIR/renamed-lint-still-applies.rs:2:9
+   |
+LL | #![deny(broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::broken_intra_doc_links`
+   |
+   = note: `#[warn(renamed_and_removed_lints)]` on by default
+
 warning: lint `rustdoc::non_autolinks` has been renamed to `rustdoc::bare_urls`
-  --> $DIR/renamed-lint-still-applies.rs:8:9
+  --> $DIR/renamed-lint-still-applies.rs:7:9
    |
 LL | #![deny(rustdoc::non_autolinks)]
    |         ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::bare_urls`
-   |
-   = note: `#[warn(renamed_and_removed_lints)]` on by default
 
 error: unresolved link to `x`
-  --> $DIR/renamed-lint-still-applies.rs:5:6
+  --> $DIR/renamed-lint-still-applies.rs:4:6
    |
 LL | //! [x]
    |      ^ no item named `x` in scope
@@ -17,21 +23,20 @@ note: the lint level is defined here
    |
 LL | #![deny(broken_intra_doc_links)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
-   = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(broken_intra_doc_links)]`
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: this URL is not a hyperlink
-  --> $DIR/renamed-lint-still-applies.rs:10:5
+  --> $DIR/renamed-lint-still-applies.rs:9:5
    |
 LL | //! http://example.com
    |     ^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://example.com>`
    |
 note: the lint level is defined here
-  --> $DIR/renamed-lint-still-applies.rs:8:9
+  --> $DIR/renamed-lint-still-applies.rs:7:9
    |
 LL | #![deny(rustdoc::non_autolinks)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
    = note: bare URLs are not automatically turned into clickable links
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to 2 previous errors; 2 warnings emitted
 
diff --git a/src/test/rustdoc-ui/unknown-renamed-lints.rs b/src/test/rustdoc-ui/unknown-renamed-lints.rs
index 9096cce1276..ddf03dd079f 100644
--- a/src/test/rustdoc-ui/unknown-renamed-lints.rs
+++ b/src/test/rustdoc-ui/unknown-renamed-lints.rs
@@ -14,8 +14,7 @@
 //~^ ERROR renamed to `rustdoc::bare_urls`
 
 #![deny(private_doc_tests)]
-// FIXME: the old names for rustdoc lints should warn by default once `rustdoc::` makes it to the
-// stable channel.
+//~^ ERROR renamed to `rustdoc::private_doc_tests`
 
 #![deny(rustdoc)]
 //~^ ERROR removed: use `rustdoc::all` instead
diff --git a/src/test/rustdoc-ui/unknown-renamed-lints.stderr b/src/test/rustdoc-ui/unknown-renamed-lints.stderr
index 51e06821cf7..ad814b82352 100644
--- a/src/test/rustdoc-ui/unknown-renamed-lints.stderr
+++ b/src/test/rustdoc-ui/unknown-renamed-lints.stderr
@@ -40,19 +40,25 @@ error: lint `rustdoc::non_autolinks` has been renamed to `rustdoc::bare_urls`
 LL | #![deny(rustdoc::non_autolinks)]
    |         ^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::bare_urls`
 
+error: lint `private_doc_tests` has been renamed to `rustdoc::private_doc_tests`
+  --> $DIR/unknown-renamed-lints.rs:16:9
+   |
+LL | #![deny(private_doc_tests)]
+   |         ^^^^^^^^^^^^^^^^^ help: use the new name: `rustdoc::private_doc_tests`
+
 error: lint `rustdoc` has been removed: use `rustdoc::all` instead
-  --> $DIR/unknown-renamed-lints.rs:20:9
+  --> $DIR/unknown-renamed-lints.rs:19:9
    |
 LL | #![deny(rustdoc)]
    |         ^^^^^^^
 
 error: unknown lint: `rustdoc::intra_doc_link_resolution_failure`
-  --> $DIR/unknown-renamed-lints.rs:24:9
+  --> $DIR/unknown-renamed-lints.rs:23:9
    |
 LL | #![deny(rustdoc::intra_doc_link_resolution_failure)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: Compilation failed, aborting rustdoc
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/src/test/rustdoc-ui/unused-extern-crate.rs b/src/test/rustdoc-ui/unused-extern-crate.rs
deleted file mode 100644
index f703a183790..00000000000
--- a/src/test/rustdoc-ui/unused-extern-crate.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-// check-pass
-// aux-crate:panic_item=panic-item.rs
-// @has unused_extern_crate/index.html
diff --git a/src/test/rustdoc/auxiliary/cross-crate-hidden-impl-parameter.rs b/src/test/rustdoc/auxiliary/cross-crate-hidden-impl-parameter.rs
new file mode 100644
index 00000000000..15953122280
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/cross-crate-hidden-impl-parameter.rs
@@ -0,0 +1,5 @@
+#[doc(hidden)]
+pub enum HiddenType {}
+
+#[doc(hidden)]
+pub trait HiddenTrait {}
diff --git a/src/test/rustdoc/auxiliary/issue-66159-1.rs b/src/test/rustdoc/auxiliary/issue-66159-1.rs
new file mode 100644
index 00000000000..2f3d069bd51
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/issue-66159-1.rs
@@ -0,0 +1,2 @@
+/// This will be referred to by the test docstring
+pub struct Something;
diff --git a/src/test/rustdoc/auxiliary/issue-85454.rs b/src/test/rustdoc/auxiliary/issue-85454.rs
new file mode 100644
index 00000000000..45664dfc382
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/issue-85454.rs
@@ -0,0 +1,17 @@
+// @has issue_85454/trait.FromResidual.html
+// @has - '//pre[@class="rust trait"]' 'pub trait FromResidual<R = <Self as Try>::Residual> { fn from_residual(residual: R) -> Self; }'
+pub trait FromResidual<R = <Self as Try>::Residual> {
+    fn from_residual(residual: R) -> Self;
+}
+
+pub trait Try: FromResidual {
+    type Output;
+    type Residual;
+    fn from_output(output: Self::Output) -> Self;
+    fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+}
+
+pub enum ControlFlow<B, C = ()> {
+    Continue(C),
+    Break(B),
+}
diff --git a/src/test/rustdoc/cross-crate-hidden-impl-parameter.rs b/src/test/rustdoc/cross-crate-hidden-impl-parameter.rs
new file mode 100644
index 00000000000..eb2ced2f7f4
--- /dev/null
+++ b/src/test/rustdoc/cross-crate-hidden-impl-parameter.rs
@@ -0,0 +1,35 @@
+// Issue #86448: test for cross-crate `doc(hidden)`
+#![crate_name = "foo"]
+
+// aux-build:cross-crate-hidden-impl-parameter.rs
+extern crate cross_crate_hidden_impl_parameter;
+
+pub use ::cross_crate_hidden_impl_parameter::{HiddenType, HiddenTrait}; // OK, not re-exported
+
+pub enum MyLibType {}
+
+// @!has foo/enum.MyLibType.html '//*[@id="impl-From%3CHiddenType%3E"]' 'impl From<HiddenType> for MyLibType'
+impl From<HiddenType> for MyLibType {
+    fn from(it: HiddenType) -> MyLibType {
+        match it {}
+    }
+}
+
+pub struct T<T>(T);
+
+// @!has foo/enum.MyLibType.html '//*[@id="impl-From%3CT%3CT%3CT%3CT%3CHiddenType%3E%3E%3E%3E%3E"]' 'impl From<T<T<T<T<HiddenType>>>>> for MyLibType'
+impl From<T<T<T<T<HiddenType>>>>> for MyLibType {
+    fn from(it: T<T<T<T<HiddenType>>>>) -> MyLibType {
+        todo!()
+    }
+}
+
+// @!has foo/enum.MyLibType.html '//*[@id="impl-HiddenTrait"]' 'impl HiddenTrait for MyLibType'
+impl HiddenTrait for MyLibType {}
+
+// @!has foo/struct.T.html '//*[@id="impl-From%3CMyLibType%3E"]' 'impl From<MyLibType> for T<T<T<T<HiddenType>>>>'
+impl From<MyLibType> for T<T<T<T<HiddenType>>>> {
+    fn from(it: MyLibType) -> T<T<T<T<HiddenType>>>> {
+        match it {}
+    }
+}
diff --git a/src/test/rustdoc/deprecated.rs b/src/test/rustdoc/deprecated.rs
index a286856b2c3..b3178da98ee 100644
--- a/src/test/rustdoc/deprecated.rs
+++ b/src/test/rustdoc/deprecated.rs
@@ -1,6 +1,6 @@
-// @has deprecated/index.html '//*[@class="docblock-short"]/span[@class="stab deprecated"]' \
+// @has deprecated/index.html '//*[@class="item-left module-item"]/span[@class="stab deprecated"]' \
 //      'Deprecated'
-// @has - '//*[@class="docblock-short"]' 'Deprecated docs'
+// @has - '//*[@class="item-right docblock-short"]' 'Deprecated docs'
 
 // @has deprecated/struct.S.html '//*[@class="stab deprecated"]' \
 //      'Deprecated since 1.0.0: text'
@@ -8,7 +8,7 @@
 #[deprecated(since = "1.0.0", note = "text")]
 pub struct S;
 
-// @matches deprecated/index.html '//*[@class="docblock-short"]' '^Docs'
+// @matches deprecated/index.html '//*[@class="item-right docblock-short"]' '^Docs'
 /// Docs
 pub struct T;
 
diff --git a/src/test/rustdoc/doc-cfg.rs b/src/test/rustdoc/doc-cfg.rs
index 1fc80b3e76c..416ffb60098 100644
--- a/src/test/rustdoc/doc-cfg.rs
+++ b/src/test/rustdoc/doc-cfg.rs
@@ -12,7 +12,7 @@ pub struct Portable;
 // @has doc_cfg/unix_only/index.html \
 //  '//*[@id="main"]/*[@class="item-info"]/*[@class="stab portability"]' \
 //  'This is supported on Unix only.'
-// @matches - '//*[@class="module-item"]//*[@class="stab portability"]' '\AARM\Z'
+// @matches - '//*[@class="item-left module-item"]//*[@class="stab portability"]' '\AARM\Z'
 // @count - '//*[@class="stab portability"]' 2
 #[doc(cfg(unix))]
 pub mod unix_only {
@@ -42,7 +42,7 @@ pub mod unix_only {
 // @has doc_cfg/wasi_only/index.html \
 //  '//*[@id="main"]/*[@class="item-info"]/*[@class="stab portability"]' \
 //  'This is supported on WASI only.'
-// @matches - '//*[@class="module-item"]//*[@class="stab portability"]' '\AWebAssembly\Z'
+// @matches - '//*[@class="item-left module-item"]//*[@class="stab portability"]' '\AWebAssembly\Z'
 // @count - '//*[@class="stab portability"]' 2
 #[doc(cfg(target_os = "wasi"))]
 pub mod wasi_only {
@@ -74,7 +74,7 @@ pub mod wasi_only {
 
 // the portability header is different on the module view versus the full view
 // @has doc_cfg/index.html
-// @matches - '//*[@class="module-item"]//*[@class="stab portability"]' '\Aavx\Z'
+// @matches - '//*[@class="item-left module-item"]//*[@class="stab portability"]' '\Aavx\Z'
 
 // @has doc_cfg/fn.uses_target_feature.html
 // @has - '//*[@id="main"]/*[@class="item-info"]/*[@class="stab portability"]' \
diff --git a/src/test/rustdoc/duplicate-cfg.rs b/src/test/rustdoc/duplicate-cfg.rs
index cec504ea151..886ec675030 100644
--- a/src/test/rustdoc/duplicate-cfg.rs
+++ b/src/test/rustdoc/duplicate-cfg.rs
@@ -2,13 +2,14 @@
 #![feature(doc_cfg)]
 
 // @has 'foo/index.html'
-// @matches '-' '//*[@class="module-item"]//*[@class="stab portability"]' '^sync$'
-// @has '-' '//*[@class="module-item"]//*[@class="stab portability"]/@title' 'This is supported on crate feature `sync` only'
+// @matches '-' '//*[@class="item-left module-item"]//*[@class="stab portability"]' '^sync$'
+// @has '-' '//*[@class="item-left module-item"]//*[@class="stab portability"]/@title' 'This is supported on crate feature `sync` only'
 
 // @has 'foo/struct.Foo.html'
 // @has '-' '//*[@class="stab portability"]' 'sync'
 #[doc(cfg(feature = "sync"))]
 #[doc(cfg(feature = "sync"))]
+/// my feature sync struct
 pub struct Foo;
 
 // @has 'foo/bar/index.html'
diff --git a/src/test/rustdoc/for-lifetime.rs b/src/test/rustdoc/for-lifetime.rs
deleted file mode 100644
index 34a7eae31c7..00000000000
--- a/src/test/rustdoc/for-lifetime.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-#![crate_name = "foo"]
-#![crate_type = "lib"]
-
-pub struct Foo {
-    pub some_func: for<'a> fn(val: &'a i32) -> i32,
-    pub some_trait: dyn for<'a> Trait<'a>,
-}
-
-// @has foo/struct.Foo.html '//span[@id="structfield.some_func"]' "some_func: for<'a> fn(val: &'a i32) -> i32"
-// @has foo/struct.Foo.html '//span[@id="structfield.some_trait"]' "some_trait: dyn Trait<'a>"
-
-pub trait Trait<'a> {}
diff --git a/src/test/rustdoc/higher-ranked-trait-bounds.rs b/src/test/rustdoc/higher-ranked-trait-bounds.rs
new file mode 100644
index 00000000000..41940b0884e
--- /dev/null
+++ b/src/test/rustdoc/higher-ranked-trait-bounds.rs
@@ -0,0 +1,61 @@
+#![crate_name = "foo"]
+
+// @has foo/trait.Trait.html
+pub trait Trait<'x> {}
+
+// @has foo/fn.test1.html
+// @has - '//pre' "pub fn test1<T>() where for<'a> &'a T: Iterator,"
+pub fn test1<T>()
+where
+    for<'a> &'a T: Iterator,
+{
+}
+
+// @has foo/fn.test2.html
+// @has - '//pre' "pub fn test2<T>() where for<'a, 'b> &'a T: Trait<'b>,"
+pub fn test2<T>()
+where
+    for<'a, 'b> &'a T: Trait<'b>,
+{
+}
+
+// @has foo/fn.test3.html
+// @has - '//pre' "pub fn test3<F>() where F: for<'a, 'b> Fn(&'a u8, &'b u8),"
+pub fn test3<F>()
+where
+    F: for<'a, 'b> Fn(&'a u8, &'b u8),
+{
+}
+
+// @has foo/struct.Foo.html
+pub struct Foo<'a> {
+    _x: &'a u8,
+    pub some_trait: &'a dyn for<'b> Trait<'b>,
+    pub some_func: for<'c> fn(val: &'c i32) -> i32,
+}
+
+// @has - '//span[@id="structfield.some_func"]' "some_func: for<'c> fn(val: &'c i32) -> i32"
+// @has - '//span[@id="structfield.some_trait"]' "some_trait: &'a dyn for<'b> Trait<'b>"
+
+impl<'a> Foo<'a> {
+    // @has - '//code' "pub fn bar<T>() where T: Trait<'a>,"
+    pub fn bar<T>()
+    where
+        T: Trait<'a>,
+    {
+    }
+}
+
+// @has foo/trait.B.html
+pub trait B<'x> {}
+
+// @has - '//code[@class="in-band"]' "impl<'a> B<'a> for dyn for<'b> Trait<'b>"
+impl<'a> B<'a> for dyn for<'b> Trait<'b> {}
+
+// @has foo/struct.Bar.html
+// @has - '//span[@id="structfield.bar"]' "bar: &'a (dyn for<'b> Trait<'b> + Unpin)"
+// @has - '//span[@id="structfield.baz"]' "baz: &'a (dyn Unpin + for<'b> Trait<'b>)"
+pub struct Bar<'a> {
+    pub bar: &'a (dyn for<'b> Trait<'b> + Unpin),
+    pub baz: &'a (dyn Unpin + for<'b> Trait<'b>),
+}
diff --git a/src/test/rustdoc/inline_cross/macros.rs b/src/test/rustdoc/inline_cross/macros.rs
index f9bf982659e..9cb933c177b 100644
--- a/src/test/rustdoc/inline_cross/macros.rs
+++ b/src/test/rustdoc/inline_cross/macros.rs
@@ -7,8 +7,10 @@
 
 extern crate macros;
 
-// @has foo/index.html '//*[@class="docblock-short"]/span[@class="stab deprecated"]' Deprecated
-// @has - '//*[@class="docblock-short"]/span[@class="stab unstable"]' Experimental
+// @has foo/index.html '//*[@class="item-left unstable deprecated module-item"]/span[@class="stab deprecated"]' \
+//         Deprecated
+// @has - '//*[@class="item-left unstable deprecated module-item"]/span[@class="stab unstable"]' \
+//         Experimental
 
 // @has foo/macro.my_macro.html
 // @has - '//*[@class="docblock"]' 'docs for my_macro'
diff --git a/src/test/rustdoc/internal.rs b/src/test/rustdoc/internal.rs
index a1e322fb9a3..f316eb24a48 100644
--- a/src/test/rustdoc/internal.rs
+++ b/src/test/rustdoc/internal.rs
@@ -2,9 +2,11 @@
 
 // Check that the unstable marker is not added for "rustc_private".
 
-// @!matches internal/index.html '//*[@class="docblock-short"]/span[@class="stab unstable"]'
-// @!matches internal/index.html '//*[@class="docblock-short"]/span[@class="stab internal"]'
-// @matches - '//*[@class="docblock-short"]' 'Docs'
+// @!matches internal/index.html \
+//      '//*[@class="item-right docblock-short"]/span[@class="stab unstable"]'
+// @!matches internal/index.html \
+//      '//*[@class="item-right docblock-short"]/span[@class="stab internal"]'
+// @matches - '//*[@class="item-right docblock-short"]' 'Docs'
 
 // @!has internal/struct.S.html '//*[@class="stab unstable"]'
 // @!has internal/struct.S.html '//*[@class="stab internal"]'
diff --git a/src/test/rustdoc/issue-32374.rs b/src/test/rustdoc/issue-32374.rs
index 11caa34d4b1..4e92ae49a20 100644
--- a/src/test/rustdoc/issue-32374.rs
+++ b/src/test/rustdoc/issue-32374.rs
@@ -1,17 +1,17 @@
 #![feature(staged_api)]
-#![doc(issue_tracker_base_url = "http://issue_url/")]
+#![doc(issue_tracker_base_url = "https://issue_url/")]
 
 #![unstable(feature="test", issue = "32374")]
 
-// @matches issue_32374/index.html '//*[@class="docblock-short"]/span[@class="stab deprecated"]' \
+// @matches issue_32374/index.html '//*[@class="item-left unstable deprecated module-item"]/span[@class="stab deprecated"]' \
 //      'Deprecated'
-// @matches issue_32374/index.html '//*[@class="docblock-short"]/span[@class="stab unstable"]' \
+// @matches issue_32374/index.html '//*[@class="item-left unstable deprecated module-item"]/span[@class="stab unstable"]' \
 //      'Experimental'
-// @matches issue_32374/index.html '//*[@class="docblock-short"]/text()' 'Docs'
+// @matches issue_32374/index.html '//*[@class="item-right docblock-short"]/text()' 'Docs'
 
 // @has issue_32374/struct.T.html '//*[@class="stab deprecated"]' \
 //      '👎 Deprecated since 1.0.0: text'
-// @has - '<code>test</code>&nbsp;<a href="http://issue_url/32374">#32374</a>'
+// @has - '<code>test</code>&nbsp;<a href="https://issue_url/32374">#32374</a>'
 // @matches issue_32374/struct.T.html '//*[@class="stab unstable"]' \
 //      '🔬 This is a nightly-only experimental API. \(test\s#32374\)$'
 /// Docs
diff --git a/src/test/rustdoc/issue-46377.rs b/src/test/rustdoc/issue-46377.rs
index 236afb20be5..4489f038c59 100644
--- a/src/test/rustdoc/issue-46377.rs
+++ b/src/test/rustdoc/issue-46377.rs
@@ -1,3 +1,3 @@
-// @has 'issue_46377/index.html' '//*[@class="docblock-short"]' 'Check out this struct!'
+// @has 'issue_46377/index.html' '//*[@class="item-right docblock-short"]' 'Check out this struct!'
 /// # Check out this struct!
 pub struct SomeStruct;
diff --git a/src/test/rustdoc/issue-55364.rs b/src/test/rustdoc/issue-55364.rs
index bc0ad14be03..70aa10767b2 100644
--- a/src/test/rustdoc/issue-55364.rs
+++ b/src/test/rustdoc/issue-55364.rs
@@ -29,8 +29,8 @@ pub mod subone {
 // @has - '//section[@id="main"]/details/div[@class="docblock"]//a[@href="../fn.foo.html"]' 'foo'
 // @has - '//section[@id="main"]/details/div[@class="docblock"]//a[@href="../fn.bar.html"]' 'bar'
 // Though there should be such links later
-// @has - '//section[@id="main"]/table//tr[@class="module-item"]/td/a[@class="fn"][@href="fn.foo.html"]' 'foo'
-// @has - '//section[@id="main"]/table//tr[@class="module-item"]/td/a[@class="fn"][@href="fn.bar.html"]' 'bar'
+// @has - '//section[@id="main"]/div[@class="item-table"]//div[@class="item-left module-item"]/a[@class="fn"][@href="fn.foo.html"]' 'foo'
+// @has - '//section[@id="main"]/div[@class="item-table"]//div[@class="item-left module-item"]/a[@class="fn"][@href="fn.bar.html"]' 'bar'
 /// See either [foo] or [bar].
 pub mod subtwo {
 
@@ -68,8 +68,8 @@ pub mod subthree {
 // Next we go *deeper* - In order to ensure it's not just "this or parent"
 // we test `crate::` and a `super::super::...` chain
 // @has issue_55364/subfour/subfive/subsix/subseven/subeight/index.html
-// @has - '//section[@id="main"]/table//tr[@class="module-item"]/td[@class="docblock-short"]//a[@href="../../../../../subone/fn.foo.html"]' 'other foo'
-// @has - '//section[@id="main"]/table//tr[@class="module-item"]/td[@class="docblock-short"]//a[@href="../../../../../subtwo/fn.bar.html"]' 'other bar'
+// @has - '//section[@id="main"]/div[@class="item-table"]//div[@class="item-right docblock-short"]//a[@href="../../../../../subone/fn.foo.html"]' 'other foo'
+// @has - '//section[@id="main"]/div[@class="item-table"]//div[@class="item-right docblock-short"]//a[@href="../../../../../subtwo/fn.bar.html"]' 'other bar'
 pub mod subfour {
     pub mod subfive {
         pub mod subsix {
diff --git a/src/test/rustdoc/issue-66159.rs b/src/test/rustdoc/issue-66159.rs
new file mode 100644
index 00000000000..003d079a470
--- /dev/null
+++ b/src/test/rustdoc/issue-66159.rs
@@ -0,0 +1,10 @@
+// aux-crate:priv:issue_66159_1=issue-66159-1.rs
+// compile-flags:-Z unstable-options
+
+// The issue was an ICE which meant that we never actually generated the docs
+// so if we have generated the docs, we're okay.
+// Since we don't generate the docs for the auxiliary files, we can't actually
+// verify that the struct is linked correctly.
+
+// @has issue_66159/index.html
+//! [issue_66159_1::Something]
diff --git a/src/test/rustdoc/issue-85454.rs b/src/test/rustdoc/issue-85454.rs
index 45664dfc382..3351b5c8350 100644
--- a/src/test/rustdoc/issue-85454.rs
+++ b/src/test/rustdoc/issue-85454.rs
@@ -1,4 +1,10 @@
-// @has issue_85454/trait.FromResidual.html
+// aux-build:issue-85454.rs
+// build-aux-docs
+#![crate_name = "foo"]
+
+extern crate issue_85454;
+
+// @has foo/trait.FromResidual.html
 // @has - '//pre[@class="rust trait"]' 'pub trait FromResidual<R = <Self as Try>::Residual> { fn from_residual(residual: R) -> Self; }'
 pub trait FromResidual<R = <Self as Try>::Residual> {
     fn from_residual(residual: R) -> Self;
@@ -15,3 +21,9 @@ pub enum ControlFlow<B, C = ()> {
     Continue(C),
     Break(B),
 }
+
+pub mod reexport {
+    // @has foo/reexport/trait.FromResidual.html
+    // @has - '//pre[@class="rust trait"]' 'pub trait FromResidual<R = <Self as Try>::Residual> { fn from_residual(residual: R) -> Self; }'
+    pub use issue_85454::*;
+}
diff --git a/src/test/rustdoc/reexport-check.rs b/src/test/rustdoc/reexport-check.rs
index 9a22903a94c..db1f90c6999 100644
--- a/src/test/rustdoc/reexport-check.rs
+++ b/src/test/rustdoc/reexport-check.rs
@@ -4,15 +4,15 @@
 extern crate reexport_check;
 
 // @!has 'foo/index.html' '//code' 'pub use self::i32;'
-// @has 'foo/index.html' '//tr[@class="deprecated module-item"]' 'i32'
+// @has 'foo/index.html' '//div[@class="item-left deprecated module-item"]' 'i32'
 // @has 'foo/i32/index.html'
 #[allow(deprecated, deprecated_in_future)]
 pub use std::i32;
 // @!has 'foo/index.html' '//code' 'pub use self::string::String;'
-// @has 'foo/index.html' '//tr[@class="module-item"]' 'String'
+// @has 'foo/index.html' '//div[@class="item-left module-item"]' 'String'
 pub use std::string::String;
 
-// @has 'foo/index.html' '//td[@class="docblock-short"]' 'Docs in original'
+// @has 'foo/index.html' '//div[@class="item-right docblock-short"]' 'Docs in original'
 // this is a no-op, but shows what happens if there's an attribute that isn't a doc-comment
 #[doc(inline)]
 pub use reexport_check::S;
diff --git a/src/test/rustdoc/same-crate-hidden-impl-parameter.rs b/src/test/rustdoc/same-crate-hidden-impl-parameter.rs
new file mode 100644
index 00000000000..d55393af859
--- /dev/null
+++ b/src/test/rustdoc/same-crate-hidden-impl-parameter.rs
@@ -0,0 +1,36 @@
+// test for `doc(hidden)` with impl parameters in the same crate.
+#![crate_name = "foo"]
+
+#[doc(hidden)]
+pub enum HiddenType {}
+
+#[doc(hidden)]
+pub trait HiddenTrait {}
+
+pub enum MyLibType {}
+
+// @!has foo/enum.MyLibType.html '//*[@id="impl-From%3CHiddenType%3E"]' 'impl From<HiddenType> for MyLibType'
+impl From<HiddenType> for MyLibType {
+    fn from(it: HiddenType) -> MyLibType {
+        match it {}
+    }
+}
+
+pub struct T<T>(T);
+
+// @!has foo/enum.MyLibType.html '//*[@id="impl-From%3CT%3CT%3CT%3CT%3CHiddenType%3E%3E%3E%3E%3E"]' 'impl From<T<T<T<T<HiddenType>>>>> for MyLibType'
+impl From<T<T<T<T<HiddenType>>>>> for MyLibType {
+    fn from(it: T<T<T<T<HiddenType>>>>) -> MyLibType {
+        todo!()
+    }
+}
+
+// @!has foo/enum.MyLibType.html '//*[@id="impl-HiddenTrait"]' 'impl HiddenTrait for MyLibType'
+impl HiddenTrait for MyLibType {}
+
+// @!has foo/struct.T.html '//*[@id="impl-From%3CMyLibType%3E"]' 'impl From<MyLibType> for T<T<T<T<HiddenType>>>>'
+impl From<MyLibType> for T<T<T<T<HiddenType>>>> {
+    fn from(it: MyLibType) -> T<T<T<T<HiddenType>>>> {
+        match it {}
+    }
+}
diff --git a/src/test/rustdoc/short-docblock-codeblock.rs b/src/test/rustdoc/short-docblock-codeblock.rs
index fc8d53ccf35..c6b318b0677 100644
--- a/src/test/rustdoc/short-docblock-codeblock.rs
+++ b/src/test/rustdoc/short-docblock-codeblock.rs
@@ -1,8 +1,8 @@
 #![crate_name = "foo"]
 
-// @has foo/index.html '//*[@class="module-item"]//td[@class="docblock-short"]' ""
-// @!has foo/index.html '//*[@id="module-item"]//td[@class="docblock-short"]' "Some text."
-// @!has foo/index.html '//*[@id="module-item"]//td[@class="docblock-short"]' "let x = 12;"
+// @has foo/index.html '//*[@class="item-right docblock-short"]' ""
+// @!has foo/index.html '//*[@class="item-right docblock-short"]' "Some text."
+// @!has foo/index.html '//*[@class="item-right docblock-short"]' "let x = 12;"
 
 /// ```
 /// let x = 12;
diff --git a/src/test/rustdoc/short-docblock.rs b/src/test/rustdoc/short-docblock.rs
new file mode 100644
index 00000000000..74fa783174d
--- /dev/null
+++ b/src/test/rustdoc/short-docblock.rs
@@ -0,0 +1,25 @@
+#![crate_name = "foo"]
+
+// @has foo/index.html '//*[@class="item-right docblock-short"]/p' 'fooo'
+// @!has foo/index.html '//*[@class="item-right docblock-short"]/p/h1' 'fooo'
+// @has foo/fn.foo.html '//h1[@id="fooo"]/a[@href="#fooo"]' 'fooo'
+
+/// # fooo
+///
+/// foo
+pub fn foo() {}
+
+// @has foo/index.html '//*[@class="item-right docblock-short"]/p' 'mooood'
+// @!has foo/index.html '//*[@class="item-right docblock-short"]/p/h2' 'mooood'
+// @has foo/foo/index.html '//h2[@id="mooood"]/a[@href="#mooood"]' 'mooood'
+
+/// ## mooood
+///
+/// foo mod
+pub mod foo {}
+
+// @has foo/index.html '//*[@class="item-right docblock-short"]/p/a[@href=\
+//                      "https://nougat.world"]/code' 'nougat'
+
+/// [`nougat`](https://nougat.world)
+pub struct Bar;
diff --git a/src/test/rustdoc/short-dockblock.rs b/src/test/rustdoc/short-dockblock.rs
deleted file mode 100644
index 5493bca54c5..00000000000
--- a/src/test/rustdoc/short-dockblock.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-#![crate_name = "foo"]
-
-// @has foo/index.html '//*[@class="docblock-short"]/p' 'fooo'
-// @!has foo/index.html '//*[@class="docblock-short"]/p/h1' 'fooo'
-// @has foo/fn.foo.html '//h1[@id="fooo"]/a[@href="#fooo"]' 'fooo'
-
-/// # fooo
-///
-/// foo
-pub fn foo() {}
-
-// @has foo/index.html '//*[@class="docblock-short"]/p' 'mooood'
-// @!has foo/index.html '//*[@class="docblock-short"]/p/h2' 'mooood'
-// @has foo/foo/index.html '//h2[@id="mooood"]/a[@href="#mooood"]' 'mooood'
-
-/// ## mooood
-///
-/// foo mod
-pub mod foo {}
-
-// @has foo/index.html '//*[@class="docblock-short"]/p/a[@href=\
-//                      "https://nougat.world"]/code' 'nougat'
-
-/// [`nougat`](https://nougat.world)
-pub struct Bar;
diff --git a/src/test/ui/anon-params/anon-params-deprecated.fixed b/src/test/ui/anon-params/anon-params-deprecated.fixed
index d288bba5957..c09e2077084 100644
--- a/src/test/ui/anon-params/anon-params-deprecated.fixed
+++ b/src/test/ui/anon-params/anon-params-deprecated.fixed
@@ -7,13 +7,13 @@
 
 trait T {
     fn foo(_: i32); //~ WARNING anonymous parameters are deprecated
-                 //~| WARNING hard error
+                 //~| WARNING this is accepted in the current edition
 
     fn bar_with_default_impl(_: String, _: String) {}
     //~^ WARNING anonymous parameters are deprecated
-    //~| WARNING hard error
+    //~| WARNING this is accepted in the current edition
     //~| WARNING anonymous parameters are deprecated
-    //~| WARNING hard error
+    //~| WARNING this is accepted in the current edition
 }
 
 fn main() {}
diff --git a/src/test/ui/anon-params/anon-params-deprecated.rs b/src/test/ui/anon-params/anon-params-deprecated.rs
index d677e0c32b0..6f7385da040 100644
--- a/src/test/ui/anon-params/anon-params-deprecated.rs
+++ b/src/test/ui/anon-params/anon-params-deprecated.rs
@@ -7,13 +7,13 @@
 
 trait T {
     fn foo(i32); //~ WARNING anonymous parameters are deprecated
-                 //~| WARNING hard error
+                 //~| WARNING this is accepted in the current edition
 
     fn bar_with_default_impl(String, String) {}
     //~^ WARNING anonymous parameters are deprecated
-    //~| WARNING hard error
+    //~| WARNING this is accepted in the current edition
     //~| WARNING anonymous parameters are deprecated
-    //~| WARNING hard error
+    //~| WARNING this is accepted in the current edition
 }
 
 fn main() {}
diff --git a/src/test/ui/anon-params/anon-params-deprecated.stderr b/src/test/ui/anon-params/anon-params-deprecated.stderr
index c1bf5f690ec..98d52d659a9 100644
--- a/src/test/ui/anon-params/anon-params-deprecated.stderr
+++ b/src/test/ui/anon-params/anon-params-deprecated.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![warn(anonymous_parameters)]
    |         ^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
 
 warning: anonymous parameters are deprecated and will be removed in the next edition.
@@ -18,7 +18,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi
 LL |     fn bar_with_default_impl(String, String) {}
    |                              ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
 
 warning: anonymous parameters are deprecated and will be removed in the next edition.
@@ -27,7 +27,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi
 LL |     fn bar_with_default_impl(String, String) {}
    |                                      ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
 
 warning: 3 warnings emitted
diff --git a/src/test/ui/asm/bad-options.stderr b/src/test/ui/asm/bad-options.stderr
index 4e27a6e2cb5..9039483be4b 100644
--- a/src/test/ui/asm/bad-options.stderr
+++ b/src/test/ui/asm/bad-options.stderr
@@ -28,41 +28,41 @@ error: asm outputs are not allowed with the `noreturn` option
 LL |         asm!("{}", out(reg) foo, options(noreturn));
    |                    ^^^^^^^^^^^^
 
-error: expected one of `)` or `att_syntax`, found `nomem`
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
   --> $DIR/bad-options.rs:20:25
    |
 LL | global_asm!("", options(nomem));
-   |                         ^^^^^ expected one of `)` or `att_syntax`
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)` or `att_syntax`, found `readonly`
+error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
   --> $DIR/bad-options.rs:22:25
    |
 LL | global_asm!("", options(readonly));
-   |                         ^^^^^^^^ expected one of `)` or `att_syntax`
+   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)` or `att_syntax`, found `noreturn`
+error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
   --> $DIR/bad-options.rs:24:25
    |
 LL | global_asm!("", options(noreturn));
-   |                         ^^^^^^^^ expected one of `)` or `att_syntax`
+   |                         ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)` or `att_syntax`, found `pure`
+error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
   --> $DIR/bad-options.rs:26:25
    |
 LL | global_asm!("", options(pure));
-   |                         ^^^^ expected one of `)` or `att_syntax`
+   |                         ^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)` or `att_syntax`, found `nostack`
+error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
   --> $DIR/bad-options.rs:28:25
    |
 LL | global_asm!("", options(nostack));
-   |                         ^^^^^^^ expected one of `)` or `att_syntax`
+   |                         ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)` or `att_syntax`, found `preserves_flags`
+error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
   --> $DIR/bad-options.rs:30:25
    |
 LL | global_asm!("", options(preserves_flags));
-   |                         ^^^^^^^^^^^^^^^ expected one of `)` or `att_syntax`
+   |                         ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: aborting due to 11 previous errors
 
diff --git a/src/test/ui/asm/inline-syntax.arm.stderr b/src/test/ui/asm/inline-syntax.arm.stderr
index b1685bd4e02..bf6ea6b67f9 100644
--- a/src/test/ui/asm/inline-syntax.arm.stderr
+++ b/src/test/ui/asm/inline-syntax.arm.stderr
@@ -13,7 +13,7 @@ LL | .intel_syntax noprefix
    | ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:29:15
+  --> $DIR/inline-syntax.rs:31:15
    |
 LL |         asm!(".intel_syntax noprefix", "nop");
    |               ^
@@ -25,7 +25,7 @@ LL |     .intel_syntax noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:32:15
+  --> $DIR/inline-syntax.rs:34:15
    |
 LL |         asm!(".intel_syntax aaa noprefix", "nop");
    |               ^
@@ -37,7 +37,7 @@ LL |     .intel_syntax aaa noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:35:15
+  --> $DIR/inline-syntax.rs:37:15
    |
 LL |         asm!(".att_syntax noprefix", "nop");
    |               ^
@@ -49,7 +49,7 @@ LL |     .att_syntax noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:38:15
+  --> $DIR/inline-syntax.rs:40:15
    |
 LL |         asm!(".att_syntax bbb noprefix", "nop");
    |               ^
@@ -61,7 +61,7 @@ LL |     .att_syntax bbb noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:41:15
+  --> $DIR/inline-syntax.rs:43:15
    |
 LL |         asm!(".intel_syntax noprefix; nop");
    |               ^
@@ -73,7 +73,7 @@ LL |     .intel_syntax noprefix; nop
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:47:13
+  --> $DIR/inline-syntax.rs:49:13
    |
 LL |             .intel_syntax noprefix
    |             ^
diff --git a/src/test/ui/asm/inline-syntax.rs b/src/test/ui/asm/inline-syntax.rs
index 2d54ef7bd6b..481990398f4 100644
--- a/src/test/ui/asm/inline-syntax.rs
+++ b/src/test/ui/asm/inline-syntax.rs
@@ -1,11 +1,13 @@
-// needs-llvm-components: arm
 // revisions: x86_64 arm
 //[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
 //[x86_64] check-pass
+//[x86_64] needs-llvm-components: x86
 //[x86_64_allowed] compile-flags: --target x86_64-unknown-linux-gnu
 //[x86_64_allowed] check-pass
+//[x86_64_allowed] needs-llvm-components: x86
 //[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
 //[arm] build-fail
+//[arm] needs-llvm-components: arm
 
 #![feature(no_core, lang_items, rustc_attrs)]
 #![crate_type = "rlib"]
diff --git a/src/test/ui/asm/inline-syntax.x86_64.stderr b/src/test/ui/asm/inline-syntax.x86_64.stderr
index 59c95194322..dcbc17bb260 100644
--- a/src/test/ui/asm/inline-syntax.x86_64.stderr
+++ b/src/test/ui/asm/inline-syntax.x86_64.stderr
@@ -1,5 +1,5 @@
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:55:14
+  --> $DIR/inline-syntax.rs:57:14
    |
 LL | global_asm!(".intel_syntax noprefix", "nop");
    |              ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,37 +7,37 @@ LL | global_asm!(".intel_syntax noprefix", "nop");
    = note: `#[warn(bad_asm_style)]` on by default
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:29:15
+  --> $DIR/inline-syntax.rs:31:15
    |
 LL |         asm!(".intel_syntax noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:32:15
+  --> $DIR/inline-syntax.rs:34:15
    |
 LL |         asm!(".intel_syntax aaa noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
-  --> $DIR/inline-syntax.rs:35:15
+  --> $DIR/inline-syntax.rs:37:15
    |
 LL |         asm!(".att_syntax noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
-  --> $DIR/inline-syntax.rs:38:15
+  --> $DIR/inline-syntax.rs:40:15
    |
 LL |         asm!(".att_syntax bbb noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:41:15
+  --> $DIR/inline-syntax.rs:43:15
    |
 LL |         asm!(".intel_syntax noprefix; nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:47:13
+  --> $DIR/inline-syntax.rs:49:13
    |
 LL |             .intel_syntax noprefix
    |             ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-82869.rs b/src/test/ui/asm/issue-82869.rs
index a8e688cbe1f..a8e688cbe1f 100644
--- a/src/test/ui/issues/issue-82869.rs
+++ b/src/test/ui/asm/issue-82869.rs
diff --git a/src/test/ui/issues/issue-82869.stderr b/src/test/ui/asm/issue-82869.stderr
index d05714ea6f2..d05714ea6f2 100644
--- a/src/test/ui/issues/issue-82869.stderr
+++ b/src/test/ui/asm/issue-82869.stderr
diff --git a/src/test/ui/asm/parse-error.stderr b/src/test/ui/asm/parse-error.stderr
index afd262b851c..33dca61dc8e 100644
--- a/src/test/ui/asm/parse-error.stderr
+++ b/src/test/ui/asm/parse-error.stderr
@@ -64,11 +64,11 @@ error: argument to `sym` must be a path expression
 LL |         asm!("{}", sym foo + bar);
    |                        ^^^^^^^^^
 
-error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, or `readonly`, found `foo`
+error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo`
   --> $DIR/parse-error.rs:31:26
    |
 LL |         asm!("", options(foo));
-   |                          ^^^ expected one of 8 possible tokens
+   |                          ^^^ expected one of 9 possible tokens
 
 error: expected one of `)` or `,`, found `foo`
   --> $DIR/parse-error.rs:33:32
@@ -76,11 +76,11 @@ error: expected one of `)` or `,`, found `foo`
 LL |         asm!("", options(nomem foo));
    |                                ^^^ expected one of `)` or `,`
 
-error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, or `readonly`, found `foo`
+error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo`
   --> $DIR/parse-error.rs:35:33
    |
 LL |         asm!("", options(nomem, foo));
-   |                                 ^^^ expected one of 8 possible tokens
+   |                                 ^^^ expected one of 9 possible tokens
 
 error: arguments are not allowed after options
   --> $DIR/parse-error.rs:37:31
@@ -200,23 +200,23 @@ error: expected one of `,`, `.`, `?`, or an operator, found `FOO`
 LL | global_asm!("{}", const(reg) FOO);
    |                              ^^^ expected one of `,`, `.`, `?`, or an operator
 
-error: expected one of `)` or `att_syntax`, found `FOO`
+error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
   --> $DIR/parse-error.rs:81:25
    |
 LL | global_asm!("", options(FOO));
-   |                         ^^^ expected one of `)` or `att_syntax`
+   |                         ^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)` or `att_syntax`, found `nomem`
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
   --> $DIR/parse-error.rs:83:25
    |
 LL | global_asm!("", options(nomem FOO));
-   |                         ^^^^^ expected one of `)` or `att_syntax`
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
-error: expected one of `)` or `att_syntax`, found `nomem`
+error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
   --> $DIR/parse-error.rs:85:25
    |
 LL | global_asm!("", options(nomem, FOO));
-   |                         ^^^^^ expected one of `)` or `att_syntax`
+   |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: arguments are not allowed after options
   --> $DIR/parse-error.rs:87:30
diff --git a/src/test/ui/issues/issue-20005.rs b/src/test/ui/associated-types/issue-20005.rs
index 36350bff100..36350bff100 100644
--- a/src/test/ui/issues/issue-20005.rs
+++ b/src/test/ui/associated-types/issue-20005.rs
diff --git a/src/test/ui/issues/issue-20005.stderr b/src/test/ui/associated-types/issue-20005.stderr
index bc414044f78..bc414044f78 100644
--- a/src/test/ui/issues/issue-20005.stderr
+++ b/src/test/ui/associated-types/issue-20005.stderr
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs
index a3a20cb97e1..50c1639996e 100644
--- a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs
+++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs
@@ -3,36 +3,36 @@
 
 mod outer_mod {
     pub mod await { //~ ERROR `await` is a keyword in the 2018 edition
-    //~^ WARN this was previously accepted by the compiler
+    //~^ WARN this is accepted in the current edition
         pub struct await; //~ ERROR `await` is a keyword in the 2018 edition
-        //~^ WARN this was previously accepted by the compiler
+        //~^ WARN this is accepted in the current edition
     }
 }
 use outer_mod::await::await; //~ ERROR `await` is a keyword in the 2018 edition
 //~^ ERROR `await` is a keyword in the 2018 edition
-//~^^ WARN this was previously accepted by the compiler
-//~^^^ WARN this was previously accepted by the compiler
+//~^^ WARN this is accepted in the current edition
+//~^^^ WARN this is accepted in the current edition
 
 struct Foo { await: () }
 //~^ ERROR `await` is a keyword in the 2018 edition
-//~^^ WARN this was previously accepted by the compiler
+//~^^ WARN this is accepted in the current edition
 
 impl Foo { fn await() {} }
 //~^ ERROR `await` is a keyword in the 2018 edition
-//~^^ WARN this was previously accepted by the compiler
+//~^^ WARN this is accepted in the current edition
 
 macro_rules! await {
 //~^ ERROR `await` is a keyword in the 2018 edition
-//~^^ WARN this was previously accepted by the compiler
+//~^^ WARN this is accepted in the current edition
     () => {}
 }
 
 fn main() {
     await!(); //~ ERROR `await` is a keyword in the 2018 edition
-    //~^ WARN this was previously accepted by the compiler
+    //~^ WARN this is accepted in the current edition
 
     match await { await => {} } //~ ERROR `await` is a keyword in the 2018 edition
     //~^ ERROR `await` is a keyword in the 2018 edition
-    //~^^ WARN this was previously accepted by the compiler
-    //~^^^ WARN this was previously accepted by the compiler
+    //~^^ WARN this is accepted in the current edition
+    //~^^^ WARN this is accepted in the current edition
 }
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr
index 474c09d79df..50a82c08c3f 100644
--- a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr
+++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(keyword_idents)]
    |         ^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -18,7 +18,7 @@ error: `await` is a keyword in the 2018 edition
 LL |         pub struct await;
    |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -27,7 +27,7 @@ error: `await` is a keyword in the 2018 edition
 LL | use outer_mod::await::await;
    |                ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -36,7 +36,7 @@ error: `await` is a keyword in the 2018 edition
 LL | use outer_mod::await::await;
    |                       ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -45,7 +45,7 @@ error: `await` is a keyword in the 2018 edition
 LL | struct Foo { await: () }
    |              ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -54,7 +54,7 @@ error: `await` is a keyword in the 2018 edition
 LL | impl Foo { fn await() {} }
    |               ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -63,7 +63,7 @@ error: `await` is a keyword in the 2018 edition
 LL | macro_rules! await {
    |              ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -72,7 +72,7 @@ error: `await` is a keyword in the 2018 edition
 LL |     await!();
    |     ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -81,7 +81,7 @@ error: `await` is a keyword in the 2018 edition
 LL |     match await { await => {} }
    |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -90,7 +90,7 @@ error: `await` is a keyword in the 2018 edition
 LL |     match await { await => {} }
    |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: aborting due to 10 previous errors
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-warning.fixed b/src/test/ui/async-await/await-keyword/2015-edition-warning.fixed
index c58496c91f5..117495e130f 100644
--- a/src/test/ui/async-await/await-keyword/2015-edition-warning.fixed
+++ b/src/test/ui/async-await/await-keyword/2015-edition-warning.fixed
@@ -6,22 +6,22 @@
 mod outer_mod {
     pub mod r#await {
 //~^ ERROR `await` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
         pub struct r#await;
 //~^ ERROR `await` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
     }
 }
 use outer_mod::r#await::r#await;
 //~^ ERROR `await` is a keyword
 //~| ERROR `await` is a keyword
-//~| WARN was previously accepted
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
+//~| WARN this is accepted in the current edition
 
 fn main() {
     match r#await { r#await => {} }
 //~^ ERROR `await` is a keyword
 //~| ERROR `await` is a keyword
-//~| WARN was previously accepted
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
+//~| WARN this is accepted in the current edition
 }
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-warning.rs b/src/test/ui/async-await/await-keyword/2015-edition-warning.rs
index a7543a14325..b3c64895c6d 100644
--- a/src/test/ui/async-await/await-keyword/2015-edition-warning.rs
+++ b/src/test/ui/async-await/await-keyword/2015-edition-warning.rs
@@ -6,22 +6,22 @@
 mod outer_mod {
     pub mod await {
 //~^ ERROR `await` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
         pub struct await;
 //~^ ERROR `await` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
     }
 }
 use outer_mod::await::await;
 //~^ ERROR `await` is a keyword
 //~| ERROR `await` is a keyword
-//~| WARN was previously accepted
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
+//~| WARN this is accepted in the current edition
 
 fn main() {
     match await { await => {} }
 //~^ ERROR `await` is a keyword
 //~| ERROR `await` is a keyword
-//~| WARN was previously accepted
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
+//~| WARN this is accepted in the current edition
 }
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr b/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr
index 0c558eb12f0..1c4c19ea45f 100644
--- a/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr
+++ b/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(keyword_idents)]
    |         ^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -18,7 +18,7 @@ error: `await` is a keyword in the 2018 edition
 LL |         pub struct await;
    |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -27,7 +27,7 @@ error: `await` is a keyword in the 2018 edition
 LL | use outer_mod::await::await;
    |                ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -36,7 +36,7 @@ error: `await` is a keyword in the 2018 edition
 LL | use outer_mod::await::await;
    |                       ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -45,7 +45,7 @@ error: `await` is a keyword in the 2018 edition
 LL |     match await { await => {} }
    |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
@@ -54,7 +54,7 @@ error: `await` is a keyword in the 2018 edition
 LL |     match await { await => {} }
    |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: aborting due to 6 previous errors
diff --git a/src/test/ui/async-await/issue-84841.rs b/src/test/ui/async-await/issue-84841.rs
new file mode 100644
index 00000000000..ba3a1617b9c
--- /dev/null
+++ b/src/test/ui/async-await/issue-84841.rs
@@ -0,0 +1,16 @@
+// edition:2018
+
+fn main() {
+
+}
+
+async fn foo() {
+    // Adding an .await here avoids the ICE
+    test()?;
+    //~^ ERROR the `?` operator can only be applied to values that implement `Try`
+    //~| ERROR the `?` operator can only be used in an async function that returns
+}
+
+// Removing the const generic parameter here avoids the ICE
+async fn test<const N: usize>() {
+}
diff --git a/src/test/ui/async-await/issue-84841.stderr b/src/test/ui/async-await/issue-84841.stderr
new file mode 100644
index 00000000000..170dcf581ed
--- /dev/null
+++ b/src/test/ui/async-await/issue-84841.stderr
@@ -0,0 +1,28 @@
+error[E0277]: the `?` operator can only be applied to values that implement `Try`
+  --> $DIR/issue-84841.rs:9:5
+   |
+LL |     test()?;
+   |     ^^^^^^^ the `?` operator cannot be applied to type `impl Future`
+   |
+   = help: the trait `Try` is not implemented for `impl Future`
+   = note: required by `branch`
+
+error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`)
+  --> $DIR/issue-84841.rs:9:11
+   |
+LL |   async fn foo() {
+   |  ________________-
+LL | |     // Adding an .await here avoids the ICE
+LL | |     test()?;
+   | |           ^ cannot use the `?` operator in an async function that returns `()`
+LL | |
+LL | |
+LL | | }
+   | |_- this function should return `Result` or `Option` to accept `?`
+   |
+   = help: the trait `FromResidual<_>` is not implemented for `()`
+   = note: required by `from_residual`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/fsu-moves-and-copies.rs b/src/test/ui/borrowck/fsu-moves-and-copies.rs
index 6a0b4ed17b9..6a0b4ed17b9 100644
--- a/src/test/ui/fsu-moves-and-copies.rs
+++ b/src/test/ui/borrowck/fsu-moves-and-copies.rs
diff --git a/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs b/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs
index f7392bfeaab..50248a55838 100644
--- a/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs
+++ b/src/test/ui/borrowck/two-phase-reservation-sharing-interference.rs
@@ -1,8 +1,8 @@
 // revisions: nll_target
 
-// The following revisions are disabled due to missing support from two-phase beyond autorefs
+// The nll_beyond revision is disabled due to missing support from two-phase beyond autorefs
 //[nll_beyond]compile-flags: -Z borrowck=mir -Z two-phase-beyond-autoref
-//[nll_beyond] should-fail
+//[nll_beyond]should-fail
 
 //[nll_target]compile-flags: -Z borrowck=mir
 
diff --git a/src/test/ui/cast/fat-ptr-cast-rpass.rs b/src/test/ui/cast/fat-ptr-cast-rpass.rs
index 9fa2255e1b3..f5747eb8b96 100644
--- a/src/test/ui/cast/fat-ptr-cast-rpass.rs
+++ b/src/test/ui/cast/fat-ptr-cast-rpass.rs
@@ -1,12 +1,6 @@
 // run-pass
 
-// Remove this file when `std::raw` is removed.
-// The replacement pointer metadata APIs are tested in library/core/tests/ptr.rs
-#![allow(deprecated)]
-#![feature(raw)]
-
-use std::mem;
-use std::raw;
+#![feature(ptr_metadata)]
 
 trait Foo {
     fn foo(&self) {}
@@ -31,13 +25,10 @@ fn main() {
 
     // And conversion to a void pointer/address for trait objects too.
     let a: *mut dyn Foo = &mut Bar;
-    let b = a as *mut ();
+    let b = a as *mut () as usize;
     let c = a as *const () as usize;
-    let d = unsafe {
-        let r: raw::TraitObject = mem::transmute(a);
-        r.data
-    };
+    let d = a.to_raw_parts().0 as usize;
 
     assert_eq!(b, d);
-    assert_eq!(c, d as usize);
+    assert_eq!(c, d);
 }
diff --git a/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.rs b/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.rs
index 131af6a10c8..7a4b21f0223 100644
--- a/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.rs
+++ b/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.rs
@@ -1,7 +1,4 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| `#[warn(incomplete_features)]` on by default
-//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
 #![feature(rustc_attrs)]
 
 // Ensure that capture analysis results in arrays being completely captured.
diff --git a/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr b/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr
index 2a350f30331..69ec53447b8 100644
--- a/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/arrays-completely-captured.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/arrays-completely-captured.rs:11:17
+  --> $DIR/arrays-completely-captured.rs:8:17
    |
 LL |     let mut c = #[rustc_capture_analysis]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let mut c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/arrays-completely-captured.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/arrays-completely-captured.rs:14:5
+  --> $DIR/arrays-completely-captured.rs:11:5
    |
 LL | /     || {
 LL | |
@@ -29,13 +20,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing m[] -> MutBorrow
-  --> $DIR/arrays-completely-captured.rs:17:9
+  --> $DIR/arrays-completely-captured.rs:14:9
    |
 LL |         m[0] += 10;
    |         ^
 
 error: Min Capture analysis includes:
-  --> $DIR/arrays-completely-captured.rs:14:5
+  --> $DIR/arrays-completely-captured.rs:11:5
    |
 LL | /     || {
 LL | |
@@ -47,11 +38,11 @@ LL | |     };
    | |_____^
    |
 note: Min Capture m[] -> MutBorrow
-  --> $DIR/arrays-completely-captured.rs:17:9
+  --> $DIR/arrays-completely-captured.rs:14:9
    |
 LL |         m[0] += 10;
    |         ^
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/by_value.rs b/src/test/ui/closures/2229_closure_analysis/by_value.rs
index 27c8fb1363f..02a243e0506 100644
--- a/src/test/ui/closures/2229_closure_analysis/by_value.rs
+++ b/src/test/ui/closures/2229_closure_analysis/by_value.rs
@@ -1,11 +1,7 @@
+// edition:2021
+
 // Test that we handle derferences properly when only some of the captures are being moved with
 // `capture_disjoint_fields` enabled.
-
-
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![feature(rustc_attrs)]
 
 #[derive(Debug, Default)]
diff --git a/src/test/ui/closures/2229_closure_analysis/by_value.stderr b/src/test/ui/closures/2229_closure_analysis/by_value.stderr
index 944e4c40a78..7014ae6a5e6 100644
--- a/src/test/ui/closures/2229_closure_analysis/by_value.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/by_value.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/by_value.rs:22:13
+  --> $DIR/by_value.rs:18:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/by_value.rs:5:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/by_value.rs:25:5
+  --> $DIR/by_value.rs:21:5
    |
 LL | /     || {
 LL | |
@@ -29,23 +20,23 @@ LL | |     };
    | |_____^
    |
 note: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
-  --> $DIR/by_value.rs:28:17
+  --> $DIR/by_value.rs:24:17
    |
 LL |         let p = t.0.0;
    |                 ^^^^^
 note: Capturing t[(0, 0)] -> ByValue
-  --> $DIR/by_value.rs:28:17
+  --> $DIR/by_value.rs:24:17
    |
 LL |         let p = t.0.0;
    |                 ^^^^^
 note: Capturing t[(1, 0)] -> ImmBorrow
-  --> $DIR/by_value.rs:32:29
+  --> $DIR/by_value.rs:28:29
    |
 LL |         println!("{} {:?}", t.1, p);
    |                             ^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/by_value.rs:25:5
+  --> $DIR/by_value.rs:21:5
    |
 LL | /     || {
 LL | |
@@ -57,16 +48,16 @@ LL | |     };
    | |_____^
    |
 note: Min Capture t[(0, 0)] -> ByValue
-  --> $DIR/by_value.rs:28:17
+  --> $DIR/by_value.rs:24:17
    |
 LL |         let p = t.0.0;
    |                 ^^^^^
 note: Min Capture t[(1, 0)] -> ImmBorrow
-  --> $DIR/by_value.rs:32:29
+  --> $DIR/by_value.rs:28:29
    |
 LL |         println!("{} {:?}", t.1, p);
    |                             ^^^
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs
index 4368c830e1c..dc53b31768e 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(rustc_attrs)]
 
 #[derive(Debug)]
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr
index 09255343af0..fceafb9c84e 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-1.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/capture-analysis-1.rs:17:13
+  --> $DIR/capture-analysis-1.rs:15:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/capture-analysis-1.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/capture-analysis-1.rs:20:5
+  --> $DIR/capture-analysis-1.rs:18:5
    |
 LL | /     || {
 LL | |
@@ -29,28 +20,28 @@ LL | |     };
    | |_____^
    |
 note: Capturing p[] -> ImmBorrow
-  --> $DIR/capture-analysis-1.rs:23:26
+  --> $DIR/capture-analysis-1.rs:21:26
    |
 LL |         println!("{:?}", p);
    |                          ^
 note: Capturing p[(0, 0)] -> ImmBorrow
-  --> $DIR/capture-analysis-1.rs:26:26
+  --> $DIR/capture-analysis-1.rs:24:26
    |
 LL |         println!("{:?}", p.x);
    |                          ^^^
 note: Capturing q[(0, 0)] -> ImmBorrow
-  --> $DIR/capture-analysis-1.rs:29:26
+  --> $DIR/capture-analysis-1.rs:27:26
    |
 LL |         println!("{:?}", q.x);
    |                          ^^^
 note: Capturing q[] -> ImmBorrow
-  --> $DIR/capture-analysis-1.rs:31:26
+  --> $DIR/capture-analysis-1.rs:29:26
    |
 LL |         println!("{:?}", q);
    |                          ^
 
 error: Min Capture analysis includes:
-  --> $DIR/capture-analysis-1.rs:20:5
+  --> $DIR/capture-analysis-1.rs:18:5
    |
 LL | /     || {
 LL | |
@@ -62,16 +53,16 @@ LL | |     };
    | |_____^
    |
 note: Min Capture p[] -> ImmBorrow
-  --> $DIR/capture-analysis-1.rs:23:26
+  --> $DIR/capture-analysis-1.rs:21:26
    |
 LL |         println!("{:?}", p);
    |                          ^
 note: Min Capture q[] -> ImmBorrow
-  --> $DIR/capture-analysis-1.rs:31:26
+  --> $DIR/capture-analysis-1.rs:29:26
    |
 LL |         println!("{:?}", q);
    |                          ^
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs
index ab7fce6a430..99d12f8d8f1 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(rustc_attrs)]
 
 #[derive(Debug)]
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr
index 0e48d6b300b..cb44ca26652 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-2.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/capture-analysis-2.rs:16:13
+  --> $DIR/capture-analysis-2.rs:14:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/capture-analysis-2.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/capture-analysis-2.rs:19:5
+  --> $DIR/capture-analysis-2.rs:17:5
    |
 LL | /     || {
 LL | |
@@ -29,18 +20,18 @@ LL | |     };
    | |_____^
    |
 note: Capturing p[(0, 0)] -> ByValue
-  --> $DIR/capture-analysis-2.rs:22:18
+  --> $DIR/capture-analysis-2.rs:20:18
    |
 LL |         let _x = p.x;
    |                  ^^^
 note: Capturing p[] -> ImmBorrow
-  --> $DIR/capture-analysis-2.rs:25:26
+  --> $DIR/capture-analysis-2.rs:23:26
    |
 LL |         println!("{:?}", p);
    |                          ^
 
 error: Min Capture analysis includes:
-  --> $DIR/capture-analysis-2.rs:19:5
+  --> $DIR/capture-analysis-2.rs:17:5
    |
 LL | /     || {
 LL | |
@@ -52,7 +43,7 @@ LL | |     };
    | |_____^
    |
 note: Min Capture p[] -> ByValue
-  --> $DIR/capture-analysis-2.rs:22:18
+  --> $DIR/capture-analysis-2.rs:20:18
    |
 LL |         let _x = p.x;
    |                  ^^^ p[] captured as ByValue here
@@ -60,6 +51,6 @@ LL |         let _x = p.x;
 LL |         println!("{:?}", p);
    |                          ^ p[] used here
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs
index 817ade899e2..3f337097dbd 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(rustc_attrs)]
 
 #[derive(Debug)]
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr
index 263e9ca56eb..71e7bdc354f 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-3.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/capture-analysis-3.rs:21:13
+  --> $DIR/capture-analysis-3.rs:19:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/capture-analysis-3.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/capture-analysis-3.rs:24:5
+  --> $DIR/capture-analysis-3.rs:22:5
    |
 LL | /     || {
 LL | |
@@ -29,18 +20,18 @@ LL | |     };
    | |_____^
    |
 note: Capturing a[(0, 0),(0, 0)] -> ByValue
-  --> $DIR/capture-analysis-3.rs:27:18
+  --> $DIR/capture-analysis-3.rs:25:18
    |
 LL |         let _x = a.b.c;
    |                  ^^^^^
 note: Capturing a[(0, 0)] -> ImmBorrow
-  --> $DIR/capture-analysis-3.rs:30:26
+  --> $DIR/capture-analysis-3.rs:28:26
    |
 LL |         println!("{:?}", a.b);
    |                          ^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/capture-analysis-3.rs:24:5
+  --> $DIR/capture-analysis-3.rs:22:5
    |
 LL | /     || {
 LL | |
@@ -52,7 +43,7 @@ LL | |     };
    | |_____^
    |
 note: Min Capture a[(0, 0)] -> ByValue
-  --> $DIR/capture-analysis-3.rs:27:18
+  --> $DIR/capture-analysis-3.rs:25:18
    |
 LL |         let _x = a.b.c;
    |                  ^^^^^ a[(0, 0)] captured as ByValue here
@@ -60,6 +51,6 @@ LL |         let _x = a.b.c;
 LL |         println!("{:?}", a.b);
    |                          ^^^ a[(0, 0)] used here
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs b/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs
index e8401299b30..bc46ec99736 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(rustc_attrs)]
 
 #[derive(Debug)]
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr b/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr
index f4605c1d51b..7e6e625bc7d 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/capture-analysis-4.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/capture-analysis-4.rs:21:13
+  --> $DIR/capture-analysis-4.rs:19:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/capture-analysis-4.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/capture-analysis-4.rs:24:5
+  --> $DIR/capture-analysis-4.rs:22:5
    |
 LL | /     || {
 LL | |
@@ -29,18 +20,18 @@ LL | |     };
    | |_____^
    |
 note: Capturing a[(0, 0)] -> ByValue
-  --> $DIR/capture-analysis-4.rs:27:18
+  --> $DIR/capture-analysis-4.rs:25:18
    |
 LL |         let _x = a.b;
    |                  ^^^
 note: Capturing a[(0, 0),(0, 0)] -> ImmBorrow
-  --> $DIR/capture-analysis-4.rs:30:26
+  --> $DIR/capture-analysis-4.rs:28:26
    |
 LL |         println!("{:?}", a.b.c);
    |                          ^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/capture-analysis-4.rs:24:5
+  --> $DIR/capture-analysis-4.rs:22:5
    |
 LL | /     || {
 LL | |
@@ -52,11 +43,11 @@ LL | |     };
    | |_____^
    |
 note: Min Capture a[(0, 0)] -> ByValue
-  --> $DIR/capture-analysis-4.rs:27:18
+  --> $DIR/capture-analysis-4.rs:25:18
    |
 LL |         let _x = a.b;
    |                  ^^^
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.rs b/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.rs
index ba495508537..6fd15155331 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.rs
+++ b/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.rs
@@ -1,9 +1,5 @@
-// FIXME(arora-aman) add run-pass once 2229 is implemented
+// edition:2021
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![feature(rustc_attrs)]
 
 struct Point {
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.stderr b/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.stderr
index 5fac6963afd..0f64ecf3a0c 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-struct.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/capture-disjoint-field-struct.rs:17:13
+  --> $DIR/capture-disjoint-field-struct.rs:13:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/capture-disjoint-field-struct.rs:3:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/capture-disjoint-field-struct.rs:20:5
+  --> $DIR/capture-disjoint-field-struct.rs:16:5
    |
 LL | /     || {
 LL | |
@@ -29,13 +20,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing p[(0, 0)] -> ImmBorrow
-  --> $DIR/capture-disjoint-field-struct.rs:23:24
+  --> $DIR/capture-disjoint-field-struct.rs:19:24
    |
 LL |         println!("{}", p.x);
    |                        ^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/capture-disjoint-field-struct.rs:20:5
+  --> $DIR/capture-disjoint-field-struct.rs:16:5
    |
 LL | /     || {
 LL | |
@@ -47,11 +38,11 @@ LL | |     };
    | |_____^
    |
 note: Min Capture p[(0, 0)] -> ImmBorrow
-  --> $DIR/capture-disjoint-field-struct.rs:23:24
+  --> $DIR/capture-disjoint-field-struct.rs:19:24
    |
 LL |         println!("{}", p.x);
    |                        ^^^
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.rs b/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.rs
index c1693fbad79..8d3bb3262fb 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.rs
+++ b/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.rs
@@ -1,9 +1,5 @@
-// FIXME(arora-aman) add run-pass once 2229 is implemented
+// edition:2021
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![feature(rustc_attrs)]
 
 fn main() {
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.stderr b/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.stderr
index 1bfd63f2ace..a8ca9622a6a 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/capture-disjoint-field-tuple.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/capture-disjoint-field-tuple.rs:12:13
+  --> $DIR/capture-disjoint-field-tuple.rs:8:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/capture-disjoint-field-tuple.rs:3:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/capture-disjoint-field-tuple.rs:15:5
+  --> $DIR/capture-disjoint-field-tuple.rs:11:5
    |
 LL | /     || {
 LL | |
@@ -29,13 +20,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing t[(0, 0)] -> ImmBorrow
-  --> $DIR/capture-disjoint-field-tuple.rs:18:24
+  --> $DIR/capture-disjoint-field-tuple.rs:14:24
    |
 LL |         println!("{}", t.0);
    |                        ^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/capture-disjoint-field-tuple.rs:15:5
+  --> $DIR/capture-disjoint-field-tuple.rs:11:5
    |
 LL | /     || {
 LL | |
@@ -47,11 +38,11 @@ LL | |     };
    | |_____^
    |
 note: Min Capture t[(0, 0)] -> ImmBorrow
-  --> $DIR/capture-disjoint-field-tuple.rs:18:24
+  --> $DIR/capture-disjoint-field-tuple.rs:14:24
    |
 LL |         println!("{}", t.0);
    |                        ^^^
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-enums.rs b/src/test/ui/closures/2229_closure_analysis/capture-enums.rs
index 8fb2f7f16d6..322ae99b861 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-enums.rs
+++ b/src/test/ui/closures/2229_closure_analysis/capture-enums.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(rustc_attrs)]
 
 enum Info {
diff --git a/src/test/ui/closures/2229_closure_analysis/capture-enums.stderr b/src/test/ui/closures/2229_closure_analysis/capture-enums.stderr
index ebe1dcb9884..8a6ba8444a8 100644
--- a/src/test/ui/closures/2229_closure_analysis/capture-enums.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/capture-enums.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/capture-enums.rs:18:13
+  --> $DIR/capture-enums.rs:16:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/capture-enums.rs:49:13
+  --> $DIR/capture-enums.rs:47:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,17 +16,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/capture-enums.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/capture-enums.rs:21:5
+  --> $DIR/capture-enums.rs:19:5
    |
 LL | /     || {
 LL | |
@@ -38,28 +29,28 @@ LL | |     };
    | |_____^
    |
 note: Capturing point[] -> ImmBorrow
-  --> $DIR/capture-enums.rs:24:41
+  --> $DIR/capture-enums.rs:22:41
    |
 LL |         if let Info::Point(_, _, str) = point {
    |                                         ^^^^^
 note: Capturing point[(2, 0)] -> ByValue
-  --> $DIR/capture-enums.rs:24:41
+  --> $DIR/capture-enums.rs:22:41
    |
 LL |         if let Info::Point(_, _, str) = point {
    |                                         ^^^^^
 note: Capturing meta[] -> ImmBorrow
-  --> $DIR/capture-enums.rs:31:35
+  --> $DIR/capture-enums.rs:29:35
    |
 LL |         if let Info::Meta(_, v) = meta {
    |                                   ^^^^
 note: Capturing meta[(1, 1)] -> ByValue
-  --> $DIR/capture-enums.rs:31:35
+  --> $DIR/capture-enums.rs:29:35
    |
 LL |         if let Info::Meta(_, v) = meta {
    |                                   ^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/capture-enums.rs:21:5
+  --> $DIR/capture-enums.rs:19:5
    |
 LL | /     || {
 LL | |
@@ -71,18 +62,18 @@ LL | |     };
    | |_____^
    |
 note: Min Capture point[] -> ByValue
-  --> $DIR/capture-enums.rs:24:41
+  --> $DIR/capture-enums.rs:22:41
    |
 LL |         if let Info::Point(_, _, str) = point {
    |                                         ^^^^^
 note: Min Capture meta[] -> ByValue
-  --> $DIR/capture-enums.rs:31:35
+  --> $DIR/capture-enums.rs:29:35
    |
 LL |         if let Info::Meta(_, v) = meta {
    |                                   ^^^^
 
 error: First Pass analysis includes:
-  --> $DIR/capture-enums.rs:52:5
+  --> $DIR/capture-enums.rs:50:5
    |
 LL | /     || {
 LL | |
@@ -94,13 +85,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing point[(2, 0)] -> ByValue
-  --> $DIR/capture-enums.rs:55:47
+  --> $DIR/capture-enums.rs:53:47
    |
 LL |         let SingleVariant::Point(_, _, str) = point;
    |                                               ^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/capture-enums.rs:52:5
+  --> $DIR/capture-enums.rs:50:5
    |
 LL | /     || {
 LL | |
@@ -112,11 +103,11 @@ LL | |     };
    | |_____^
    |
 note: Min Capture point[(2, 0)] -> ByValue
-  --> $DIR/capture-enums.rs:55:47
+  --> $DIR/capture-enums.rs:53:47
    |
 LL |         let SingleVariant::Point(_, _, str) = point;
    |                                               ^^^^^
 
-error: aborting due to 6 previous errors; 1 warning emitted
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs
index f81866bb7e0..3341166e22b 100644
--- a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs
+++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(rustc_attrs)]
 #![allow(unused)]
 
diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr
index 863f1009131..29e1af0431e 100644
--- a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-struct.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/deep-multilevel-struct.rs:36:13
+  --> $DIR/deep-multilevel-struct.rs:34:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/deep-multilevel-struct.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/deep-multilevel-struct.rs:39:5
+  --> $DIR/deep-multilevel-struct.rs:37:5
    |
 LL | /     || {
 LL | |
@@ -29,23 +20,23 @@ LL | |     };
    | |_____^
    |
 note: Capturing p[(0, 0),(0, 0),(0, 0)] -> ImmBorrow
-  --> $DIR/deep-multilevel-struct.rs:42:18
+  --> $DIR/deep-multilevel-struct.rs:40:18
    |
 LL |         let x = &p.a.p.x;
    |                  ^^^^^^^
 note: Capturing p[(1, 0),(1, 0),(1, 0)] -> MutBorrow
-  --> $DIR/deep-multilevel-struct.rs:44:9
+  --> $DIR/deep-multilevel-struct.rs:42:9
    |
 LL |         p.b.q.y = 9;
    |         ^^^^^^^
 note: Capturing p[] -> ImmBorrow
-  --> $DIR/deep-multilevel-struct.rs:47:26
+  --> $DIR/deep-multilevel-struct.rs:45:26
    |
 LL |         println!("{:?}", p);
    |                          ^
 
 error: Min Capture analysis includes:
-  --> $DIR/deep-multilevel-struct.rs:39:5
+  --> $DIR/deep-multilevel-struct.rs:37:5
    |
 LL | /     || {
 LL | |
@@ -57,7 +48,7 @@ LL | |     };
    | |_____^
    |
 note: Min Capture p[] -> MutBorrow
-  --> $DIR/deep-multilevel-struct.rs:44:9
+  --> $DIR/deep-multilevel-struct.rs:42:9
    |
 LL |         p.b.q.y = 9;
    |         ^^^^^^^ p[] captured as MutBorrow here
@@ -65,6 +56,6 @@ LL |         p.b.q.y = 9;
 LL |         println!("{:?}", p);
    |                          ^ p[] used here
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs
index fb03a02efa0..34b0132f3cb 100644
--- a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs
+++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.rs
@@ -1,7 +1,4 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
 #![feature(rustc_attrs)]
 #![allow(unused)]
 
diff --git a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr
index 252db444732..e917516765c 100644
--- a/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/deep-multilevel-tuple.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/deep-multilevel-tuple.rs:11:13
+  --> $DIR/deep-multilevel-tuple.rs:8:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/deep-multilevel-tuple.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/deep-multilevel-tuple.rs:14:5
+  --> $DIR/deep-multilevel-tuple.rs:11:5
    |
 LL | /     || {
 LL | |
@@ -29,23 +20,23 @@ LL | |     };
    | |_____^
    |
 note: Capturing t[(0, 0),(0, 0),(0, 0)] -> ImmBorrow
-  --> $DIR/deep-multilevel-tuple.rs:17:18
+  --> $DIR/deep-multilevel-tuple.rs:14:18
    |
 LL |         let x = &t.0.0.0;
    |                  ^^^^^^^
 note: Capturing t[(1, 0),(1, 0),(1, 0)] -> MutBorrow
-  --> $DIR/deep-multilevel-tuple.rs:19:9
+  --> $DIR/deep-multilevel-tuple.rs:16:9
    |
 LL |         t.1.1.1 = 9;
    |         ^^^^^^^
 note: Capturing t[] -> ImmBorrow
-  --> $DIR/deep-multilevel-tuple.rs:22:26
+  --> $DIR/deep-multilevel-tuple.rs:19:26
    |
 LL |         println!("{:?}", t);
    |                          ^
 
 error: Min Capture analysis includes:
-  --> $DIR/deep-multilevel-tuple.rs:14:5
+  --> $DIR/deep-multilevel-tuple.rs:11:5
    |
 LL | /     || {
 LL | |
@@ -57,7 +48,7 @@ LL | |     };
    | |_____^
    |
 note: Min Capture t[] -> MutBorrow
-  --> $DIR/deep-multilevel-tuple.rs:19:9
+  --> $DIR/deep-multilevel-tuple.rs:16:9
    |
 LL |         t.1.1.1 = 9;
    |         ^^^^^^^ t[] captured as MutBorrow here
@@ -65,6 +56,6 @@ LL |         t.1.1.1 = 9;
 LL |         println!("{:?}", t);
    |                          ^ t[] used here
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/destructure_patterns.rs b/src/test/ui/closures/2229_closure_analysis/destructure_patterns.rs
index 080ca0405b4..9918802334e 100644
--- a/src/test/ui/closures/2229_closure_analysis/destructure_patterns.rs
+++ b/src/test/ui/closures/2229_closure_analysis/destructure_patterns.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(rustc_attrs)]
 
 // Test to ensure Index projections are handled properly during capture analysis
diff --git a/src/test/ui/closures/2229_closure_analysis/destructure_patterns.stderr b/src/test/ui/closures/2229_closure_analysis/destructure_patterns.stderr
index 06ccc2d7a88..b53adb52481 100644
--- a/src/test/ui/closures/2229_closure_analysis/destructure_patterns.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/destructure_patterns.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/destructure_patterns.rs:12:13
+  --> $DIR/destructure_patterns.rs:10:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/destructure_patterns.rs:38:13
+  --> $DIR/destructure_patterns.rs:36:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     let c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/destructure_patterns.rs:58:13
+  --> $DIR/destructure_patterns.rs:56:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,17 +25,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/destructure_patterns.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/destructure_patterns.rs:15:5
+  --> $DIR/destructure_patterns.rs:13:5
    |
 LL | /     || {
 LL | |
@@ -47,13 +38,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing arr[Index] -> ByValue
-  --> $DIR/destructure_patterns.rs:18:29
+  --> $DIR/destructure_patterns.rs:16:29
    |
 LL |         let [a, b, .., e] = arr;
    |                             ^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/destructure_patterns.rs:15:5
+  --> $DIR/destructure_patterns.rs:13:5
    |
 LL | /     || {
 LL | |
@@ -65,13 +56,13 @@ LL | |     };
    | |_____^
    |
 note: Min Capture arr[] -> ByValue
-  --> $DIR/destructure_patterns.rs:18:29
+  --> $DIR/destructure_patterns.rs:16:29
    |
 LL |         let [a, b, .., e] = arr;
    |                             ^^^
 
 error: First Pass analysis includes:
-  --> $DIR/destructure_patterns.rs:41:5
+  --> $DIR/destructure_patterns.rs:39:5
    |
 LL | /     || {
 LL | |
@@ -83,18 +74,18 @@ LL | |     };
    | |_____^
    |
 note: Capturing p[(0, 0)] -> MutBorrow
-  --> $DIR/destructure_patterns.rs:44:58
+  --> $DIR/destructure_patterns.rs:42:58
    |
 LL |         let Point { x: ref mut x, y: _, id: moved_id } = p;
    |                                                          ^
 note: Capturing p[(2, 0)] -> ByValue
-  --> $DIR/destructure_patterns.rs:44:58
+  --> $DIR/destructure_patterns.rs:42:58
    |
 LL |         let Point { x: ref mut x, y: _, id: moved_id } = p;
    |                                                          ^
 
 error: Min Capture analysis includes:
-  --> $DIR/destructure_patterns.rs:41:5
+  --> $DIR/destructure_patterns.rs:39:5
    |
 LL | /     || {
 LL | |
@@ -106,18 +97,18 @@ LL | |     };
    | |_____^
    |
 note: Min Capture p[(0, 0)] -> MutBorrow
-  --> $DIR/destructure_patterns.rs:44:58
+  --> $DIR/destructure_patterns.rs:42:58
    |
 LL |         let Point { x: ref mut x, y: _, id: moved_id } = p;
    |                                                          ^
 note: Min Capture p[(2, 0)] -> ByValue
-  --> $DIR/destructure_patterns.rs:44:58
+  --> $DIR/destructure_patterns.rs:42:58
    |
 LL |         let Point { x: ref mut x, y: _, id: moved_id } = p;
    |                                                          ^
 
 error: First Pass analysis includes:
-  --> $DIR/destructure_patterns.rs:61:5
+  --> $DIR/destructure_patterns.rs:59:5
    |
 LL | /     || {
 LL | |
@@ -129,23 +120,23 @@ LL | |     };
    | |_____^
    |
 note: Capturing t[(0, 0)] -> MutBorrow
-  --> $DIR/destructure_patterns.rs:64:54
+  --> $DIR/destructure_patterns.rs:62:54
    |
 LL |         let (ref mut x, ref ref_str, (moved_s, _)) = t;
    |                                                      ^
 note: Capturing t[(1, 0)] -> ImmBorrow
-  --> $DIR/destructure_patterns.rs:64:54
+  --> $DIR/destructure_patterns.rs:62:54
    |
 LL |         let (ref mut x, ref ref_str, (moved_s, _)) = t;
    |                                                      ^
 note: Capturing t[(2, 0),(0, 0)] -> ByValue
-  --> $DIR/destructure_patterns.rs:64:54
+  --> $DIR/destructure_patterns.rs:62:54
    |
 LL |         let (ref mut x, ref ref_str, (moved_s, _)) = t;
    |                                                      ^
 
 error: Min Capture analysis includes:
-  --> $DIR/destructure_patterns.rs:61:5
+  --> $DIR/destructure_patterns.rs:59:5
    |
 LL | /     || {
 LL | |
@@ -157,21 +148,21 @@ LL | |     };
    | |_____^
    |
 note: Min Capture t[(0, 0)] -> MutBorrow
-  --> $DIR/destructure_patterns.rs:64:54
+  --> $DIR/destructure_patterns.rs:62:54
    |
 LL |         let (ref mut x, ref ref_str, (moved_s, _)) = t;
    |                                                      ^
 note: Min Capture t[(1, 0)] -> ImmBorrow
-  --> $DIR/destructure_patterns.rs:64:54
+  --> $DIR/destructure_patterns.rs:62:54
    |
 LL |         let (ref mut x, ref ref_str, (moved_s, _)) = t;
    |                                                      ^
 note: Min Capture t[(2, 0),(0, 0)] -> ByValue
-  --> $DIR/destructure_patterns.rs:64:54
+  --> $DIR/destructure_patterns.rs:62:54
    |
 LL |         let (ref mut x, ref ref_str, (moved_s, _)) = t;
    |                                                      ^
 
-error: aborting due to 9 previous errors; 1 warning emitted
+error: aborting due to 9 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
index 0b94317fd71..93131b2ac4e 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
@@ -1,7 +1,6 @@
-// Test that arrays are completely captured by closures by relying on the borrow check diagnostics
+// edition:2021
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+// Test that arrays are completely captured by closures by relying on the borrow check diagnostics
 
 fn arrays_1() {
     let mut arr = [1, 2, 3, 4, 5];
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
index 77e3e71bc61..a3f2f25e447 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/arrays.rs:3:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0503]: cannot use `arr` because it was mutably borrowed
-  --> $DIR/arrays.rs:15:5
+  --> $DIR/arrays.rs:14:5
    |
 LL |     let mut c = || {
    |                 -- borrow of `arr` occurs here
@@ -22,7 +13,7 @@ LL |     c();
    |     - borrow later used here
 
 error[E0503]: cannot use `arr[_]` because it was mutably borrowed
-  --> $DIR/arrays.rs:15:5
+  --> $DIR/arrays.rs:14:5
    |
 LL |     let mut c = || {
    |                 -- borrow of `arr` occurs here
@@ -36,7 +27,7 @@ LL |     c();
    |     - borrow later used here
 
 error[E0506]: cannot assign to `arr[_]` because it is borrowed
-  --> $DIR/arrays.rs:30:5
+  --> $DIR/arrays.rs:29:5
    |
 LL |     let c = || {
    |             -- borrow of `arr[_]` occurs here
@@ -50,7 +41,7 @@ LL |     c();
    |     - borrow later used here
 
 error[E0506]: cannot assign to `arr[_]` because it is borrowed
-  --> $DIR/arrays.rs:44:5
+  --> $DIR/arrays.rs:43:5
    |
 LL |     let c = || {
    |             -- borrow of `arr[_]` occurs here
@@ -64,7 +55,7 @@ LL |     c();
    |     - borrow later used here
 
 error[E0503]: cannot use `arr` because it was mutably borrowed
-  --> $DIR/arrays.rs:58:20
+  --> $DIR/arrays.rs:57:20
    |
 LL |     let mut c = || {
    |                 -- borrow of `arr` occurs here
@@ -78,7 +69,7 @@ LL |     c();
    |     - borrow later used here
 
 error[E0502]: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
-  --> $DIR/arrays.rs:58:20
+  --> $DIR/arrays.rs:57:20
    |
 LL |     let mut c = || {
    |                 -- mutable borrow occurs here
@@ -92,7 +83,7 @@ LL |     c();
    |     - mutable borrow later used here
 
 error[E0502]: cannot borrow `arr` as immutable because it is also borrowed as mutable
-  --> $DIR/arrays.rs:74:24
+  --> $DIR/arrays.rs:73:24
    |
 LL |     let mut c = || {
    |                 -- mutable borrow occurs here
@@ -105,7 +96,7 @@ LL |     println!("{:#?}", &arr[3..2]);
 LL |     c();
    |     - mutable borrow later used here
 
-error: aborting due to 7 previous errors; 1 warning emitted
+error: aborting due to 7 previous errors
 
 Some errors have detailed explanations: E0502, E0503, E0506.
 For more information about an error, try `rustc --explain E0502`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.rs
index 2f3358dcd8d..3664d76c203 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.rs
@@ -1,5 +1,4 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+// edition:2021
 
 #[derive(Debug)]
 struct Point {
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.stderr
index e15067b264d..341d2bc6563 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/borrowck-1.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0499]: cannot borrow `p` as mutable more than once at a time
-  --> $DIR/borrowck-1.rs:13:17
+  --> $DIR/borrowck-1.rs:12:17
    |
 LL |     let y = &mut p.y;
    |             -------- first mutable borrow occurs here
@@ -23,6 +14,6 @@ LL |        println!("{:?}", p);
 LL |     *y+=1;
    |     ----- first borrow later used here
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0499`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.rs
index 06c6a87eb10..ae416bab65e 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.rs
@@ -1,5 +1,4 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+// edition:2021
 
 #[derive(Debug)]
 struct Point {
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.stderr
index a195b981eaa..584bb862b2c 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/borrowck-2.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-2.rs:13:17
+  --> $DIR/borrowck-2.rs:12:17
    |
 LL |     let y = &p.y;
    |             ---- immutable borrow occurs here
@@ -23,6 +14,6 @@ LL |        let x = &mut p.x;
 LL |     println!("{}", y);
    |                    - immutable borrow later used here
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0502`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs
index ba998f78c87..bdd6cb79b60 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs
@@ -1,5 +1,4 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+// edition:2021
 
 #[derive(Debug)]
 struct Point {
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr
index b54c729a307..dab1809a381 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/borrowck-3.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0597]: `p` does not live long enough
-  --> $DIR/borrowck-3.rs:14:29
+  --> $DIR/borrowck-3.rs:13:29
    |
 LL |     let mut c = {
    |         ----- borrow later stored here
@@ -22,6 +13,6 @@ LL |            println!("{:?}", p);
 LL |     };
    |     - `p` dropped here while still borrowed
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs
index 4fab0189c27..a2290d85020 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs
@@ -1,5 +1,4 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+// edition:2021
 
 #[derive(Debug)]
 struct Point {
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr
index 905fa3475ed..29bd4b27d6b 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/borrowck-4.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0373]: closure may outlive the current function, but it borrows `p`, which is owned by the current function
-  --> $DIR/borrowck-4.rs:11:17
+  --> $DIR/borrowck-4.rs:10:17
    |
 LL |     let mut c = || {
    |                 ^^ may outlive borrowed value `p`
@@ -17,7 +8,7 @@ LL |        println!("{:?}", p);
    |                         - `p` is borrowed here
    |
 note: closure is returned here
-  --> $DIR/borrowck-4.rs:9:14
+  --> $DIR/borrowck-4.rs:8:14
    |
 LL | fn foo () -> impl FnMut()->() {
    |              ^^^^^^^^^^^^^^^^
@@ -26,6 +17,6 @@ help: to force the closure to take ownership of `p` (and any other referenced va
 LL |     let mut c = move || {
    |                 ^^^^^^^
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0373`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs
index b23947ad5d1..6a8c9664051 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs
@@ -1,8 +1,8 @@
+// edition:2021
+
 // Tests that two closures cannot simultaneously have mutable
 // and immutable access to the variable. Issue #6801.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
 #![feature(box_syntax)]
 
 #[derive(Debug)]
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr
index 58975c6f46f..5f1dae2972f 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr
@@ -1,12 +1,3 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/borrowck-closures-mut-and-imm.rs:4:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable
   --> $DIR/borrowck-closures-mut-and-imm.rs:17:14
    |
@@ -25,6 +16,6 @@ LL |     };
 LL |     drop(c2);
    |          -- immutable borrow later used here
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0502`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/box.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.rs
index 15be1d8c722..a110fa4e2cb 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/box.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.rs
@@ -1,7 +1,6 @@
-// Test borrow checker when we precise capture when using boxes
+// edition:2021
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+// Test borrow checker when we precise capture when using boxes
 
 struct MetaData { x: String, name: String }
 struct Data { m: MetaData }
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr
index 174faa33c49..2badf051418 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/box.rs:3:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed
-  --> $DIR/box.rs:22:5
+  --> $DIR/box.rs:21:5
    |
 LL |     let mut c = || {
    |                 -- borrow of `e.0.0.m.x` occurs here
@@ -22,7 +13,7 @@ LL |     c();
    |     - borrow later used here
 
 error[E0502]: cannot borrow `e.0.0.m.x` as immutable because it is also borrowed as mutable
-  --> $DIR/box.rs:39:20
+  --> $DIR/box.rs:38:20
    |
 LL |     let mut c = || {
    |                 -- mutable borrow occurs here
@@ -36,7 +27,7 @@ LL |     c();
    |     - mutable borrow later used here
 
 error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed
-  --> $DIR/box.rs:56:5
+  --> $DIR/box.rs:55:5
    |
 LL |     let c = || {
    |             -- borrow of `e.0.0.m.x` occurs here
@@ -49,7 +40,7 @@ LL |
 LL |     c();
    |     - borrow later used here
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0502, E0506.
 For more information about an error, try `rustc --explain E0502`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.rs
index 1ea38e260b6..a5b4a19d8c3 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.rs
@@ -1,9 +1,8 @@
+// edition:2021
+
 // Test that if we deref an immutable borrow to access a Place,
 // then we can't mutate the final place.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-
 fn main() {
     let mut x = (format!(""), format!("X2"));
     let mut y = (&x, "Y");
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.stderr
index 39a11fb3327..cfe531e17d3 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/cant-mutate-imm-borrow.rs:4:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0596]: cannot borrow `z.0.0.0` as mutable, as it is behind a `&` reference
-  --> $DIR/cant-mutate-imm-borrow.rs:14:17
+  --> $DIR/cant-mutate-imm-borrow.rs:13:17
    |
 LL |     let mut c = || {
    |                 ^^ cannot borrow as mutable
@@ -16,6 +7,6 @@ LL |
 LL |         z.0.0.0 = format!("X1");
    |         ------- mutable borrow occurs due to use of `z.0.0.0` in closure
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.rs
index 928c866726f..25ee9a1490e 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.rs
@@ -1,5 +1,4 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+// edition:2021
 
 // Ensure that diagnostics for mutability error (because the root variable
 // isn't mutable) work with `capture_disjoint_fields` enabled.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr
index 9fb8dd4a1c3..98414fa8a3d 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/cant-mutate-imm.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0594]: cannot assign to `z.0.0.0`, as it is not declared as mutable
-  --> $DIR/cant-mutate-imm.rs:13:9
+  --> $DIR/cant-mutate-imm.rs:12:9
    |
 LL |     let z = (y, 10);
    |         - help: consider changing this to be mutable: `mut z`
@@ -17,7 +8,7 @@ LL |         z.0.0.0 = 20;
    |         ^^^^^^^^^^^^ cannot assign
 
 error[E0594]: cannot assign to `*bx.0`, as it is not declared as mutable
-  --> $DIR/cant-mutate-imm.rs:25:9
+  --> $DIR/cant-mutate-imm.rs:24:9
    |
 LL |     let bx = Box::new(x);
    |         -- help: consider changing this to be mutable: `mut bx`
@@ -25,6 +16,6 @@ LL |     let bx = Box::new(x);
 LL |         bx.0 = 20;
    |         ^^^^^^^^^ cannot assign
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0594`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.rs
index cd7c25620a7..f3be542e40d 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.rs
@@ -1,7 +1,4 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| `#[warn(incomplete_features)]` on by default
-//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
 
 // Test that array access is not stored as part of closure kind origin
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr
index bd9428771f4..bcde35983fc 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/closure-origin-array-diagnostics.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
-  --> $DIR/closure-origin-array-diagnostics.rs:12:13
+  --> $DIR/closure-origin-array-diagnostics.rs:9:13
    |
 LL |     let c = || {
    |             ^^ this closure implements `FnOnce`, not `Fn`
@@ -18,6 +9,6 @@ LL |     };
 LL |     expect_fn(c);
    |     --------- the requirement to implement `Fn` derives from here
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0525`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.rs
index 2916d8c794f..aa85b55b15c 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.rs
@@ -1,11 +1,7 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| `#[warn(incomplete_features)]` on by default
-//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
 
 // Check that precise paths are being reported back in the error message.
 
-
 enum MultiVariant {
     Point(i32, i32),
     Meta(i32)
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr
index de0bfe3bd76..066c000c832 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/closure-origin-multi-variant-diagnostics.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0382]: use of moved value: `c`
-  --> $DIR/closure-origin-multi-variant-diagnostics.rs:30:13
+  --> $DIR/closure-origin-multi-variant-diagnostics.rs:26:13
    |
 LL |     let a = c;
    |             - value moved here
@@ -16,11 +7,11 @@ LL |     let b = c;
    |             ^ value used here after move
    |
 note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `point.0` out of its environment
-  --> $DIR/closure-origin-multi-variant-diagnostics.rs:20:52
+  --> $DIR/closure-origin-multi-variant-diagnostics.rs:16:52
    |
 LL |         if let MultiVariant::Point(ref mut x, _) = point {
    |                                                    ^^^^^
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.rs
index 2ed0149b9db..bedb103cc4c 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.rs
@@ -1,9 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| `#[warn(incomplete_features)]` on by default
-//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
 
-// Check that precise paths are being reported back in the error message.
 
 enum SingleVariant {
     Point(i32, i32),
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr
index 402f5e4f33e..2a6e00850fa 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/closure-origin-single-variant-diagnostics.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0382]: use of moved value: `c`
-  --> $DIR/closure-origin-single-variant-diagnostics.rs:21:13
+  --> $DIR/closure-origin-single-variant-diagnostics.rs:17:13
    |
 LL |     let b = c;
    |             - value moved here
@@ -16,11 +7,11 @@ LL |     let a = c;
    |             ^ value used here after move
    |
 note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `point.0` out of its environment
-  --> $DIR/closure-origin-single-variant-diagnostics.rs:16:50
+  --> $DIR/closure-origin-single-variant-diagnostics.rs:12:50
    |
 LL |         let SingleVariant::Point(ref mut x, _) = point;
    |                                                  ^^^^^
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.rs
index 103890f1f35..3277a83c4e1 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.rs
@@ -1,7 +1,4 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| `#[warn(incomplete_features)]` on by default
-//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
 
 // Check that precise paths are being reported back in the error message.
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr
index 474d77b7cd2..d7fc51c55ea 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/closure-origin-struct-diagnostics.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0382]: use of moved value: `hello`
-  --> $DIR/closure-origin-struct-diagnostics.rs:24:13
+  --> $DIR/closure-origin-struct-diagnostics.rs:21:13
    |
 LL |     let b = hello;
    |             ----- value moved here
@@ -16,11 +7,11 @@ LL |     let c = hello;
    |             ^^^^^ value used here after move
    |
 note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `x.y.a` out of its environment
-  --> $DIR/closure-origin-struct-diagnostics.rs:20:9
+  --> $DIR/closure-origin-struct-diagnostics.rs:17:9
    |
 LL |         x.y.a += 1;
    |         ^^^^^
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.rs
index 6b078d2329c..dc3a57ae793 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.rs
@@ -1,7 +1,4 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| `#[warn(incomplete_features)]` on by default
-//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
 
 // Check that precise paths are being reported back in the error message.
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr
index 716728e96ec..63e2d300eb0 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/closure-origin-tuple-diagnostics-1.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0382]: use of moved value: `hello`
-  --> $DIR/closure-origin-tuple-diagnostics-1.rs:15:13
+  --> $DIR/closure-origin-tuple-diagnostics-1.rs:12:13
    |
 LL |     let b = hello;
    |             ----- value moved here
@@ -16,11 +7,11 @@ LL |     let c = hello;
    |             ^^^^^ value used here after move
    |
 note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `x.0` out of its environment
-  --> $DIR/closure-origin-tuple-diagnostics-1.rs:11:9
+  --> $DIR/closure-origin-tuple-diagnostics-1.rs:8:9
    |
 LL |         x.0 += 1;
    |         ^^^
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.rs
index 0638db60769..fa1328013db 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| `#[warn(incomplete_features)]` on by default
-//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 struct S(String, String);
 
 fn expect_fn<F: Fn()>(_f: F) {}
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr
index 77eb2a94ffb..df33c4f1fd6 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/closure-origin-tuple-diagnostics.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
-  --> $DIR/closure-origin-tuple-diagnostics.rs:11:13
+  --> $DIR/closure-origin-tuple-diagnostics.rs:9:13
    |
 LL |     let c = || {
    |             ^^ this closure implements `FnOnce`, not `Fn`
@@ -18,6 +9,6 @@ LL |     };
 LL |     expect_fn(c);
    |     --------- the requirement to implement `Fn` derives from here
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0525`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs
index 09491f296f6..1cc22fac352 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.rs
@@ -1,6 +1,6 @@
+// edition:2021
+
 // check-pass
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
 #![allow(unreachable_code)]
 #![warn(unused)]
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr
index 81bbc4e1dc0..4eac5a2d282 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr
@@ -1,12 +1,3 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/liveness.rs:2:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 warning: value captured by `a` is never read
   --> $DIR/liveness.rs:23:9
    |
@@ -75,5 +66,5 @@ LL |             b = Some("e1");
    |
    = help: did you mean to capture by reference instead?
 
-warning: 8 warnings emitted
+warning: 7 warnings emitted
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs
index e2035464dfa..10a7d07a1df 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs
@@ -1,6 +1,6 @@
+// edition:2021
+
 // check-pass
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
 #![warn(unused)]
 
 #[derive(Debug)]
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr
index 35b0c22fc4f..f74303e3dd6 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr
@@ -1,12 +1,3 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/liveness_unintentional_copy.rs:2:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 warning: value assigned to `a` is never read
   --> $DIR/liveness_unintentional_copy.rs:19:9
    |
@@ -43,5 +34,5 @@ LL |         a += x;
    |
    = help: did you mean to capture by reference instead?
 
-warning: 4 warnings emitted
+warning: 3 warnings emitted
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.rs
index 39b04c833e3..fa73ff23f9c 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.rs
@@ -1,8 +1,8 @@
+// edition:2021
+
 // Test that when a borrow checker diagnostics are emitted, it's as precise
 // as the capture by the closure.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
 #![allow(unused)]
 
 struct Point {
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr
index a3d1f550557..ac4c9c93769 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr
@@ -1,12 +1,3 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/multilevel-path.rs:4:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0499]: cannot borrow `w.p.x` as mutable more than once at a time
   --> $DIR/multilevel-path.rs:23:14
    |
@@ -21,6 +12,6 @@ LL |
 LL |     c();
    |     - first borrow later used here
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0499`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.rs
index 676fde558df..3d5a31e8b8e 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.rs
@@ -1,9 +1,8 @@
+// edition:2021
+
 // Test that we can't mutate a place if we need to deref an imm-borrow
 // to reach it.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-
 fn imm_mut_ref() {
     let mut x = String::new();
     let y = String::new();
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr
index 831e486db82..dbf8523a3ba 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/mut_ref.rs:4:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0596]: cannot borrow `**ref_mref_x` as mutable, as it is behind a `&` reference
-  --> $DIR/mut_ref.rs:13:13
+  --> $DIR/mut_ref.rs:12:13
    |
 LL |     let ref_mref_x = &mref_x;
    |                      ------- help: consider changing this to be a mutable reference: `&mut mref_x`
@@ -20,7 +11,7 @@ LL |         **ref_mref_x = y;
    |         ------------ mutable borrow occurs due to use of `**ref_mref_x` in closure
 
 error[E0596]: cannot borrow `**mref_ref_x` as mutable, as it is behind a `&` reference
-  --> $DIR/mut_ref.rs:27:13
+  --> $DIR/mut_ref.rs:26:13
    |
 LL |     let c = || {
    |             ^^ cannot borrow as mutable
@@ -28,6 +19,6 @@ LL |
 LL |         **mref_ref_x = y;
    |         ------------ mutable borrow occurs due to use of `**mref_ref_x` in closure
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs
index 82ec60a2e79..4799f488d7d 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs
@@ -1,7 +1,6 @@
-// check-pass
+// edition:2021
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+// check-pass
 
 // Given how the closure desugaring is implemented (at least at the time of writing this test),
 // we don't need to truncate the captured path to a reference into a packed-struct if the field
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr
index e8cc164be87..d2466681a08 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/repr_packed.rs:3:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 warning: reference to packed field is unaligned
-  --> $DIR/repr_packed.rs:25:24
+  --> $DIR/repr_packed.rs:24:24
    |
 LL |         println!("{}", foo.x);
    |                        ^^^^^
@@ -18,5 +9,5 @@ LL |         println!("{}", foo.x);
    = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
 
-warning: 2 warnings emitted
+warning: 1 warning emitted
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.rs
index e78d8715e48..ed2d9a3de00 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.rs
@@ -1,9 +1,8 @@
+// edition:2021
+
 // Test that borrow checker error is accurate and that min capture pass of the
 // closure analysis is working as expected.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-
 #[derive(Debug)]
 struct Point {
     x: i32,
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr
index f1748fda151..32705af3d01 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/simple-struct-min-capture.rs:4:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0502]: cannot borrow `p` as immutable because it is also borrowed as mutable
-  --> $DIR/simple-struct-min-capture.rs:23:22
+  --> $DIR/simple-struct-min-capture.rs:22:22
    |
 LL |     let mut c = || {
    |                 -- mutable borrow occurs here
@@ -23,6 +14,6 @@ LL |
 LL |     c();
    |     - mutable borrow later used here
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0502`.
diff --git a/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.rs b/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.rs
index a3222635b62..269cf76e673 100644
--- a/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.rs
+++ b/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(rustc_attrs)]
 
 fn main() {
diff --git a/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr b/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr
index a031360ed34..b936c5ee35a 100644
--- a/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/feature-gate-capture_disjoint_fields.rs:10:13
+  --> $DIR/feature-gate-capture_disjoint_fields.rs:8:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/feature-gate-capture_disjoint_fields.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/feature-gate-capture_disjoint_fields.rs:13:5
+  --> $DIR/feature-gate-capture_disjoint_fields.rs:11:5
    |
 LL | /     || {
 LL | |
@@ -29,13 +20,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing s[] -> ImmBorrow
-  --> $DIR/feature-gate-capture_disjoint_fields.rs:16:69
+  --> $DIR/feature-gate-capture_disjoint_fields.rs:14:69
    |
 LL |         println!("This uses new capture analyysis to capture s={}", s);
    |                                                                     ^
 
 error: Min Capture analysis includes:
-  --> $DIR/feature-gate-capture_disjoint_fields.rs:13:5
+  --> $DIR/feature-gate-capture_disjoint_fields.rs:11:5
    |
 LL | /     || {
 LL | |
@@ -47,11 +38,11 @@ LL | |     };
    | |_____^
    |
 note: Min Capture s[] -> ImmBorrow
-  --> $DIR/feature-gate-capture_disjoint_fields.rs:16:69
+  --> $DIR/feature-gate-capture_disjoint_fields.rs:14:69
    |
 LL |         println!("This uses new capture analyysis to capture s={}", s);
    |                                                                     ^
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/filter-on-struct-member.rs b/src/test/ui/closures/2229_closure_analysis/filter-on-struct-member.rs
index 9466e103897..bfa3ebcd6d2 100644
--- a/src/test/ui/closures/2229_closure_analysis/filter-on-struct-member.rs
+++ b/src/test/ui/closures/2229_closure_analysis/filter-on-struct-member.rs
@@ -1,9 +1,5 @@
-// FIXME(arora-aman) add run-pass once 2229 is implemented
+// edition:2021
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![feature(rustc_attrs)]
 
 struct Filter {
diff --git a/src/test/ui/closures/2229_closure_analysis/filter-on-struct-member.stderr b/src/test/ui/closures/2229_closure_analysis/filter-on-struct-member.stderr
index e9420fe5a0c..10e0d076b42 100644
--- a/src/test/ui/closures/2229_closure_analysis/filter-on-struct-member.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/filter-on-struct-member.stderr
@@ -1,35 +1,26 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/filter-on-struct-member.rs:3:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/filter-on-struct-member.rs:28:13
+  --> $DIR/filter-on-struct-member.rs:24:13
    |
 LL |             |v| self.filter.allowed(*v),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: Capturing self[Deref,(0, 0)] -> ImmBorrow
-  --> $DIR/filter-on-struct-member.rs:28:17
+  --> $DIR/filter-on-struct-member.rs:24:17
    |
 LL |             |v| self.filter.allowed(*v),
    |                 ^^^^^^^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/filter-on-struct-member.rs:28:13
+  --> $DIR/filter-on-struct-member.rs:24:13
    |
 LL |             |v| self.filter.allowed(*v),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: Min Capture self[Deref,(0, 0)] -> ImmBorrow
-  --> $DIR/filter-on-struct-member.rs:28:17
+  --> $DIR/filter-on-struct-member.rs:24:17
    |
 LL |             |v| self.filter.allowed(*v),
    |                 ^^^^^^^^^^^
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed
index 93e6cf03405..ee8dd4b4fc3 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed
@@ -11,7 +11,7 @@ fn test_send_trait() {
     let mut f = 10;
     let fptr = SendPointer(&mut f as *mut i32);
     thread::spawn(move || { let _ = &fptr; unsafe {
-        //~^ ERROR: `Send` trait implementation affected for closure because of `capture_disjoint_fields`
+        //~^ ERROR: `Send` trait implementation
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0 = 20;
     } });
@@ -28,7 +28,7 @@ fn test_sync_trait() {
     let f = CustomInt(&mut f as *mut i32);
     let fptr = SyncPointer(f);
     thread::spawn(move || { let _ = &fptr; unsafe {
-        //~^ ERROR: `Sync`, `Send` trait implementation affected for closure because of `capture_disjoint_fields`
+        //~^ ERROR: `Sync`, `Send` trait implementation
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0.0 = 20;
     } });
@@ -49,7 +49,7 @@ impl Clone for U {
 fn test_clone_trait() {
     let f = U(S(String::from("Hello World")), T(0));
     let c = || { let _ = &f; 
-        //~^ ERROR: `Clone` trait implementation, and drop order affected for closure because of `capture_disjoint_fields`
+        //~^ ERROR: `Clone` trait implementation, and drop order
         //~| HELP: add a dummy let to cause `f` to be fully captured
         let f_1 = f.1;
         println!("{:?}", f_1.0);
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs
index 2c0dbd01754..7a6dcc55bbb 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.rs
@@ -11,7 +11,7 @@ fn test_send_trait() {
     let mut f = 10;
     let fptr = SendPointer(&mut f as *mut i32);
     thread::spawn(move || unsafe {
-        //~^ ERROR: `Send` trait implementation affected for closure because of `capture_disjoint_fields`
+        //~^ ERROR: `Send` trait implementation
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0 = 20;
     });
@@ -28,7 +28,7 @@ fn test_sync_trait() {
     let f = CustomInt(&mut f as *mut i32);
     let fptr = SyncPointer(f);
     thread::spawn(move || unsafe {
-        //~^ ERROR: `Sync`, `Send` trait implementation affected for closure because of `capture_disjoint_fields`
+        //~^ ERROR: `Sync`, `Send` trait implementation
         //~| HELP: add a dummy let to cause `fptr` to be fully captured
         *fptr.0.0 = 20;
     });
@@ -49,7 +49,7 @@ impl Clone for U {
 fn test_clone_trait() {
     let f = U(S(String::from("Hello World")), T(0));
     let c = || {
-        //~^ ERROR: `Clone` trait implementation, and drop order affected for closure because of `capture_disjoint_fields`
+        //~^ ERROR: `Clone` trait implementation, and drop order
         //~| HELP: add a dummy let to cause `f` to be fully captured
         let f_1 = f.1;
         println!("{:?}", f_1.0);
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
index 6e3723b8bdb..d8420f9652e 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
@@ -1,4 +1,4 @@
-error: `Send` trait implementation affected for closure because of `capture_disjoint_fields`
+error: `Send` trait implementation will change in Rust 2021
   --> $DIR/auto_traits.rs:13:19
    |
 LL |       thread::spawn(move || unsafe {
@@ -14,6 +14,7 @@ note: the lint level is defined here
    |
 LL | #![deny(disjoint_capture_migration)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `fptr` to be fully captured
    |
 LL |     thread::spawn(move || { let _ = &fptr; unsafe {
@@ -23,7 +24,7 @@ LL |         *fptr.0 = 20;
 LL |     } });
    |
 
-error: `Sync`, `Send` trait implementation affected for closure because of `capture_disjoint_fields`
+error: `Sync`, `Send` trait implementation will change in Rust 2021
   --> $DIR/auto_traits.rs:30:19
    |
 LL |       thread::spawn(move || unsafe {
@@ -34,6 +35,7 @@ LL | |         *fptr.0.0 = 20;
 LL | |     });
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `fptr` to be fully captured
    |
 LL |     thread::spawn(move || { let _ = &fptr; unsafe {
@@ -43,7 +45,7 @@ LL |         *fptr.0.0 = 20;
 LL |     } });
    |
 
-error: `Clone` trait implementation, and drop order affected for closure because of `capture_disjoint_fields`
+error: `Clone` trait implementation, and drop order will change in Rust 2021
   --> $DIR/auto_traits.rs:51:13
    |
 LL |       let c = || {
@@ -55,6 +57,7 @@ LL | |         println!("{:?}", f_1.0);
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `f` to be fully captured
    |
 LL |     let c = || { let _ = &f; 
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed
index 3770e93239a..4bc9b19642f 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.fixed
@@ -13,7 +13,8 @@ fn test1_all_need_migration() {
     let t2 = (String::new(), String::new());
 
     let c = || { let _ = (&t, &t1, &t2); 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
 
         let _t = t.0;
@@ -32,7 +33,8 @@ fn test2_only_precise_paths_need_migration() {
     let t2 = (String::new(), String::new());
 
     let c = || { let _ = (&t, &t1); 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
         let _t = t.0;
         let _t1 = t1.0;
@@ -48,7 +50,8 @@ fn test3_only_by_value_need_migration() {
     let t = (String::new(), String::new());
     let t1 = (String::new(), String::new());
     let c = || { let _ = &t; 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
         println!("{}", t1.1);
@@ -66,7 +69,8 @@ fn test4_only_non_copy_types_need_migration() {
     let t1 = (0i32, 0i32);
 
     let c = || { let _ = &t; 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
         let _t1 = t1.0;
@@ -84,7 +88,8 @@ fn test5_only_drop_types_need_migration() {
     let s = S(0i32, 0i32);
 
     let c = || { let _ = &t; 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
         let _s = s.0;
@@ -99,7 +104,8 @@ fn test6_move_closures_non_copy_types_might_need_migration() {
     let t = (String::new(), String::new());
     let t1 = (String::new(), String::new());
     let c = move || { let _ = (&t1, &t); 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
         println!("{} {}", t1.1, t.1);
     };
@@ -114,7 +120,8 @@ fn test7_drop_non_drop_aggregate_need_migration() {
     let t = (String::new(), String::new(), 0i32);
 
     let c = || { let _ = &t; 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
     };
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs
index 2015ab7e9b8..446ce43a469 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.rs
@@ -13,7 +13,8 @@ fn test1_all_need_migration() {
     let t2 = (String::new(), String::new());
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
 
         let _t = t.0;
@@ -32,7 +33,8 @@ fn test2_only_precise_paths_need_migration() {
     let t2 = (String::new(), String::new());
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
         let _t = t.0;
         let _t1 = t1.0;
@@ -48,7 +50,8 @@ fn test3_only_by_value_need_migration() {
     let t = (String::new(), String::new());
     let t1 = (String::new(), String::new());
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
         println!("{}", t1.1);
@@ -66,7 +69,8 @@ fn test4_only_non_copy_types_need_migration() {
     let t1 = (0i32, 0i32);
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
         let _t1 = t1.0;
@@ -84,7 +88,8 @@ fn test5_only_drop_types_need_migration() {
     let s = S(0i32, 0i32);
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
         let _s = s.0;
@@ -99,7 +104,8 @@ fn test6_move_closures_non_copy_types_might_need_migration() {
     let t = (String::new(), String::new());
     let t1 = (String::new(), String::new());
     let c = move || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
         println!("{} {}", t1.1, t.1);
     };
@@ -114,7 +120,8 @@ fn test7_drop_non_drop_aggregate_need_migration() {
     let t = (String::new(), String::new(), 0i32);
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
     };
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr
index 69a99f7a53a..0dfbcddc279 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop.stderr
@@ -1,4 +1,4 @@
-error: drop order affected for closure because of `capture_disjoint_fields`
+error: drop order will change in Rust 2021
   --> $DIR/insignificant_drop.rs:15:13
    |
 LL |       let c = || {
@@ -16,141 +16,155 @@ note: the lint level is defined here
    |
 LL | #![deny(disjoint_capture_migration)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
    |
 LL |     let c = || { let _ = (&t, &t1, &t2); 
 LL |
 LL |
+LL |
 LL | 
 LL |         let _t = t.0;
-LL |         let _t1 = t1.0;
  ...
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/insignificant_drop.rs:34:13
+error: drop order will change in Rust 2021
+  --> $DIR/insignificant_drop.rs:35:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
-LL | |         let _t = t.0;
-LL | |         let _t1 = t1.0;
+LL | |
+...  |
 LL | |         let _t2 = t2;
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t`, `t1` to be fully captured
    |
 LL |     let c = || { let _ = (&t, &t1); 
 LL |
 LL |
+LL |
 LL |         let _t = t.0;
 LL |         let _t1 = t1.0;
-LL |         let _t2 = t2;
  ...
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/insignificant_drop.rs:50:13
+error: drop order will change in Rust 2021
+  --> $DIR/insignificant_drop.rs:52:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         let _t = t.0;
 LL | |         println!("{}", t1.1);
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = || { let _ = &t; 
 LL |
 LL |
+LL |
 LL |         let _t = t.0;
 LL |         println!("{}", t1.1);
-LL |     };
-   |
+ ...
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/insignificant_drop.rs:68:13
+error: drop order will change in Rust 2021
+  --> $DIR/insignificant_drop.rs:71:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         let _t = t.0;
 LL | |         let _t1 = t1.0;
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = || { let _ = &t; 
 LL |
 LL |
+LL |
 LL |         let _t = t.0;
 LL |         let _t1 = t1.0;
-LL |     };
-   |
+ ...
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/insignificant_drop.rs:86:13
+error: drop order will change in Rust 2021
+  --> $DIR/insignificant_drop.rs:90:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         let _t = t.0;
 LL | |         let _s = s.0;
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = || { let _ = &t; 
 LL |
 LL |
+LL |
 LL |         let _t = t.0;
 LL |         let _s = s.0;
-LL |     };
-   |
+ ...
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/insignificant_drop.rs:101:13
+error: drop order will change in Rust 2021
+  --> $DIR/insignificant_drop.rs:106:13
    |
 LL |       let c = move || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         println!("{} {}", t1.1, t.1);
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t1`, `t` to be fully captured
    |
 LL |     let c = move || { let _ = (&t1, &t); 
 LL |
 LL |
+LL |
 LL |         println!("{} {}", t1.1, t.1);
 LL |     };
    |
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/insignificant_drop.rs:116:13
+error: drop order will change in Rust 2021
+  --> $DIR/insignificant_drop.rs:122:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         let _t = t.0;
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = || { let _ = &t; 
 LL |
 LL |
+LL |
 LL |         let _t = t.0;
 LL |     };
    |
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed
index e89cc2c8fb3..5a781219a72 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.fixed
@@ -36,7 +36,8 @@ fn significant_drop_needs_migration() {
     let t = (SigDrop {}, SigDrop {});
 
     let c = || { let _ = &t; 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
     };
@@ -53,7 +54,8 @@ fn generic_struct_with_significant_drop_needs_migration() {
 
     // move is used to force i32 to be copied instead of being a ref
     let c = move || { let _ = &t; 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.1;
     };
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs
index e16cd9d52b7..d57da326556 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.rs
@@ -36,7 +36,8 @@ fn significant_drop_needs_migration() {
     let t = (SigDrop {}, SigDrop {});
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
     };
@@ -53,7 +54,8 @@ fn generic_struct_with_significant_drop_needs_migration() {
 
     // move is used to force i32 to be copied instead of being a ref
     let c = move || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.1;
     };
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr
index 2b141656be2..d25f8f635be 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr
@@ -1,10 +1,11 @@
-error: drop order affected for closure because of `capture_disjoint_fields`
+error: drop order will change in Rust 2021
   --> $DIR/insignificant_drop_attr_migrations.rs:38:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         let _t = t.0;
 LL | |     };
    | |_____^
@@ -14,31 +15,36 @@ note: the lint level is defined here
    |
 LL | #![deny(disjoint_capture_migration)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = || { let _ = &t; 
 LL |
 LL |
+LL |
 LL |         let _t = t.0;
 LL |     };
    |
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/insignificant_drop_attr_migrations.rs:55:13
+error: drop order will change in Rust 2021
+  --> $DIR/insignificant_drop_attr_migrations.rs:56:13
    |
 LL |       let c = move || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         let _t = t.1;
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = move || { let _ = &t; 
 LL |
 LL |
+LL |
 LL |         let _t = t.1;
 LL |     };
    |
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/issue-86753.rs b/src/test/ui/closures/2229_closure_analysis/migrations/issue-86753.rs
new file mode 100644
index 00000000000..fce9cac627b
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/issue-86753.rs
@@ -0,0 +1,34 @@
+// edition:2018
+// check-pass
+
+#![warn(rust_2021_compatibility)]
+
+use std::future::Future;
+
+struct Runtime;
+
+impl Runtime {
+    pub fn block_on<F: Future>(&self, _future: F) -> F::Output {
+        unimplemented!()
+    }
+}
+
+pub fn http<F, Fut>(_func: F)
+where
+    F: Fn() -> Fut,
+    Fut: Future<Output = ()>,
+{
+    let rt = Runtime {};
+    let srv = rt.block_on(async move { serve(move || async move { unimplemented!() }) });
+    let _ = || rt.block_on(async { srv });
+}
+
+pub struct Server<S> {
+    _marker: std::marker::PhantomData<S>,
+}
+
+pub fn serve<S>(_new_service: S) -> Server<S> {
+    unimplemented!()
+}
+
+fn main() { }
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed
index 979c023fc53..42b6ce54d3c 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.fixed
@@ -17,7 +17,8 @@ impl Drop for Foo {
 fn closure_contains_block() {
     let t = (Foo(0), Foo(0));
     let c = || { let _ = &t; 
-        //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+        //~^ ERROR: drop order
+        //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
     };
@@ -28,7 +29,8 @@ fn closure_contains_block() {
 fn closure_doesnt_contain_block() {
     let t = (Foo(0), Foo(0));
     let c = || { let _ = &t; t.0 };
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
 
     c();
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs
index c2a700bd9ca..ab0ed460fba 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.rs
@@ -17,7 +17,8 @@ impl Drop for Foo {
 fn closure_contains_block() {
     let t = (Foo(0), Foo(0));
     let c = || {
-        //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+        //~^ ERROR: drop order
+        //~| NOTE: for more information, see
         //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
     };
@@ -28,7 +29,8 @@ fn closure_contains_block() {
 fn closure_doesnt_contain_block() {
     let t = (Foo(0), Foo(0));
     let c = || t.0;
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
 
     c();
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr
index a968d3a093b..7b654f480a3 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr
@@ -1,10 +1,11 @@
-error: drop order affected for closure because of `capture_disjoint_fields`
+error: drop order will change in Rust 2021
   --> $DIR/migrations_rustfix.rs:19:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         let _t = t.0;
 LL | |     };
    | |_____^
@@ -14,21 +15,24 @@ note: the lint level is defined here
    |
 LL | #![deny(disjoint_capture_migration)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = || { let _ = &t; 
 LL |
 LL |
+LL |
 LL |         let _t = t.0;
 LL |     };
    |
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/migrations_rustfix.rs:30:13
+error: drop order will change in Rust 2021
+  --> $DIR/migrations_rustfix.rs:31:13
    |
 LL |     let c = || t.0;
    |             ^^^^^^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = || { let _ = &t; t.0 };
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed
index 95463a62185..abff6802e95 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.fixed
@@ -13,7 +13,7 @@ fn foo_diverges() -> ! { panic!() }
 fn assert_panics<F>(f: F) where F: FnOnce() {
     let f = panic::AssertUnwindSafe(f);
     let result = panic::catch_unwind(move || { let _ = &f; 
-        //~^ ERROR: `UnwindSafe`, `RefUnwindSafe` trait implementation affected for closure because of `capture_disjoint_fields`
+        //~^ ERROR: `UnwindSafe`, `RefUnwindSafe` trait implementation
         //~| HELP: add a dummy let to cause `f` to be fully captured
         f.0()
     });
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs
index fae7fc87c02..baa17e85b52 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.rs
@@ -13,7 +13,7 @@ fn foo_diverges() -> ! { panic!() }
 fn assert_panics<F>(f: F) where F: FnOnce() {
     let f = panic::AssertUnwindSafe(f);
     let result = panic::catch_unwind(move || {
-        //~^ ERROR: `UnwindSafe`, `RefUnwindSafe` trait implementation affected for closure because of `capture_disjoint_fields`
+        //~^ ERROR: `UnwindSafe`, `RefUnwindSafe` trait implementation
         //~| HELP: add a dummy let to cause `f` to be fully captured
         f.0()
     });
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
index bbc8eb9a9cd..8dca06a836c 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
@@ -1,4 +1,4 @@
-error: `UnwindSafe`, `RefUnwindSafe` trait implementation affected for closure because of `capture_disjoint_fields`
+error: `UnwindSafe`, `RefUnwindSafe` trait implementation will change in Rust 2021
   --> $DIR/mir_calls_to_shims.rs:15:38
    |
 LL |       let result = panic::catch_unwind(move || {
@@ -14,6 +14,7 @@ note: the lint level is defined here
    |
 LL | #![deny(disjoint_capture_migration)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `f` to be fully captured
    |
 LL |     let result = panic::catch_unwind(move || { let _ = &f; 
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed
index 5c93fce9250..90ea1ed2883 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.fixed
@@ -17,7 +17,7 @@ fn test_precise_analysis_drop_paths_not_captured_by_move() {
     let t = ConstainsDropField(Foo(10), Foo(20));
 
     let c = || { let _ = &t; 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
         let _t = &t.1;
@@ -40,7 +40,7 @@ fn test_precise_analysis_long_path_missing() {
     let u = U(T(S, S), T(S, S));
 
     let c = || { let _ = &u; 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
     //~| HELP: add a dummy let to cause `u` to be fully captured
         let _x = u.0.0;
         let _x = u.0.1;
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs b/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs
index fb4af00aa06..cb432304592 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs
@@ -17,7 +17,7 @@ fn test_precise_analysis_drop_paths_not_captured_by_move() {
     let t = ConstainsDropField(Foo(10), Foo(20));
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
         let _t = &t.1;
@@ -40,7 +40,7 @@ fn test_precise_analysis_long_path_missing() {
     let u = U(T(S, S), T(S, S));
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
     //~| HELP: add a dummy let to cause `u` to be fully captured
         let _x = u.0.0;
         let _x = u.0.1;
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr
index 0cd191e2c98..f010c51f136 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr
@@ -1,4 +1,4 @@
-error: drop order affected for closure because of `capture_disjoint_fields`
+error: drop order will change in Rust 2021
   --> $DIR/precise.rs:19:13
    |
 LL |       let c = || {
@@ -15,6 +15,7 @@ note: the lint level is defined here
    |
 LL | #![deny(disjoint_capture_migration)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = || { let _ = &t; 
@@ -25,7 +26,7 @@ LL |         let _t = &t.1;
 LL |     };
    |
 
-error: drop order affected for closure because of `capture_disjoint_fields`
+error: drop order will change in Rust 2021
   --> $DIR/precise.rs:42:13
    |
 LL |       let c = || {
@@ -38,6 +39,7 @@ LL | |         let _x = u.1.0;
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `u` to be fully captured
    |
 LL |     let c = || { let _ = &u; 
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed
index 1fa0fb3db2f..1c970175d18 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed
@@ -23,7 +23,8 @@ fn test1_all_need_migration() {
     let t2 = (Foo(0), Foo(0));
 
     let c = || { let _ = (&t, &t1, &t2); 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
         let _t = t.0;
         let _t1 = t1.0;
@@ -41,7 +42,8 @@ fn test2_only_precise_paths_need_migration() {
     let t2 = (Foo(0), Foo(0));
 
     let c = || { let _ = (&t, &t1); 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
         let _t = t.0;
         let _t1 = t1.0;
@@ -57,7 +59,8 @@ fn test3_only_by_value_need_migration() {
     let t = (Foo(0), Foo(0));
     let t1 = (Foo(0), Foo(0));
     let c = || { let _ = &t; 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
         println!("{:?}", t1.1);
@@ -74,7 +77,8 @@ fn test4_type_contains_drop_need_migration() {
     let t = ConstainsDropField(Foo(0), Foo(0));
 
     let c = || { let _ = &t; 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
     };
@@ -89,7 +93,8 @@ fn test5_drop_non_drop_aggregate_need_migration() {
     let t = (Foo(0), Foo(0), 0i32);
 
     let c = || { let _ = &t; 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
     };
@@ -102,7 +107,8 @@ fn test6_significant_insignificant_drop_aggregate_need_migration() {
     let t = (Foo(0), String::new());
 
     let c = || { let _ = &t; 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.1;
     };
@@ -117,7 +123,8 @@ fn test7_move_closures_non_copy_types_might_need_migration() {
     let t1 = (Foo(0), Foo(0), Foo(0));
 
     let c = move || { let _ = (&t1, &t); 
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
         println!("{:?} {:?}", t1.1, t.1);
     };
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs
index 1f0efbe1ebc..c479a6a54f0 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs
@@ -23,7 +23,8 @@ fn test1_all_need_migration() {
     let t2 = (Foo(0), Foo(0));
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
         let _t = t.0;
         let _t1 = t1.0;
@@ -41,7 +42,8 @@ fn test2_only_precise_paths_need_migration() {
     let t2 = (Foo(0), Foo(0));
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
         let _t = t.0;
         let _t1 = t1.0;
@@ -57,7 +59,8 @@ fn test3_only_by_value_need_migration() {
     let t = (Foo(0), Foo(0));
     let t1 = (Foo(0), Foo(0));
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
         println!("{:?}", t1.1);
@@ -74,7 +77,8 @@ fn test4_type_contains_drop_need_migration() {
     let t = ConstainsDropField(Foo(0), Foo(0));
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
     };
@@ -89,7 +93,8 @@ fn test5_drop_non_drop_aggregate_need_migration() {
     let t = (Foo(0), Foo(0), 0i32);
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.0;
     };
@@ -102,7 +107,8 @@ fn test6_significant_insignificant_drop_aggregate_need_migration() {
     let t = (Foo(0), String::new());
 
     let c = || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t` to be fully captured
         let _t = t.1;
     };
@@ -117,7 +123,8 @@ fn test7_move_closures_non_copy_types_might_need_migration() {
     let t1 = (Foo(0), Foo(0), Foo(0));
 
     let c = move || {
-    //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~^ ERROR: drop order
+    //~| NOTE: for more information, see
     //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
         println!("{:?} {:?}", t1.1, t.1);
     };
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr
index 91e75ffb81a..873a9100bee 100644
--- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr
@@ -1,12 +1,12 @@
-error: drop order affected for closure because of `capture_disjoint_fields`
+error: drop order will change in Rust 2021
   --> $DIR/significant_drop.rs:25:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
-LL | |         let _t = t.0;
-LL | |         let _t1 = t1.0;
+LL | |
+...  |
 LL | |         let _t2 = t2.0;
 LL | |     };
    | |_____^
@@ -16,137 +16,153 @@ note: the lint level is defined here
    |
 LL | #![deny(disjoint_capture_migration)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
    |
 LL |     let c = || { let _ = (&t, &t1, &t2); 
 LL |
 LL |
+LL |
 LL |         let _t = t.0;
 LL |         let _t1 = t1.0;
-LL |         let _t2 = t2.0;
  ...
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/significant_drop.rs:43:13
+error: drop order will change in Rust 2021
+  --> $DIR/significant_drop.rs:44:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
-LL | |         let _t = t.0;
-LL | |         let _t1 = t1.0;
+LL | |
+...  |
 LL | |         let _t2 = t2;
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t`, `t1` to be fully captured
    |
 LL |     let c = || { let _ = (&t, &t1); 
 LL |
 LL |
+LL |
 LL |         let _t = t.0;
 LL |         let _t1 = t1.0;
-LL |         let _t2 = t2;
  ...
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/significant_drop.rs:59:13
+error: drop order will change in Rust 2021
+  --> $DIR/significant_drop.rs:61:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         let _t = t.0;
 LL | |         println!("{:?}", t1.1);
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = || { let _ = &t; 
 LL |
 LL |
+LL |
 LL |         let _t = t.0;
 LL |         println!("{:?}", t1.1);
-LL |     };
-   |
+ ...
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/significant_drop.rs:76:13
+error: drop order will change in Rust 2021
+  --> $DIR/significant_drop.rs:79:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         let _t = t.0;
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = || { let _ = &t; 
 LL |
 LL |
+LL |
 LL |         let _t = t.0;
 LL |     };
    |
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/significant_drop.rs:91:13
+error: drop order will change in Rust 2021
+  --> $DIR/significant_drop.rs:95:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         let _t = t.0;
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = || { let _ = &t; 
 LL |
 LL |
+LL |
 LL |         let _t = t.0;
 LL |     };
    |
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/significant_drop.rs:104:13
+error: drop order will change in Rust 2021
+  --> $DIR/significant_drop.rs:109:13
    |
 LL |       let c = || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         let _t = t.1;
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t` to be fully captured
    |
 LL |     let c = || { let _ = &t; 
 LL |
 LL |
+LL |
 LL |         let _t = t.1;
 LL |     };
    |
 
-error: drop order affected for closure because of `capture_disjoint_fields`
-  --> $DIR/significant_drop.rs:119:13
+error: drop order will change in Rust 2021
+  --> $DIR/significant_drop.rs:125:13
    |
 LL |       let c = move || {
    |  _____________^
 LL | |
 LL | |
+LL | |
 LL | |         println!("{:?} {:?}", t1.1, t.1);
 LL | |     };
    | |_____^
    |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
 help: add a dummy let to cause `t1`, `t` to be fully captured
    |
 LL |     let c = move || { let _ = (&t1, &t); 
 LL |
 LL |
+LL |
 LL |         println!("{:?} {:?}", t1.1, t.1);
 LL |     };
    |
diff --git a/src/test/ui/closures/2229_closure_analysis/move_closure.rs b/src/test/ui/closures/2229_closure_analysis/move_closure.rs
index 1c574da5f48..06db19974eb 100644
--- a/src/test/ui/closures/2229_closure_analysis/move_closure.rs
+++ b/src/test/ui/closures/2229_closure_analysis/move_closure.rs
@@ -1,9 +1,7 @@
+// edition:2021
+
 // Test that move closures drop derefs with `capture_disjoint_fields` enabled.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![feature(rustc_attrs)]
 
 fn simple_move_closure() {
@@ -114,8 +112,9 @@ fn struct_contains_ref_to_another_struct_3() {
 fn truncate_box_derefs() {
     struct S(i32);
 
-    let b = Box::new(S(10));
 
+    // Content within the box is moved within the closure
+    let b = Box::new(S(10));
     let c = #[rustc_capture_analysis]
     //~^ ERROR: attributes on expressions are experimental
     //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
@@ -129,6 +128,37 @@ fn truncate_box_derefs() {
     };
 
     c();
+
+    // Content within the box is used by a shared ref and the box is the root variable
+    let b = Box::new(S(10));
+
+    let c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    move || {
+    //~^ ERROR: First Pass analysis includes:
+    //~| ERROR: Min Capture analysis includes:
+        println!("{}", b.0);
+        //~^ NOTE: Capturing b[Deref,(0, 0)] -> ByValue
+        //~| NOTE: Min Capture b[] -> ByValue
+    };
+
+    c();
+
+    // Content within the box is used by a shared ref and the box is not the root variable
+    let b = Box::new(S(10));
+    let t = (0, b);
+
+    let c = #[rustc_capture_analysis]
+    //~^ ERROR: attributes on expressions are experimental
+    //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+    move || {
+    //~^ ERROR: First Pass analysis includes:
+    //~| ERROR: Min Capture analysis includes:
+        println!("{}", t.1.0);
+        //~^ NOTE: Capturing t[(1, 0),Deref,(0, 0)] -> ByValue
+        //~| NOTE: Min Capture t[(1, 0)] -> ByValue
+    };
 }
 
 fn main() {
diff --git a/src/test/ui/closures/2229_closure_analysis/move_closure.stderr b/src/test/ui/closures/2229_closure_analysis/move_closure.stderr
index b91ef4dd85c..013cacfb9f2 100644
--- a/src/test/ui/closures/2229_closure_analysis/move_closure.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/move_closure.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/move_closure.rs:14:17
+  --> $DIR/move_closure.rs:12:17
    |
 LL |     let mut c = #[rustc_capture_analysis]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let mut c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/move_closure.rs:32:17
+  --> $DIR/move_closure.rs:30:17
    |
 LL |     let mut c = #[rustc_capture_analysis]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     let mut c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/move_closure.rs:53:17
+  --> $DIR/move_closure.rs:51:17
    |
 LL |     let mut c = #[rustc_capture_analysis]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL |     let mut c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/move_closure.rs:76:17
+  --> $DIR/move_closure.rs:74:17
    |
 LL |     let mut c = #[rustc_capture_analysis]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -35,7 +35,7 @@ LL |     let mut c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/move_closure.rs:98:17
+  --> $DIR/move_closure.rs:96:17
    |
 LL |     let mut c = #[rustc_capture_analysis]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -44,7 +44,7 @@ LL |     let mut c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/move_closure.rs:119:13
+  --> $DIR/move_closure.rs:118:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -52,17 +52,26 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/move_closure.rs:3:12
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/move_closure.rs:135:13
+   |
+LL |     let c = #[rustc_capture_analysis]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/move_closure.rs:152:13
    |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let c = #[rustc_capture_analysis]
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error: First Pass analysis includes:
-  --> $DIR/move_closure.rs:17:5
+  --> $DIR/move_closure.rs:15:5
    |
 LL | /     move || {
 LL | |
@@ -74,13 +83,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing t[(0, 0),(0, 0)] -> ByValue
-  --> $DIR/move_closure.rs:20:9
+  --> $DIR/move_closure.rs:18:9
    |
 LL |         t.0.0 = "new S".into();
    |         ^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/move_closure.rs:17:5
+  --> $DIR/move_closure.rs:15:5
    |
 LL | /     move || {
 LL | |
@@ -92,13 +101,13 @@ LL | |     };
    | |_____^
    |
 note: Min Capture t[(0, 0),(0, 0)] -> ByValue
-  --> $DIR/move_closure.rs:20:9
+  --> $DIR/move_closure.rs:18:9
    |
 LL |         t.0.0 = "new S".into();
    |         ^^^^^
 
 error: First Pass analysis includes:
-  --> $DIR/move_closure.rs:35:5
+  --> $DIR/move_closure.rs:33:5
    |
 LL | /     move || {
 LL | |
@@ -110,13 +119,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing ref_s[Deref] -> UniqueImmBorrow
-  --> $DIR/move_closure.rs:38:9
+  --> $DIR/move_closure.rs:36:9
    |
 LL |         *ref_s += 10;
    |         ^^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/move_closure.rs:35:5
+  --> $DIR/move_closure.rs:33:5
    |
 LL | /     move || {
 LL | |
@@ -128,13 +137,13 @@ LL | |     };
    | |_____^
    |
 note: Min Capture ref_s[Deref] -> UniqueImmBorrow
-  --> $DIR/move_closure.rs:38:9
+  --> $DIR/move_closure.rs:36:9
    |
 LL |         *ref_s += 10;
    |         ^^^^^^
 
 error: First Pass analysis includes:
-  --> $DIR/move_closure.rs:56:5
+  --> $DIR/move_closure.rs:54:5
    |
 LL | /     move || {
 LL | |
@@ -146,13 +155,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing t[(0, 0),Deref,(0, 0)] -> UniqueImmBorrow
-  --> $DIR/move_closure.rs:59:9
+  --> $DIR/move_closure.rs:57:9
    |
 LL |         t.0.0 = "new s".into();
    |         ^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/move_closure.rs:56:5
+  --> $DIR/move_closure.rs:54:5
    |
 LL | /     move || {
 LL | |
@@ -164,13 +173,13 @@ LL | |     };
    | |_____^
    |
 note: Min Capture t[(0, 0),Deref,(0, 0)] -> UniqueImmBorrow
-  --> $DIR/move_closure.rs:59:9
+  --> $DIR/move_closure.rs:57:9
    |
 LL |         t.0.0 = "new s".into();
    |         ^^^^^
 
 error: First Pass analysis includes:
-  --> $DIR/move_closure.rs:79:5
+  --> $DIR/move_closure.rs:77:5
    |
 LL | /     move || {
 LL | |
@@ -182,13 +191,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
-  --> $DIR/move_closure.rs:82:18
+  --> $DIR/move_closure.rs:80:18
    |
 LL |         let _t = t.0.0;
    |                  ^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/move_closure.rs:79:5
+  --> $DIR/move_closure.rs:77:5
    |
 LL | /     move || {
 LL | |
@@ -200,13 +209,13 @@ LL | |     };
    | |_____^
    |
 note: Min Capture t[(0, 0),Deref,(0, 0)] -> ImmBorrow
-  --> $DIR/move_closure.rs:82:18
+  --> $DIR/move_closure.rs:80:18
    |
 LL |         let _t = t.0.0;
    |                  ^^^^^
 
 error: First Pass analysis includes:
-  --> $DIR/move_closure.rs:101:5
+  --> $DIR/move_closure.rs:99:5
    |
 LL | /     move || {
 LL | |
@@ -218,18 +227,18 @@ LL | |     };
    | |_____^
    |
 note: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
-  --> $DIR/move_closure.rs:104:18
+  --> $DIR/move_closure.rs:102:18
    |
 LL |         let _t = t.0.0;
    |                  ^^^^^
 note: Capturing t[(0, 0)] -> ByValue
-  --> $DIR/move_closure.rs:104:18
+  --> $DIR/move_closure.rs:102:18
    |
 LL |         let _t = t.0.0;
    |                  ^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/move_closure.rs:101:5
+  --> $DIR/move_closure.rs:99:5
    |
 LL | /     move || {
 LL | |
@@ -241,13 +250,13 @@ LL | |     };
    | |_____^
    |
 note: Min Capture t[(0, 0)] -> ByValue
-  --> $DIR/move_closure.rs:104:18
+  --> $DIR/move_closure.rs:102:18
    |
 LL |         let _t = t.0.0;
    |                  ^^^^^
 
 error: First Pass analysis includes:
-  --> $DIR/move_closure.rs:122:5
+  --> $DIR/move_closure.rs:121:5
    |
 LL | /     move || {
 LL | |
@@ -259,18 +268,18 @@ LL | |     };
    | |_____^
    |
 note: Capturing b[Deref,(0, 0)] -> ByValue
-  --> $DIR/move_closure.rs:125:18
+  --> $DIR/move_closure.rs:124:18
    |
 LL |         let _t = b.0;
    |                  ^^^
 note: Capturing b[] -> ByValue
-  --> $DIR/move_closure.rs:125:18
+  --> $DIR/move_closure.rs:124:18
    |
 LL |         let _t = b.0;
    |                  ^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/move_closure.rs:122:5
+  --> $DIR/move_closure.rs:121:5
    |
 LL | /     move || {
 LL | |
@@ -282,11 +291,83 @@ LL | |     };
    | |_____^
    |
 note: Min Capture b[] -> ByValue
-  --> $DIR/move_closure.rs:125:18
+  --> $DIR/move_closure.rs:124:18
    |
 LL |         let _t = b.0;
    |                  ^^^
 
-error: aborting due to 18 previous errors; 1 warning emitted
+error: First Pass analysis includes:
+  --> $DIR/move_closure.rs:138:5
+   |
+LL | /     move || {
+LL | |
+LL | |
+LL | |         println!("{}", b.0);
+LL | |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing b[Deref,(0, 0)] -> ByValue
+  --> $DIR/move_closure.rs:141:24
+   |
+LL |         println!("{}", b.0);
+   |                        ^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/move_closure.rs:138:5
+   |
+LL | /     move || {
+LL | |
+LL | |
+LL | |         println!("{}", b.0);
+LL | |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture b[] -> ByValue
+  --> $DIR/move_closure.rs:141:24
+   |
+LL |         println!("{}", b.0);
+   |                        ^^^
+
+error: First Pass analysis includes:
+  --> $DIR/move_closure.rs:155:5
+   |
+LL | /     move || {
+LL | |
+LL | |
+LL | |         println!("{}", t.1.0);
+LL | |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Capturing t[(1, 0),Deref,(0, 0)] -> ByValue
+  --> $DIR/move_closure.rs:158:24
+   |
+LL |         println!("{}", t.1.0);
+   |                        ^^^^^
+
+error: Min Capture analysis includes:
+  --> $DIR/move_closure.rs:155:5
+   |
+LL | /     move || {
+LL | |
+LL | |
+LL | |         println!("{}", t.1.0);
+LL | |
+LL | |
+LL | |     };
+   | |_____^
+   |
+note: Min Capture t[(1, 0)] -> ByValue
+  --> $DIR/move_closure.rs:158:24
+   |
+LL |         println!("{}", t.1.0);
+   |                        ^^^^^
+
+error: aborting due to 24 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/multilevel-path-1.rs b/src/test/ui/closures/2229_closure_analysis/multilevel-path-1.rs
index 7d2d4c104d4..a8a2acfa78d 100644
--- a/src/test/ui/closures/2229_closure_analysis/multilevel-path-1.rs
+++ b/src/test/ui/closures/2229_closure_analysis/multilevel-path-1.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(rustc_attrs)]
 #![allow(unused)]
 
diff --git a/src/test/ui/closures/2229_closure_analysis/multilevel-path-1.stderr b/src/test/ui/closures/2229_closure_analysis/multilevel-path-1.stderr
index 1c8db7952af..29ad1c59198 100644
--- a/src/test/ui/closures/2229_closure_analysis/multilevel-path-1.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/multilevel-path-1.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/multilevel-path-1.rs:24:13
+  --> $DIR/multilevel-path-1.rs:22:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/multilevel-path-1.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/multilevel-path-1.rs:27:5
+  --> $DIR/multilevel-path-1.rs:25:5
    |
 LL | /     || {
 LL | |
@@ -29,13 +20,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing w[(0, 0)] -> ImmBorrow
-  --> $DIR/multilevel-path-1.rs:30:19
+  --> $DIR/multilevel-path-1.rs:28:19
    |
 LL |         let wp = &w.p;
    |                   ^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/multilevel-path-1.rs:27:5
+  --> $DIR/multilevel-path-1.rs:25:5
    |
 LL | /     || {
 LL | |
@@ -47,11 +38,11 @@ LL | |     };
    | |_____^
    |
 note: Min Capture w[(0, 0)] -> ImmBorrow
-  --> $DIR/multilevel-path-1.rs:30:19
+  --> $DIR/multilevel-path-1.rs:28:19
    |
 LL |         let wp = &w.p;
    |                   ^^^
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/multilevel-path-2.rs b/src/test/ui/closures/2229_closure_analysis/multilevel-path-2.rs
index 540e70138e5..e21fe318cd1 100644
--- a/src/test/ui/closures/2229_closure_analysis/multilevel-path-2.rs
+++ b/src/test/ui/closures/2229_closure_analysis/multilevel-path-2.rs
@@ -1,9 +1,5 @@
-// FIXME(arora-aman) add run-pass once 2229 is implemented
+// edition:2021
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![feature(rustc_attrs)]
 #![allow(unused)]
 
diff --git a/src/test/ui/closures/2229_closure_analysis/multilevel-path-2.stderr b/src/test/ui/closures/2229_closure_analysis/multilevel-path-2.stderr
index 37287f6b3bc..929cba11314 100644
--- a/src/test/ui/closures/2229_closure_analysis/multilevel-path-2.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/multilevel-path-2.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/multilevel-path-2.rs:21:13
+  --> $DIR/multilevel-path-2.rs:17:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/multilevel-path-2.rs:3:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/multilevel-path-2.rs:24:5
+  --> $DIR/multilevel-path-2.rs:20:5
    |
 LL | /     || {
 LL | |
@@ -29,13 +20,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing w[(0, 0),(0, 0)] -> ImmBorrow
-  --> $DIR/multilevel-path-2.rs:27:24
+  --> $DIR/multilevel-path-2.rs:23:24
    |
 LL |         println!("{}", w.p.x);
    |                        ^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/multilevel-path-2.rs:24:5
+  --> $DIR/multilevel-path-2.rs:20:5
    |
 LL | /     || {
 LL | |
@@ -47,11 +38,11 @@ LL | |     };
    | |_____^
    |
 note: Min Capture w[(0, 0),(0, 0)] -> ImmBorrow
-  --> $DIR/multilevel-path-2.rs:27:24
+  --> $DIR/multilevel-path-2.rs:23:24
    |
 LL |         println!("{}", w.p.x);
    |                        ^^^^^
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/nested-closure.rs b/src/test/ui/closures/2229_closure_analysis/nested-closure.rs
index 88620550f2e..f6775b3a3a5 100644
--- a/src/test/ui/closures/2229_closure_analysis/nested-closure.rs
+++ b/src/test/ui/closures/2229_closure_analysis/nested-closure.rs
@@ -1,9 +1,5 @@
-// FIXME(arora-aman) add run-pass once 2229 is implemented
+// edition:2021
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![feature(rustc_attrs)]
 
 struct Point {
diff --git a/src/test/ui/closures/2229_closure_analysis/nested-closure.stderr b/src/test/ui/closures/2229_closure_analysis/nested-closure.stderr
index 21147be3f1d..013bc74e67e 100644
--- a/src/test/ui/closures/2229_closure_analysis/nested-closure.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/nested-closure.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/nested-closure.rs:23:18
+  --> $DIR/nested-closure.rs:19:18
    |
 LL |     let mut c1 = #[rustc_capture_analysis]
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let mut c1 = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/nested-closure.rs:33:22
+  --> $DIR/nested-closure.rs:29:22
    |
 LL |         let mut c2 = #[rustc_capture_analysis]
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,51 +16,42 @@ LL |         let mut c2 = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/nested-closure.rs:3:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/nested-closure.rs:36:9
+  --> $DIR/nested-closure.rs:32:9
    |
 LL |         || p.y += incr;
    |         ^^^^^^^^^^^^^^
    |
 note: Capturing p[(1, 0)] -> MutBorrow
-  --> $DIR/nested-closure.rs:36:12
+  --> $DIR/nested-closure.rs:32:12
    |
 LL |         || p.y += incr;
    |            ^^^
 note: Capturing incr[] -> ImmBorrow
-  --> $DIR/nested-closure.rs:36:19
+  --> $DIR/nested-closure.rs:32:19
    |
 LL |         || p.y += incr;
    |                   ^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/nested-closure.rs:36:9
+  --> $DIR/nested-closure.rs:32:9
    |
 LL |         || p.y += incr;
    |         ^^^^^^^^^^^^^^
    |
 note: Min Capture p[(1, 0)] -> MutBorrow
-  --> $DIR/nested-closure.rs:36:12
+  --> $DIR/nested-closure.rs:32:12
    |
 LL |         || p.y += incr;
    |            ^^^
 note: Min Capture incr[] -> ImmBorrow
-  --> $DIR/nested-closure.rs:36:19
+  --> $DIR/nested-closure.rs:32:19
    |
 LL |         || p.y += incr;
    |                   ^^^^
 
 error: First Pass analysis includes:
-  --> $DIR/nested-closure.rs:26:5
+  --> $DIR/nested-closure.rs:22:5
    |
 LL | /     || {
 LL | |
@@ -72,18 +63,18 @@ LL | |     };
    | |_____^
    |
 note: Capturing p[(0, 0)] -> ImmBorrow
-  --> $DIR/nested-closure.rs:29:24
+  --> $DIR/nested-closure.rs:25:24
    |
 LL |         println!("{}", p.x);
    |                        ^^^
 note: Capturing p[(1, 0)] -> MutBorrow
-  --> $DIR/nested-closure.rs:36:12
+  --> $DIR/nested-closure.rs:32:12
    |
 LL |         || p.y += incr;
    |            ^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/nested-closure.rs:26:5
+  --> $DIR/nested-closure.rs:22:5
    |
 LL | /     || {
 LL | |
@@ -95,16 +86,16 @@ LL | |     };
    | |_____^
    |
 note: Min Capture p[(0, 0)] -> ImmBorrow
-  --> $DIR/nested-closure.rs:29:24
+  --> $DIR/nested-closure.rs:25:24
    |
 LL |         println!("{}", p.x);
    |                        ^^^
 note: Min Capture p[(1, 0)] -> MutBorrow
-  --> $DIR/nested-closure.rs:36:12
+  --> $DIR/nested-closure.rs:32:12
    |
 LL |         || p.y += incr;
    |            ^^^
 
-error: aborting due to 6 previous errors; 1 warning emitted
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/path-with-array-access.rs b/src/test/ui/closures/2229_closure_analysis/path-with-array-access.rs
index 16acd2f3206..0c10319314a 100644
--- a/src/test/ui/closures/2229_closure_analysis/path-with-array-access.rs
+++ b/src/test/ui/closures/2229_closure_analysis/path-with-array-access.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(rustc_attrs)]
 
 struct Point {
diff --git a/src/test/ui/closures/2229_closure_analysis/path-with-array-access.stderr b/src/test/ui/closures/2229_closure_analysis/path-with-array-access.stderr
index 3c8d07ed9ba..124b7bf6fe2 100644
--- a/src/test/ui/closures/2229_closure_analysis/path-with-array-access.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/path-with-array-access.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/path-with-array-access.rs:25:13
+  --> $DIR/path-with-array-access.rs:23:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/path-with-array-access.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/path-with-array-access.rs:28:5
+  --> $DIR/path-with-array-access.rs:26:5
    |
 LL | /     || {
 LL | |
@@ -29,13 +20,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing pent[(0, 0)] -> ImmBorrow
-  --> $DIR/path-with-array-access.rs:31:24
+  --> $DIR/path-with-array-access.rs:29:24
    |
 LL |         println!("{}", pent.points[5].x);
    |                        ^^^^^^^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/path-with-array-access.rs:28:5
+  --> $DIR/path-with-array-access.rs:26:5
    |
 LL | /     || {
 LL | |
@@ -47,11 +38,11 @@ LL | |     };
    | |_____^
    |
 note: Min Capture pent[(0, 0)] -> ImmBorrow
-  --> $DIR/path-with-array-access.rs:31:24
+  --> $DIR/path-with-array-access.rs:29:24
    |
 LL |         println!("{}", pent.points[5].x);
    |                        ^^^^^^^^^^^
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.rs b/src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.rs
index 609a11a578a..0f288ffa95a 100644
--- a/src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.rs
+++ b/src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| `#[warn(incomplete_features)]` on by default
-//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(never_type)]
 
 // Should fake read the discriminant and throw an error
diff --git a/src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.stderr b/src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.stderr
index c225abb58b7..45641ea3de3 100644
--- a/src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.stderr
@@ -1,14 +1,5 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/pattern-matching-should-fail.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error[E0004]: non-exhaustive patterns: type `u8` is non-empty
-  --> $DIR/pattern-matching-should-fail.rs:72:23
+  --> $DIR/pattern-matching-should-fail.rs:70:23
    |
 LL |     let c1 = || match x { };
    |                       ^
@@ -17,13 +8,13 @@ LL |     let c1 = || match x { };
    = note: the matched value is of type `u8`
 
 error[E0381]: use of possibly-uninitialized variable: `x`
-  --> $DIR/pattern-matching-should-fail.rs:10:23
+  --> $DIR/pattern-matching-should-fail.rs:8:23
    |
 LL |     let c1 = || match x { };
    |                       ^ use of possibly-uninitialized `x`
 
 error[E0381]: borrow of possibly-uninitialized variable: `x`
-  --> $DIR/pattern-matching-should-fail.rs:17:14
+  --> $DIR/pattern-matching-should-fail.rs:15:14
    |
 LL |     let c2 = || match x { _ => () };
    |              ^^       - borrow occurs due to use in closure
@@ -31,7 +22,7 @@ LL |     let c2 = || match x { _ => () };
    |              use of possibly-uninitialized `x`
 
 error[E0381]: borrow of possibly-uninitialized variable: `variant`
-  --> $DIR/pattern-matching-should-fail.rs:29:13
+  --> $DIR/pattern-matching-should-fail.rs:27:13
    |
 LL |     let c = || {
    |             ^^ use of possibly-uninitialized `variant`
@@ -40,7 +31,7 @@ LL |         match variant {
    |               ------- borrow occurs due to use in closure
 
 error[E0381]: borrow of possibly-uninitialized variable: `variant`
-  --> $DIR/pattern-matching-should-fail.rs:41:13
+  --> $DIR/pattern-matching-should-fail.rs:39:13
    |
 LL |     let c = || {
    |             ^^ use of possibly-uninitialized `variant`
@@ -49,24 +40,24 @@ LL |         match variant {
    |               ------- borrow occurs due to use in closure
 
 error[E0381]: use of possibly-uninitialized variable: `g`
-  --> $DIR/pattern-matching-should-fail.rs:57:15
+  --> $DIR/pattern-matching-should-fail.rs:55:15
    |
 LL |         match g { };
    |               ^ use of possibly-uninitialized `g`
 
 error[E0381]: use of possibly-uninitialized variable: `t`
-  --> $DIR/pattern-matching-should-fail.rs:60:19
+  --> $DIR/pattern-matching-should-fail.rs:58:19
    |
 LL |             match t { };
    |                   ^ use of possibly-uninitialized `t`
 
 error[E0381]: use of possibly-uninitialized variable: `x`
-  --> $DIR/pattern-matching-should-fail.rs:72:23
+  --> $DIR/pattern-matching-should-fail.rs:70:23
    |
 LL |     let c1 = || match x { };
    |                       ^ use of possibly-uninitialized `x`
 
-error: aborting due to 8 previous errors; 1 warning emitted
+error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0004, E0381.
 For more information about an error, try `rustc --explain E0004`.
diff --git a/src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.rs b/src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.rs
index 0a877dd366c..56f5ac44db0 100644
--- a/src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.rs
+++ b/src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(rustc_attrs)]
 
 // Should capture the discriminant since a variant of a multivariant enum is
diff --git a/src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.stderr b/src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.stderr
index ad3e96a5753..46081333395 100644
--- a/src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/patterns-capture-analysis.rs:12:14
+  --> $DIR/patterns-capture-analysis.rs:10:14
    |
 LL |     let c =  #[rustc_capture_analysis]
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let c =  #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/patterns-capture-analysis.rs:33:14
+  --> $DIR/patterns-capture-analysis.rs:31:14
    |
 LL |     let c =  #[rustc_capture_analysis]
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     let c =  #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/patterns-capture-analysis.rs:54:14
+  --> $DIR/patterns-capture-analysis.rs:52:14
    |
 LL |     let c =  #[rustc_capture_analysis]
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL |     let c =  #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/patterns-capture-analysis.rs:70:14
+  --> $DIR/patterns-capture-analysis.rs:68:14
    |
 LL |     let c =  #[rustc_capture_analysis]
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -35,7 +35,7 @@ LL |     let c =  #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/patterns-capture-analysis.rs:92:14
+  --> $DIR/patterns-capture-analysis.rs:90:14
    |
 LL |     let c =  #[rustc_capture_analysis]
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -44,7 +44,7 @@ LL |     let c =  #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/patterns-capture-analysis.rs:116:14
+  --> $DIR/patterns-capture-analysis.rs:114:14
    |
 LL |     let c =  #[rustc_capture_analysis]
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -52,17 +52,8 @@ LL |     let c =  #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/patterns-capture-analysis.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/patterns-capture-analysis.rs:16:5
+  --> $DIR/patterns-capture-analysis.rs:14:5
    |
 LL | /     || {
 LL | |
@@ -74,13 +65,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing variant[] -> ImmBorrow
-  --> $DIR/patterns-capture-analysis.rs:19:15
+  --> $DIR/patterns-capture-analysis.rs:17:15
    |
 LL |         match variant {
    |               ^^^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/patterns-capture-analysis.rs:16:5
+  --> $DIR/patterns-capture-analysis.rs:14:5
    |
 LL | /     || {
 LL | |
@@ -92,13 +83,13 @@ LL | |     };
    | |_____^
    |
 note: Min Capture variant[] -> ImmBorrow
-  --> $DIR/patterns-capture-analysis.rs:19:15
+  --> $DIR/patterns-capture-analysis.rs:17:15
    |
 LL |         match variant {
    |               ^^^^^^^
 
 error: First Pass analysis includes:
-  --> $DIR/patterns-capture-analysis.rs:36:5
+  --> $DIR/patterns-capture-analysis.rs:34:5
    |
 LL | /     || {
 LL | |
@@ -109,7 +100,7 @@ LL | |     };
    | |_____^
 
 error: First Pass analysis includes:
-  --> $DIR/patterns-capture-analysis.rs:57:5
+  --> $DIR/patterns-capture-analysis.rs:55:5
    |
 LL | /     || {
 LL | |
@@ -120,7 +111,7 @@ LL | |     };
    | |_____^
 
 error: First Pass analysis includes:
-  --> $DIR/patterns-capture-analysis.rs:73:5
+  --> $DIR/patterns-capture-analysis.rs:71:5
    |
 LL | /     || {
 LL | |
@@ -132,18 +123,18 @@ LL | |     };
    | |_____^
    |
 note: Capturing variant[] -> ImmBorrow
-  --> $DIR/patterns-capture-analysis.rs:76:15
+  --> $DIR/patterns-capture-analysis.rs:74:15
    |
 LL |         match variant {
    |               ^^^^^^^
 note: Capturing variant[(0, 0)] -> ImmBorrow
-  --> $DIR/patterns-capture-analysis.rs:76:15
+  --> $DIR/patterns-capture-analysis.rs:74:15
    |
 LL |         match variant {
    |               ^^^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/patterns-capture-analysis.rs:73:5
+  --> $DIR/patterns-capture-analysis.rs:71:5
    |
 LL | /     || {
 LL | |
@@ -155,13 +146,13 @@ LL | |     };
    | |_____^
    |
 note: Min Capture variant[] -> ImmBorrow
-  --> $DIR/patterns-capture-analysis.rs:76:15
+  --> $DIR/patterns-capture-analysis.rs:74:15
    |
 LL |         match variant {
    |               ^^^^^^^
 
 error: First Pass analysis includes:
-  --> $DIR/patterns-capture-analysis.rs:95:5
+  --> $DIR/patterns-capture-analysis.rs:93:5
    |
 LL | /     || {
 LL | |
@@ -172,7 +163,7 @@ LL | |     };
    | |_____^
 
 error: First Pass analysis includes:
-  --> $DIR/patterns-capture-analysis.rs:119:5
+  --> $DIR/patterns-capture-analysis.rs:117:5
    |
 LL | /     || {
 LL | |
@@ -184,13 +175,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing variant[] -> ImmBorrow
-  --> $DIR/patterns-capture-analysis.rs:122:15
+  --> $DIR/patterns-capture-analysis.rs:120:15
    |
 LL |         match variant {
    |               ^^^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/patterns-capture-analysis.rs:119:5
+  --> $DIR/patterns-capture-analysis.rs:117:5
    |
 LL | /     || {
 LL | |
@@ -202,11 +193,11 @@ LL | |     };
    | |_____^
    |
 note: Min Capture variant[] -> ImmBorrow
-  --> $DIR/patterns-capture-analysis.rs:122:15
+  --> $DIR/patterns-capture-analysis.rs:120:15
    |
 LL |         match variant {
    |               ^^^^^^^
 
-error: aborting due to 15 previous errors; 1 warning emitted
+error: aborting due to 15 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/repr_packed.rs b/src/test/ui/closures/2229_closure_analysis/repr_packed.rs
index 2b9ef2a76bb..7d472ad020f 100644
--- a/src/test/ui/closures/2229_closure_analysis/repr_packed.rs
+++ b/src/test/ui/closures/2229_closure_analysis/repr_packed.rs
@@ -1,7 +1,4 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| `#[warn(incomplete_features)]` on by default
-//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
 
 #![feature(rustc_attrs)]
 
diff --git a/src/test/ui/closures/2229_closure_analysis/repr_packed.stderr b/src/test/ui/closures/2229_closure_analysis/repr_packed.stderr
index 0517dd04b6f..405f66210aa 100644
--- a/src/test/ui/closures/2229_closure_analysis/repr_packed.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/repr_packed.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/repr_packed.rs:16:17
+  --> $DIR/repr_packed.rs:13:17
    |
 LL |     let mut c = #[rustc_capture_analysis]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let mut c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/repr_packed.rs:47:17
+  --> $DIR/repr_packed.rs:44:17
    |
 LL |     let mut c = #[rustc_capture_analysis]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     let mut c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/repr_packed.rs:81:13
+  --> $DIR/repr_packed.rs:78:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,17 +25,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/repr_packed.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/repr_packed.rs:19:5
+  --> $DIR/repr_packed.rs:16:5
    |
 LL | /     || {
 LL | |
@@ -47,18 +38,18 @@ LL | |     };
    | |_____^
    |
 note: Capturing foo[(0, 0)] -> ImmBorrow
-  --> $DIR/repr_packed.rs:22:24
+  --> $DIR/repr_packed.rs:19:24
    |
 LL |         let z1: &u8 = &foo.x;
    |                        ^^^^^
 note: Capturing foo[(1, 0)] -> MutBorrow
-  --> $DIR/repr_packed.rs:25:32
+  --> $DIR/repr_packed.rs:22:32
    |
 LL |         let z2: &mut u8 = &mut foo.y;
    |                                ^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/repr_packed.rs:19:5
+  --> $DIR/repr_packed.rs:16:5
    |
 LL | /     || {
 LL | |
@@ -70,18 +61,18 @@ LL | |     };
    | |_____^
    |
 note: Min Capture foo[(0, 0)] -> ImmBorrow
-  --> $DIR/repr_packed.rs:22:24
+  --> $DIR/repr_packed.rs:19:24
    |
 LL |         let z1: &u8 = &foo.x;
    |                        ^^^^^
 note: Min Capture foo[(1, 0)] -> MutBorrow
-  --> $DIR/repr_packed.rs:25:32
+  --> $DIR/repr_packed.rs:22:32
    |
 LL |         let z2: &mut u8 = &mut foo.y;
    |                                ^^^^^
 
 error: First Pass analysis includes:
-  --> $DIR/repr_packed.rs:50:5
+  --> $DIR/repr_packed.rs:47:5
    |
 LL | /     || {
 LL | |
@@ -93,13 +84,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing foo[] -> MutBorrow
-  --> $DIR/repr_packed.rs:54:33
+  --> $DIR/repr_packed.rs:51:33
    |
 LL |         let z2: &mut u16 = &mut foo.y;
    |                                 ^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/repr_packed.rs:50:5
+  --> $DIR/repr_packed.rs:47:5
    |
 LL | /     || {
 LL | |
@@ -111,13 +102,13 @@ LL | |     };
    | |_____^
    |
 note: Min Capture foo[] -> MutBorrow
-  --> $DIR/repr_packed.rs:54:33
+  --> $DIR/repr_packed.rs:51:33
    |
 LL |         let z2: &mut u16 = &mut foo.y;
    |                                 ^^^^^
 
 error: First Pass analysis includes:
-  --> $DIR/repr_packed.rs:84:5
+  --> $DIR/repr_packed.rs:81:5
    |
 LL | /     || {
 LL | |
@@ -129,18 +120,18 @@ LL | |     };
    | |_____^
    |
 note: Capturing foo[] -> ImmBorrow
-  --> $DIR/repr_packed.rs:87:24
+  --> $DIR/repr_packed.rs:84:24
    |
 LL |         println!("{}", foo.x);
    |                        ^^^^^
 note: Capturing foo[(0, 0)] -> ByValue
-  --> $DIR/repr_packed.rs:91:18
+  --> $DIR/repr_packed.rs:88:18
    |
 LL |         let _z = foo.x;
    |                  ^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/repr_packed.rs:84:5
+  --> $DIR/repr_packed.rs:81:5
    |
 LL | /     || {
 LL | |
@@ -152,7 +143,7 @@ LL | |     };
    | |_____^
    |
 note: Min Capture foo[] -> ByValue
-  --> $DIR/repr_packed.rs:87:24
+  --> $DIR/repr_packed.rs:84:24
    |
 LL |         println!("{}", foo.x);
    |                        ^^^^^ foo[] used here
@@ -160,6 +151,6 @@ LL |         println!("{}", foo.x);
 LL |         let _z = foo.x;
    |                  ^^^^^ foo[] captured as ByValue here
 
-error: aborting due to 9 previous errors; 1 warning emitted
+error: aborting due to 9 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/box.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/box.rs
index 3a66399d028..73aca288faa 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/box.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/box.rs
@@ -1,13 +1,8 @@
+// edition:2021
 // run-pass
 
 // Test precise capture when using boxes
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
-
-
 struct MetaData { x: String, name: String }
 struct Data { m: MetaData }
 struct BoxedData(Box<Data>);
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/box.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/box.stderr
deleted file mode 100644
index 9883c01b946..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/box.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/box.rs:5:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs
index 9a93e6cf1e1..2c828aed528 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.rs
@@ -1,11 +1,9 @@
+// edition:2021
 // run-pass
 
 // Test that ByValue captures compile sucessefully especially when the captures are
 // derefenced within the closure.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-
 #[derive(Debug, Default)]
 struct SomeLargeType;
 struct MuchLargerType([SomeLargeType; 32]);
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.stderr
deleted file mode 100644
index 98715c6b943..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/by_value.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/by_value.rs:6:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.rs
index 2c359519b76..3cb1eb32952 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.rs
@@ -1,13 +1,9 @@
+// edition:2021
 // run-pass
 
 // Test that we can immutably borrow field of an instance of a structure from within a closure,
 // while having a mutable borrow to another field of the same instance outside the closure.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
-
 struct Point {
     x: i32,
     y: i32,
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.stderr
deleted file mode 100644
index 9b0dea770fb..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/capture-disjoint-field-struct.rs:6:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.rs
index 2c6679feabe..0f79b7ae7b8 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.rs
@@ -1,12 +1,9 @@
+// edition:2021
 // run-pass
 
 // Test that we can mutate an element of a tuple from within a closure
 // while immutably borrowing another element of the same tuple outside the closure.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![feature(rustc_attrs)]
 
 fn main() {
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.stderr
deleted file mode 100644
index 28d09153952..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/capture-disjoint-field-tuple-mut.rs:6:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.rs
index 52f5cef9f01..81f0328b9ba 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.rs
@@ -1,12 +1,9 @@
+// edition:2021
 // run-pass
 
 // Test that we can immutably borrow an element of a tuple from within a closure,
 // while having a mutable borrow to another element of the same tuple outside the closure.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![feature(rustc_attrs)]
 
 fn main() {
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.stderr
deleted file mode 100644
index 4fb37f85f88..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/capture-disjoint-field-tuple.rs:6:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture_with_wildcard_match.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/capture_with_wildcard_match.rs
index eaea0dbfb5e..cea02fbe15d 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/capture_with_wildcard_match.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture_with_wildcard_match.rs
@@ -1,6 +1,5 @@
+// edition:2021
 //check-pass
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
 
 fn test1() {
     let foo : [Vec<u8>; 3] = ["String".into(), "String".into(), "String".into()];
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/capture_with_wildcard_match.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/capture_with_wildcard_match.stderr
deleted file mode 100644
index 2c17a189afb..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/capture_with_wildcard_match.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/capture_with_wildcard_match.rs:2:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.rs
index 3ad083a92d5..5c278bff90b 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.rs
@@ -1,6 +1,5 @@
-//check-pass
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+// edition:2021
+// check-pass
 #![warn(unused)]
 
 fn main() {
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr
index c4abf934123..40274c88318 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr
@@ -1,30 +1,21 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/destructure-pattern-closure-within-closure.rs:2:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 warning: unused variable: `t2`
-  --> $DIR/destructure-pattern-closure-within-closure.rs:14:21
+  --> $DIR/destructure-pattern-closure-within-closure.rs:13:21
    |
 LL |             let (_, t2) = t;
    |                     ^^ help: if this is intentional, prefix it with an underscore: `_t2`
    |
 note: the lint level is defined here
-  --> $DIR/destructure-pattern-closure-within-closure.rs:4:9
+  --> $DIR/destructure-pattern-closure-within-closure.rs:3:9
    |
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
 
 warning: unused variable: `g2`
-  --> $DIR/destructure-pattern-closure-within-closure.rs:11:17
+  --> $DIR/destructure-pattern-closure-within-closure.rs:10:17
    |
 LL |         let (_, g2) = g;
    |                 ^^ help: if this is intentional, prefix it with an underscore: `_g2`
 
-warning: 3 warnings emitted
+warning: 2 warnings emitted
 
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/destructure_patterns.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/destructure_patterns.rs
index 65527648b2c..07adbee03f9 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/destructure_patterns.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/destructure_patterns.rs
@@ -1,6 +1,5 @@
-//check-pass
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+// edition:2021
+// check-pass
 #![warn(unused)]
 
 struct Point {
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/destructure_patterns.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/destructure_patterns.stderr
index fcfe9ee95f1..6523f2b34d5 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/destructure_patterns.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/destructure_patterns.stderr
@@ -1,66 +1,57 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/destructure_patterns.rs:2:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 warning: unused variable: `t1`
-  --> $DIR/destructure_patterns.rs:15:14
+  --> $DIR/destructure_patterns.rs:14:14
    |
 LL |         let (t1, t2) = t;
    |              ^^ help: if this is intentional, prefix it with an underscore: `_t1`
    |
 note: the lint level is defined here
-  --> $DIR/destructure_patterns.rs:4:9
+  --> $DIR/destructure_patterns.rs:3:9
    |
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
 
 warning: unused variable: `t2`
-  --> $DIR/destructure_patterns.rs:15:18
+  --> $DIR/destructure_patterns.rs:14:18
    |
 LL |         let (t1, t2) = t;
    |                  ^^ help: if this is intentional, prefix it with an underscore: `_t2`
 
 warning: unused variable: `t1`
-  --> $DIR/destructure_patterns.rs:27:14
+  --> $DIR/destructure_patterns.rs:26:14
    |
 LL |         let (t1, _) = t;
    |              ^^ help: if this is intentional, prefix it with an underscore: `_t1`
 
 warning: unused variable: `t2`
-  --> $DIR/destructure_patterns.rs:38:17
+  --> $DIR/destructure_patterns.rs:37:17
    |
 LL |         let (_, t2) = t;
    |                 ^^ help: if this is intentional, prefix it with an underscore: `_t2`
 
 warning: unused variable: `t`
-  --> $DIR/destructure_patterns.rs:46:9
+  --> $DIR/destructure_patterns.rs:45:9
    |
 LL |     let t = (String::from("Hello"), String::from("World"));
    |         ^ help: if this is intentional, prefix it with an underscore: `_t`
 
 warning: unused variable: `x`
-  --> $DIR/destructure_patterns.rs:92:21
+  --> $DIR/destructure_patterns.rs:91:21
    |
 LL |         let Point { x, y } = p;
    |                     ^ help: try ignoring the field: `x: _`
 
 warning: unused variable: `x`
-  --> $DIR/destructure_patterns.rs:84:9
+  --> $DIR/destructure_patterns.rs:83:9
    |
 LL |     let x = 0;
    |         ^ help: if this is intentional, prefix it with an underscore: `_x`
 
 warning: unused variable: `tup`
-  --> $DIR/destructure_patterns.rs:86:9
+  --> $DIR/destructure_patterns.rs:85:9
    |
 LL |     let tup = (1, 2);
    |         ^^^ help: if this is intentional, prefix it with an underscore: `_tup`
 
-warning: 9 warnings emitted
+warning: 8 warnings emitted
 
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs
index 3f8e197b783..88a9816a052 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs
@@ -1,10 +1,6 @@
+// edition:2021
 // run-pass
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
-
 // Tests that if a closure uses indivual fields of the same object
 // then that case is handled properly.
 
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.stderr
deleted file mode 100644
index bba90f8917a..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/disjoint-capture-in-same-closure.rs:3:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs
index dae50854d82..477fdd613f5 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs
@@ -1,6 +1,5 @@
-//check-pass
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+// edition:2021
+// check-pass
 #![feature(rustc_attrs)]
 
 fn main() {
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.stderr
deleted file mode 100644
index 7f811875d13..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/drop_then_use_fake_reads.rs:2:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.rs
index 8c12593430e..e19f5ff1bae 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.rs
@@ -1,12 +1,8 @@
+// edition:2021
 // run-pass
 
 // Test disjoint capture within an impl block
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
-
 struct Filter {
     div: i32,
 }
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.stderr
deleted file mode 100644
index 6930e18992a..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/filter-on-struct-member.rs:5:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.rs
index e89cf4550c1..1286613cb13 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.rs
@@ -1,13 +1,9 @@
+// edition:2021
 // run-pass
 
 // Test that functional record update/struct update syntax works inside
 // a closure when the feature `capture_disjoint_fields` is enabled.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
-
 #[derive(Clone)]
 struct S {
     a: String,
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.stderr
deleted file mode 100644
index 7ed73abba86..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/fru_syntax.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/fru_syntax.rs:6:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs
index 9c086fe4bdf..d2375aa69ec 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs
@@ -1,6 +1,5 @@
+// edition:2021
 //check-pass
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
 #![warn(unused)]
 #![feature(rustc_attrs)]
 #![feature(btree_drain_filter)]
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.stderr
deleted file mode 100644
index bc046ecad68..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/lit-pattern-matching-with-methods.rs:2:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs
index afaafbda018..65c8a5a7850 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.rs
@@ -1,10 +1,8 @@
+// edition:2021
 // run-pass
 
 // Test that move closures compile properly with `capture_disjoint_fields` enabled.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-
 fn simple_ref() {
     let mut s = 10;
     let ref_s = &mut s;
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.stderr
deleted file mode 100644
index c1d8ba575d6..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/move_closure.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/move_closure.rs:5:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs
index 142c156bd56..b8e46403181 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs
@@ -1,3 +1,4 @@
+// edition:2021
 // run-pass
 
 // Test that closures can catpure paths that are more precise than just one level
@@ -7,10 +8,6 @@
 // while being able to mutate another path outside the closure, where the two paths are disjoint
 // after applying two projections on the root variable.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![allow(unused)]
 
 struct Point {
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.stderr
deleted file mode 100644
index 94b877522f4..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/multilevel-path-1.rs:10:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs
index d8f7d55d5aa..11a324d8a34 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs
@@ -1,9 +1,6 @@
+// edition:2021
 // run-pass
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![allow(unused)]
 
 // If the closures can handle such precison we should be able to read one path in the closure
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.stderr
deleted file mode 100644
index 100a0e167c5..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/multilevel-path-2.rs:3:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.rs
index fc3d48ec458..8fc0efb60b7 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.rs
@@ -1,9 +1,6 @@
+// edition:2021
 // run-pass
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![allow(unused)]
 
 // Test that when `capture_disjoint_fields` is enabled we can read a path
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.stderr
deleted file mode 100644
index cf5be6a00e9..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/multilevel-path-3.rs:3:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref.rs
index 315622443c3..9f0c4d96aa5 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref.rs
@@ -1,11 +1,9 @@
+// edition:2021
 // run-pass
 
 // Test that we can mutate a place through a mut-borrow
 // that is captured by the closure
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-
 // Check that we can mutate when one deref is required
 fn mut_ref_1() {
     let mut x = String::new();
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref.stderr
deleted file mode 100644
index 4b37a0b405f..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/mut_ref.rs:6:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.rs
index 2dba923647a..bb784774b8c 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.rs
@@ -1,3 +1,4 @@
+// edition:2021
 // run-pass
 
 // Test that we can mutate a place through a mut-borrow
@@ -6,9 +7,6 @@
 // More specifically we test that the if the mutable reference isn't root variable of a capture
 // but rather accessed while acessing the precise capture.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-
 fn mut_tuple() {
     let mut t = (10, 10);
 
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.stderr
deleted file mode 100644
index 418ab29098b..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/mut_ref_struct_mem.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/mut_ref_struct_mem.rs:9:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.rs
index 238580929ef..a80b40bb469 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.rs
@@ -1,12 +1,8 @@
+// edition:2021
 // run-pass
 
 // Test whether if we can do precise capture when using nested clsoure.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
-
 struct Point {
     x: i32,
     y: i32,
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.stderr
deleted file mode 100644
index 293aa82ce9f..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/nested-closure.rs:5:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.rs
index d260a448926..045fe78040a 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.rs
@@ -1,6 +1,5 @@
+// edition:2021
 //check-pass
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
 #![warn(unused)]
 #![feature(rustc_attrs)]
 
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.stderr
deleted file mode 100644
index 3e4303a3710..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/struct-pattern-matching-with-methods.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/struct-pattern-matching-with-methods.rs:2:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/tuple-struct-pattern-matching-with-methods.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/tuple-struct-pattern-matching-with-methods.rs
index b3bee79254e..f3f44433ccf 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/tuple-struct-pattern-matching-with-methods.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/tuple-struct-pattern-matching-with-methods.rs
@@ -1,6 +1,5 @@
+// edition:2021
 //check-pass
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
 
 #[derive(Copy, Clone)]
 enum PointType {
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/tuple-struct-pattern-matching-with-methods.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/tuple-struct-pattern-matching-with-methods.stderr
deleted file mode 100644
index ded0e37b0f3..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/tuple-struct-pattern-matching-with-methods.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/tuple-struct-pattern-matching-with-methods.rs:2:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs
index f6e9862b26c..8e4f91c27e2 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.rs
@@ -1,10 +1,8 @@
+// edition:2021
 // run-pass
 
 // Test that we can use raw ptrs when using `capture_disjoint_fields`.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-
 #[derive(Debug)]
 struct S {
     s: String,
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.stderr
deleted file mode 100644
index c64c8b72e81..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/unsafe_ptr.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/unsafe_ptr.rs:5:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/use_of_mutable_borrow_and_fake_reads.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/use_of_mutable_borrow_and_fake_reads.rs
index 0e6da8f4f18..0206927cc59 100644
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/use_of_mutable_borrow_and_fake_reads.rs
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/use_of_mutable_borrow_and_fake_reads.rs
@@ -1,6 +1,5 @@
+// edition:2021
 //check-pass
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
 #![feature(rustc_attrs)]
 
 fn main() {
diff --git a/src/test/ui/closures/2229_closure_analysis/run_pass/use_of_mutable_borrow_and_fake_reads.stderr b/src/test/ui/closures/2229_closure_analysis/run_pass/use_of_mutable_borrow_and_fake_reads.stderr
deleted file mode 100644
index 7d16d77bf73..00000000000
--- a/src/test/ui/closures/2229_closure_analysis/run_pass/use_of_mutable_borrow_and_fake_reads.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/use_of_mutable_borrow_and_fake_reads.rs:2:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs b/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs
index a6b5e12d2ed..563095d440d 100644
--- a/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs
+++ b/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.rs
@@ -1,9 +1,5 @@
-// FIXME(arora-aman) add run-pass once 2229 is implemented
+// edition:2021
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
 #![feature(rustc_attrs)]
 
 // Test to ensure that min analysis meets capture kind for all paths captured.
diff --git a/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr b/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr
index cbbc8792199..05d79797ab3 100644
--- a/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/simple-struct-min-capture.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/simple-struct-min-capture.rs:27:17
+  --> $DIR/simple-struct-min-capture.rs:23:17
    |
 LL |     let mut c = #[rustc_capture_analysis]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,17 +7,8 @@ LL |     let mut c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/simple-struct-min-capture.rs:3:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/simple-struct-min-capture.rs:30:5
+  --> $DIR/simple-struct-min-capture.rs:26:5
    |
 LL | /     || {
 LL | |
@@ -29,18 +20,18 @@ LL | |     };
    | |_____^
    |
 note: Capturing p[(0, 0)] -> MutBorrow
-  --> $DIR/simple-struct-min-capture.rs:33:9
+  --> $DIR/simple-struct-min-capture.rs:29:9
    |
 LL |         p.x += 10;
    |         ^^^
 note: Capturing p[] -> ImmBorrow
-  --> $DIR/simple-struct-min-capture.rs:36:26
+  --> $DIR/simple-struct-min-capture.rs:32:26
    |
 LL |         println!("{:?}", p);
    |                          ^
 
 error: Min Capture analysis includes:
-  --> $DIR/simple-struct-min-capture.rs:30:5
+  --> $DIR/simple-struct-min-capture.rs:26:5
    |
 LL | /     || {
 LL | |
@@ -52,7 +43,7 @@ LL | |     };
    | |_____^
    |
 note: Min Capture p[] -> MutBorrow
-  --> $DIR/simple-struct-min-capture.rs:33:9
+  --> $DIR/simple-struct-min-capture.rs:29:9
    |
 LL |         p.x += 10;
    |         ^^^ p[] captured as MutBorrow here
@@ -60,6 +51,6 @@ LL |         p.x += 10;
 LL |         println!("{:?}", p);
    |                          ^ p[] used here
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.rs b/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.rs
index 79d3ecc2d2b..eab9f9d08a9 100644
--- a/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.rs
+++ b/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.rs
@@ -1,10 +1,9 @@
+// edition:2021
+
 // Test that we restrict precision of a capture when we access a raw ptr,
 // i.e. the capture doesn't deref the raw ptr.
 
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| `#[warn(incomplete_features)]` on by default
-//~| see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+
 #![feature(rustc_attrs)]
 
 #[derive(Debug)]
diff --git a/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.stderr b/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.stderr
index 4508b2426e8..e740a4d2d6b 100644
--- a/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/unsafe_ptr.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/unsafe_ptr.rs:26:13
+  --> $DIR/unsafe_ptr.rs:25:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/unsafe_ptr.rs:46:13
+  --> $DIR/unsafe_ptr.rs:45:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,17 +16,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/unsafe_ptr.rs:4:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/unsafe_ptr.rs:29:6
+  --> $DIR/unsafe_ptr.rs:28:6
    |
 LL | /      || unsafe {
 LL | |
@@ -38,13 +29,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
-  --> $DIR/unsafe_ptr.rs:32:26
+  --> $DIR/unsafe_ptr.rs:31:26
    |
 LL |         println!("{:?}", (*t.0).s);
    |                          ^^^^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/unsafe_ptr.rs:29:6
+  --> $DIR/unsafe_ptr.rs:28:6
    |
 LL | /      || unsafe {
 LL | |
@@ -56,13 +47,13 @@ LL | |     };
    | |_____^
    |
 note: Min Capture t[(0, 0)] -> ImmBorrow
-  --> $DIR/unsafe_ptr.rs:32:26
+  --> $DIR/unsafe_ptr.rs:31:26
    |
 LL |         println!("{:?}", (*t.0).s);
    |                          ^^^^^^^^
 
 error: First Pass analysis includes:
-  --> $DIR/unsafe_ptr.rs:49:5
+  --> $DIR/unsafe_ptr.rs:48:5
    |
 LL | /     || {
 LL | |
@@ -74,13 +65,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing p[Deref,(0, 0)] -> ImmBorrow
-  --> $DIR/unsafe_ptr.rs:52:31
+  --> $DIR/unsafe_ptr.rs:51:31
    |
 LL |         let x = unsafe { &mut (*p).s };
    |                               ^^^^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/unsafe_ptr.rs:49:5
+  --> $DIR/unsafe_ptr.rs:48:5
    |
 LL | /     || {
 LL | |
@@ -92,11 +83,11 @@ LL | |     };
    | |_____^
    |
 note: Min Capture p[] -> ImmBorrow
-  --> $DIR/unsafe_ptr.rs:52:31
+  --> $DIR/unsafe_ptr.rs:51:31
    |
 LL |         let x = unsafe { &mut (*p).s };
    |                               ^^^^^^
 
-error: aborting due to 6 previous errors; 1 warning emitted
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/closures/2229_closure_analysis/wild_patterns.rs b/src/test/ui/closures/2229_closure_analysis/wild_patterns.rs
index 90b8033d074..7843c251666 100644
--- a/src/test/ui/closures/2229_closure_analysis/wild_patterns.rs
+++ b/src/test/ui/closures/2229_closure_analysis/wild_patterns.rs
@@ -1,7 +1,5 @@
-#![feature(capture_disjoint_fields)]
-//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
-//~| NOTE: `#[warn(incomplete_features)]` on by default
-//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
+// edition:2021
+
 #![feature(rustc_attrs)]
 
 // Test to ensure that we can handle cases where
diff --git a/src/test/ui/closures/2229_closure_analysis/wild_patterns.stderr b/src/test/ui/closures/2229_closure_analysis/wild_patterns.stderr
index 36be8431be5..c64378091e6 100644
--- a/src/test/ui/closures/2229_closure_analysis/wild_patterns.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/wild_patterns.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/wild_patterns.rs:24:13
+  --> $DIR/wild_patterns.rs:22:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/wild_patterns.rs:42:13
+  --> $DIR/wild_patterns.rs:40:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     let c = #[rustc_capture_analysis]
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/wild_patterns.rs:60:13
+  --> $DIR/wild_patterns.rs:58:13
    |
 LL |     let c = #[rustc_capture_analysis]
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,17 +25,8 @@ LL |     let c = #[rustc_capture_analysis]
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
-warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/wild_patterns.rs:1:12
-   |
-LL | #![feature(capture_disjoint_fields)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
-
 error: First Pass analysis includes:
-  --> $DIR/wild_patterns.rs:27:5
+  --> $DIR/wild_patterns.rs:25:5
    |
 LL | /     || {
 LL | |
@@ -47,13 +38,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing p[(0, 0)] -> ImmBorrow
-  --> $DIR/wild_patterns.rs:31:37
+  --> $DIR/wild_patterns.rs:29:37
    |
 LL |         let Point { x: _x, y: _ } = p;
    |                                     ^
 
 error: Min Capture analysis includes:
-  --> $DIR/wild_patterns.rs:27:5
+  --> $DIR/wild_patterns.rs:25:5
    |
 LL | /     || {
 LL | |
@@ -65,13 +56,13 @@ LL | |     };
    | |_____^
    |
 note: Min Capture p[(0, 0)] -> ImmBorrow
-  --> $DIR/wild_patterns.rs:31:37
+  --> $DIR/wild_patterns.rs:29:37
    |
 LL |         let Point { x: _x, y: _ } = p;
    |                                     ^
 
 error: First Pass analysis includes:
-  --> $DIR/wild_patterns.rs:45:5
+  --> $DIR/wild_patterns.rs:43:5
    |
 LL | /     || {
 LL | |
@@ -83,13 +74,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing t[(0, 0)] -> ByValue
-  --> $DIR/wild_patterns.rs:49:23
+  --> $DIR/wild_patterns.rs:47:23
    |
 LL |         let (_x, _) = t;
    |                       ^
 
 error: Min Capture analysis includes:
-  --> $DIR/wild_patterns.rs:45:5
+  --> $DIR/wild_patterns.rs:43:5
    |
 LL | /     || {
 LL | |
@@ -101,13 +92,13 @@ LL | |     };
    | |_____^
    |
 note: Min Capture t[(0, 0)] -> ByValue
-  --> $DIR/wild_patterns.rs:49:23
+  --> $DIR/wild_patterns.rs:47:23
    |
 LL |         let (_x, _) = t;
    |                       ^
 
 error: First Pass analysis includes:
-  --> $DIR/wild_patterns.rs:63:5
+  --> $DIR/wild_patterns.rs:61:5
    |
 LL | /     || {
 LL | |
@@ -119,13 +110,13 @@ LL | |     };
    | |_____^
    |
 note: Capturing arr[Index] -> ByValue
-  --> $DIR/wild_patterns.rs:67:23
+  --> $DIR/wild_patterns.rs:65:23
    |
 LL |         let [_x, _] = arr;
    |                       ^^^
 
 error: Min Capture analysis includes:
-  --> $DIR/wild_patterns.rs:63:5
+  --> $DIR/wild_patterns.rs:61:5
    |
 LL | /     || {
 LL | |
@@ -137,11 +128,11 @@ LL | |     };
    | |_____^
    |
 note: Min Capture arr[] -> ByValue
-  --> $DIR/wild_patterns.rs:67:23
+  --> $DIR/wild_patterns.rs:65:23
    |
 LL |         let [_x, _] = arr;
    |                       ^^^
 
-error: aborting due to 9 previous errors; 1 warning emitted
+error: aborting due to 9 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/params-on-registers.rs b/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/params-on-registers.rs
index b09ea06c8f3..9e4521df8c3 100644
--- a/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/params-on-registers.rs
+++ b/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/params-on-registers.rs
@@ -1,13 +1,21 @@
 // build-pass
 // compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
-// only-thumbv8m.main-none-eabi
-#![feature(abi_c_cmse_nonsecure_call)]
-#![no_std]
+// needs-llvm-components: arm
+#![feature(abi_c_cmse_nonsecure_call, no_core, lang_items, intrinsics)]
+#![no_core]
+#[lang="sized"]
+pub trait Sized { }
+#[lang="copy"]
+pub trait Copy { }
+
+extern "rust-intrinsic" {
+    pub fn transmute<T, U>(e: T) -> U;
+}
 
 #[no_mangle]
 pub fn test(a: u32, b: u32, c: u32, d: u32) -> u32 {
     let non_secure_function = unsafe {
-        core::mem::transmute::<usize, extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32) -> u32>(
+        transmute::<usize, extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32) -> u32>(
             0x10000004,
         )
     };
diff --git a/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/params-on-stack.rs b/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/params-on-stack.rs
index cfdce4f4e92..9697146d5c3 100644
--- a/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/params-on-stack.rs
+++ b/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/params-on-stack.rs
@@ -1,12 +1,22 @@
+// build-fail
 // compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
-// only-thumbv8m.main-none-eabi
-#![feature(abi_c_cmse_nonsecure_call)]
-#![no_std]
+// needs-llvm-components: arm
+// min-llvm-version: 11.0
+#![feature(abi_c_cmse_nonsecure_call, no_core, lang_items, intrinsics)]
+#![no_core]
+#[lang="sized"]
+pub trait Sized { }
+#[lang="copy"]
+pub trait Copy { }
+
+extern "rust-intrinsic" {
+    pub fn transmute<T, U>(e: T) -> U;
+}
 
 #[no_mangle]
 pub fn test(a: u32, b: u32, c: u32, d: u32, e: u32) -> u32 {
     let non_secure_function = unsafe {
-        core::mem::transmute::<
+        transmute::<
             usize,
             extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32, u32) -> u32>
         (
diff --git a/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs b/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs
index 17117301fef..f32b3709002 100644
--- a/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs
+++ b/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs
@@ -1,6 +1,8 @@
 // compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
-// only-thumbv8m.main-none-eabi
-#![feature(abi_c_cmse_nonsecure_call)]
-#![no_std]
+// needs-llvm-components: arm
+#![feature(abi_c_cmse_nonsecure_call, lang_items, no_core)]
+#![no_core]
+#[lang="sized"]
+trait Sized { }
 
 pub extern "C-cmse-nonsecure-call" fn test() {} //~ ERROR [E0781]
diff --git a/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr b/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr
index 78490bf8f68..3564ab4b6cd 100644
--- a/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr
+++ b/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr
@@ -1,8 +1,8 @@
-error[E0781]: the `"cmse-nonsecure-call"` ABI is only allowed on function pointers.
-  --> $DIR/wrong-abi-location-1.rs:6:1
+error[E0781]: the `"C-cmse-nonsecure-call"` ABI is only allowed on function pointers.
+  --> $DIR/wrong-abi-location-1.rs:8:1
    |
-LL | pub extern "C-cmse-nonsecure-call" fn test() {} //~ ERROR [E0781]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | pub extern "C-cmse-nonsecure-call" fn test() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs b/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs
index 78f553d747c..6f8bb24aa69 100644
--- a/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs
+++ b/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs
@@ -1,7 +1,9 @@
 // compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
-// only-thumbv8m.main-none-eabi
-#![feature(abi_c_cmse_nonsecure_call)]
-#![no_std]
+// needs-llvm-components: arm
+#![feature(abi_c_cmse_nonsecure_call, lang_items, no_core)]
+#![no_core]
+#[lang="sized"]
+trait Sized { }
 
 extern "C-cmse-nonsecure-call" { //~ ERROR [E0781]
     fn test();
diff --git a/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr b/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr
index 5c148e2cd6f..76073f54884 100644
--- a/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr
+++ b/src/test/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr
@@ -1,8 +1,8 @@
 error[E0781]: the `"C-cmse-nonsecure-call"` ABI is only allowed on function pointers.
-  --> $DIR/wrong-abi-location-2.rs:6:1
+  --> $DIR/wrong-abi-location-2.rs:8:1
    |
 LL | / extern "C-cmse-nonsecure-call" {
-LL | |     fn test(); //~ ERROR [E0781]
+LL | |     fn test();
 LL | | }
    | |_^
 
diff --git a/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.rs b/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.rs
new file mode 100644
index 00000000000..a839406cd0a
--- /dev/null
+++ b/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.rs
@@ -0,0 +1,9 @@
+// Regression test for the ICE described in #83475.
+
+#![crate_type="lib"]
+
+#![feature(cmse_nonsecure_entry)]
+#[cmse_nonsecure_entry]
+//~^ ERROR: attribute should be applied to a function definition
+struct XEmpty2;
+//~^ NOTE: not a function definition
diff --git a/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.stderr b/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.stderr
new file mode 100644
index 00000000000..426d82d8d07
--- /dev/null
+++ b/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/issue-83475.stderr
@@ -0,0 +1,11 @@
+error: attribute should be applied to a function definition
+  --> $DIR/issue-83475.rs:6:1
+   |
+LL | #[cmse_nonsecure_entry]
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | struct XEmpty2;
+   | --------------- not a function definition
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs b/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs
index a723eb73473..8cde9ba58b9 100644
--- a/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs
+++ b/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs
@@ -1,11 +1,15 @@
 // build-pass
 // compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
-// only-thumbv8m.main-none-eabi
-#![feature(cmse_nonsecure_entry)]
-#![no_std]
+// needs-llvm-components: arm
+#![feature(cmse_nonsecure_entry, no_core, lang_items)]
+#![no_core]
+#[lang="sized"]
+trait Sized { }
+#[lang="copy"]
+trait Copy { }
 
 #[no_mangle]
 #[cmse_nonsecure_entry]
-pub extern "C" fn entry_function(a: u32, b: u32, c: u32, d: u32) -> u32 {
-    a + b + c + d
+pub extern "C" fn entry_function(_: u32, _: u32, _: u32, d: u32) -> u32 {
+    d
 }
diff --git a/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs b/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs
index 553d3a8cb0b..74321fdfdde 100644
--- a/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs
+++ b/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs
@@ -1,10 +1,16 @@
+// build-fail
 // compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
-// only-thumbv8m.main-none-eabi
-#![feature(cmse_nonsecure_entry)]
-#![no_std]
+// needs-llvm-components: arm
+// min-llvm-version: 11.0
+#![feature(cmse_nonsecure_entry, no_core, lang_items)]
+#![no_core]
+#[lang="sized"]
+trait Sized { }
+#[lang="copy"]
+trait Copy { }
 
 #[no_mangle]
 #[cmse_nonsecure_entry]
-pub extern "C" fn entry_function(a: u32, b: u32, c: u32, d: u32, e: u32) -> u32 { //~ ERROR
-    a + b + c + d + e
+pub extern "C" fn entry_function(_: u32, _: u32, _: u32, _: u32, e: u32) -> u32 {
+    e
 }
diff --git a/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs b/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs
index 611c8643dcb..6320d296373 100644
--- a/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs
+++ b/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs
@@ -1,10 +1,13 @@
 // compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
-// only-thumbv8m.main-none-eabi
-#![feature(cmse_nonsecure_entry)]
-#![no_std]
+// needs-llvm-components: arm
+#![feature(cmse_nonsecure_entry, no_core, lang_items)]
+#![no_core]
+#[lang="sized"]
+trait Sized { }
 
 #[no_mangle]
 #[cmse_nonsecure_entry]
-pub fn entry_function(a: u32, b: u32, c: u32, d: u32) -> u32 { //~ ERROR [E0776]
-    a + b + c + d
+//~^ ERROR `#[cmse_nonsecure_entry]` requires C ABI [E0776]
+pub fn entry_function(_: u32, _: u32, _: u32, d: u32) -> u32 {
+    d
 }
diff --git a/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr b/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr
index d6967a11e6b..36d76c9674a 100644
--- a/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr
+++ b/src/test/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr
@@ -1,5 +1,5 @@
-error[E0776]: `#[cmse_nonsecure_entry]` functions require C ABI
-  --> $DIR/wrong-abi.rs:7:1
+error[E0776]: `#[cmse_nonsecure_entry]` requires C ABI
+  --> $DIR/wrong-abi.rs:9:1
    |
 LL | #[cmse_nonsecure_entry]
    | ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-37655.rs b/src/test/ui/coercion/issue-37655.rs
index 416854d66f3..416854d66f3 100644
--- a/src/test/ui/issues/issue-37655.rs
+++ b/src/test/ui/coercion/issue-37655.rs
diff --git a/src/test/ui/test-cfg.rs b/src/test/ui/conditional-compilation/test-cfg.rs
index 8750bae0028..8750bae0028 100644
--- a/src/test/ui/test-cfg.rs
+++ b/src/test/ui/conditional-compilation/test-cfg.rs
diff --git a/src/test/ui/test-cfg.stderr b/src/test/ui/conditional-compilation/test-cfg.stderr
index c35fe2f9458..c35fe2f9458 100644
--- a/src/test/ui/test-cfg.stderr
+++ b/src/test/ui/conditional-compilation/test-cfg.stderr
diff --git a/src/test/ui/const-generics/impl-trait-with-const-arguments.full.stderr b/src/test/ui/const-generics/impl-trait-with-const-arguments.full.stderr
index 26b965901a4..ebc8f458f79 100644
--- a/src/test/ui/const-generics/impl-trait-with-const-arguments.full.stderr
+++ b/src/test/ui/const-generics/impl-trait-with-const-arguments.full.stderr
@@ -6,3 +6,4 @@ LL |     assert_eq!(f::<4usize>(Usizable), 20usize);
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0632`.
diff --git a/src/test/ui/const-generics/impl-trait-with-const-arguments.min.stderr b/src/test/ui/const-generics/impl-trait-with-const-arguments.min.stderr
index 26b965901a4..ebc8f458f79 100644
--- a/src/test/ui/const-generics/impl-trait-with-const-arguments.min.stderr
+++ b/src/test/ui/const-generics/impl-trait-with-const-arguments.min.stderr
@@ -6,3 +6,4 @@ LL |     assert_eq!(f::<4usize>(Usizable), 20usize);
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0632`.
diff --git a/src/test/ui/const-generics/issues/issue-83765.rs b/src/test/ui/const-generics/issues/issue-83765.rs
new file mode 100644
index 00000000000..f34badc693e
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-83765.rs
@@ -0,0 +1,38 @@
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+trait TensorDimension {
+    const DIM: usize;
+}
+
+trait TensorSize: TensorDimension {
+    fn size(&self) -> [usize; Self::DIM];
+}
+
+trait Broadcastable: TensorSize + Sized {
+    type Element;
+    fn lazy_updim<const NEWDIM: usize>(&self, size: [usize; NEWDIM]) {}
+}
+
+struct BMap<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> {
+    reference: &'a T,
+    closure: F,
+}
+
+impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorDimension
+    for BMap<'a, R, T, F, DIM>
+{
+    const DIM: usize = DIM;
+}
+impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorSize
+    for BMap<'a, R, T, F, DIM>
+{
+    fn size(&self) -> [usize; DIM] {
+        //~^ ERROR: method not compatible with trait [E0308]
+        self.reference.size()
+        //~^ ERROR: unconstrained generic constant
+        //~| ERROR: mismatched types
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-83765.stderr b/src/test/ui/const-generics/issues/issue-83765.stderr
new file mode 100644
index 00000000000..ef785bf07eb
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-83765.stderr
@@ -0,0 +1,29 @@
+error[E0308]: method not compatible with trait
+  --> $DIR/issue-83765.rs:30:5
+   |
+LL |     fn size(&self) -> [usize; DIM] {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Self::DIM`, found `DIM`
+   |
+   = note: expected type `Self::DIM`
+              found type `DIM`
+
+error: unconstrained generic constant
+  --> $DIR/issue-83765.rs:32:24
+   |
+LL |         self.reference.size()
+   |                        ^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); Self::DIM]:`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-83765.rs:32:9
+   |
+LL |         self.reference.size()
+   |         ^^^^^^^^^^^^^^^^^^^^^ expected `DIM`, found `Self::DIM`
+   |
+   = note: expected type `DIM`
+              found type `Self::DIM`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/issues/issue-85848.rs b/src/test/ui/const-generics/issues/issue-85848.rs
new file mode 100644
index 00000000000..478719869b2
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-85848.rs
@@ -0,0 +1,31 @@
+#![feature(const_generics, const_fn_trait_bound, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+trait _Contains<T> {
+    const does_contain: bool;
+}
+
+trait Contains<T, const Satisfied: bool> {}
+
+trait Delegates<T> {}
+
+impl<T, U> Delegates<U> for T where T: Contains<U, true> {}
+
+const fn contains<A, B>() -> bool
+where
+    A: _Contains<B>,
+{
+    A::does_contain
+}
+
+impl<T, U> Contains<T, { contains::<T, U>() }> for U where T: _Contains<U> {}
+
+fn writes_to_path<C>(cap: &C) {
+    writes_to_specific_path(&cap);
+    //~^ ERROR: the trait bound `(): _Contains<&C>` is not satisfied [E0277]
+    //~| ERROR: unconstrained generic constant
+}
+
+fn writes_to_specific_path<C: Delegates<()>>(cap: &C) {}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-85848.stderr b/src/test/ui/const-generics/issues/issue-85848.stderr
new file mode 100644
index 00000000000..5e65136a6bc
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-85848.stderr
@@ -0,0 +1,44 @@
+error[E0277]: the trait bound `(): _Contains<&C>` is not satisfied
+  --> $DIR/issue-85848.rs:24:5
+   |
+LL |     writes_to_specific_path(&cap);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `_Contains<&C>` is not implemented for `()`
+...
+LL | fn writes_to_specific_path<C: Delegates<()>>(cap: &C) {}
+   |                               ------------- required by this bound in `writes_to_specific_path`
+   |
+note: required because of the requirements on the impl of `Contains<(), true>` for `&C`
+  --> $DIR/issue-85848.rs:21:12
+   |
+LL | impl<T, U> Contains<T, { contains::<T, U>() }> for U where T: _Contains<U> {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     ^
+note: required because of the requirements on the impl of `Delegates<()>` for `&C`
+  --> $DIR/issue-85848.rs:12:12
+   |
+LL | impl<T, U> Delegates<U> for T where T: Contains<U, true> {}
+   |            ^^^^^^^^^^^^     ^
+
+error: unconstrained generic constant
+  --> $DIR/issue-85848.rs:24:5
+   |
+LL |     writes_to_specific_path(&cap);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | fn writes_to_specific_path<C: Delegates<()>>(cap: &C) {}
+   |                               ------------- required by this bound in `writes_to_specific_path`
+   |
+   = help: try adding a `where` bound using this expression: `where [(); { contains::<T, U>() }]:`
+note: required because of the requirements on the impl of `Contains<(), true>` for `&C`
+  --> $DIR/issue-85848.rs:21:12
+   |
+LL | impl<T, U> Contains<T, { contains::<T, U>() }> for U where T: _Contains<U> {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     ^
+note: required because of the requirements on the impl of `Delegates<()>` for `&C`
+  --> $DIR/issue-85848.rs:12:12
+   |
+LL | impl<T, U> Delegates<U> for T where T: Contains<U, true> {}
+   |            ^^^^^^^^^^^^     ^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs
index d845e00694a..ae8863c567d 100644
--- a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs
+++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs
@@ -13,7 +13,7 @@ fn b() {
     //~| ERROR expected trait, found constant `BAR`
     //~| ERROR type provided when a constant was expected
     //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
 }
 fn c() {
     foo::<3 + 3>(); //~ ERROR expressions must be enclosed in braces
diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr
index 857498a1111..b93bd6c6fa0 100644
--- a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr
+++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr
@@ -138,7 +138,7 @@ LL |     foo::<BAR + BAR>();
    |           ^^^^^^^^^ help: use `dyn`: `dyn BAR + BAR`
    |
    = note: `#[warn(bare_trait_objects)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error[E0747]: type provided when a constant was expected
diff --git a/src/test/ui/const-ptr/out_of_bounds_read.rs b/src/test/ui/const-ptr/out_of_bounds_read.rs
new file mode 100644
index 00000000000..c45198cc39b
--- /dev/null
+++ b/src/test/ui/const-ptr/out_of_bounds_read.rs
@@ -0,0 +1,16 @@
+// error-pattern: evaluation of constant value failed
+
+#![feature(const_ptr_read)]
+#![feature(const_ptr_offset)]
+
+fn main() {
+    use std::ptr;
+
+    const DATA: [u32; 1] = [42];
+
+    const PAST_END_PTR: *const u32 = unsafe { DATA.as_ptr().add(1) };
+
+    const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
+    const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
+    const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
+}
diff --git a/src/test/ui/const-ptr/out_of_bounds_read.stderr b/src/test/ui/const-ptr/out_of_bounds_read.stderr
new file mode 100644
index 00000000000..67175d5d1f5
--- /dev/null
+++ b/src/test/ui/const-ptr/out_of_bounds_read.stderr
@@ -0,0 +1,70 @@
+error[E0080]: evaluation of constant value failed
+  --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
+   |
+LL |     unsafe { copy_nonoverlapping(src, dst, count) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              |
+   |              memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
+   |              inside `copy_nonoverlapping::<u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+   | 
+  ::: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |
+LL |         copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+   |         --------------------------------------------- inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   | 
+  ::: $DIR/out_of_bounds_read.rs:13:33
+   |
+LL |     const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
+   |                                 ----------------------- inside `_READ` at $DIR/out_of_bounds_read.rs:13:33
+
+error[E0080]: evaluation of constant value failed
+  --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
+   |
+LL |     unsafe { copy_nonoverlapping(src, dst, count) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              |
+   |              memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
+   |              inside `copy_nonoverlapping::<u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+   | 
+  ::: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |
+LL |         copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+   |         --------------------------------------------- inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   | 
+  ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+   |
+LL |         unsafe { read(self) }
+   |                  ---------- inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+   | 
+  ::: $DIR/out_of_bounds_read.rs:14:39
+   |
+LL |     const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
+   |                                       ------------------- inside `_CONST_READ` at $DIR/out_of_bounds_read.rs:14:39
+
+error[E0080]: evaluation of constant value failed
+  --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
+   |
+LL |     unsafe { copy_nonoverlapping(src, dst, count) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              |
+   |              memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
+   |              inside `copy_nonoverlapping::<u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+   | 
+  ::: $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |
+LL |         copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+   |         --------------------------------------------- inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   | 
+  ::: $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+   |
+LL |         unsafe { read(self) }
+   |                  ---------- inside `ptr::mut_ptr::<impl *mut u32>::read` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+   | 
+  ::: $DIR/out_of_bounds_read.rs:15:37
+   |
+LL |     const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
+   |                                     --------------------------------- inside `_MUT_READ` at $DIR/out_of_bounds_read.rs:15:37
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/ub-upvars.32bit.stderr b/src/test/ui/consts/const-eval/ub-upvars.32bit.stderr
index 17a96386f4b..0818d7fbf88 100644
--- a/src/test/ui/consts/const-eval/ub-upvars.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-upvars.32bit.stderr
@@ -10,7 +10,7 @@ LL | | };
    |
    = 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: 8, align: 4) {
-               ╾─alloc2──╼ ╾─alloc3──╼                         │ ╾──╼╾──╼
+               ╾─alloc2──╼ ╾─alloc5──╼                         │ ╾──╼╾──╼
            }
 
 error: aborting due to previous error
diff --git a/src/test/ui/consts/const-eval/ub-upvars.64bit.stderr b/src/test/ui/consts/const-eval/ub-upvars.64bit.stderr
index 11922e32ae1..59dcf7aefe4 100644
--- a/src/test/ui/consts/const-eval/ub-upvars.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-upvars.64bit.stderr
@@ -10,7 +10,7 @@ LL | | };
    |
    = 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: 16, align: 8) {
-               ╾───────alloc2────────╼ ╾───────alloc3────────╼ │ ╾──────╼╾──────╼
+               ╾───────alloc2────────╼ ╾───────alloc5────────╼ │ ╾──────╼╾──────╼
            }
 
 error: aborting due to previous error
diff --git a/src/test/ui/consts/const-float-classify.rs b/src/test/ui/consts/const-float-classify.rs
index 36fec9976be..95e7f9e9c83 100644
--- a/src/test/ui/consts/const-float-classify.rs
+++ b/src/test/ui/consts/const-float-classify.rs
@@ -53,6 +53,9 @@ impl const PartialEq<NonDet> for bool {
     fn eq(&self, _: &NonDet) -> bool {
         true
     }
+    fn ne(&self, _: &NonDet) -> bool {
+        false
+    }
 }
 
 // The result of the `is_sign` methods are not checked for correctness, since LLVM does not
diff --git a/src/test/ui/consts/copy-intrinsic.rs b/src/test/ui/consts/copy-intrinsic.rs
new file mode 100644
index 00000000000..48d128b10e8
--- /dev/null
+++ b/src/test/ui/consts/copy-intrinsic.rs
@@ -0,0 +1,51 @@
+#![stable(feature = "dummy", since = "1.0.0")]
+
+// ignore-tidy-linelength
+#![feature(intrinsics, staged_api)]
+#![feature(const_mut_refs, const_intrinsic_copy, const_ptr_offset)]
+use std::mem;
+
+extern "rust-intrinsic" {
+    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+    fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+
+    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+    fn copy<T>(src: *const T, dst: *mut T, count: usize);
+}
+
+const COPY_ZERO: () = unsafe {
+    // Since we are not copying anything, this should be allowed.
+    let src = ();
+    let mut dst = ();
+    copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0);
+};
+
+const COPY_OOB_1: () = unsafe {
+    let mut x = 0i32;
+    let dangle = (&mut x as *mut i32).wrapping_add(10);
+    // Even if the first ptr is an int ptr and this is a ZST copy, we should detect dangling 2nd ptrs.
+    copy_nonoverlapping(0x100 as *const i32, dangle, 0); //~ evaluation of constant value failed [E0080]
+};
+const COPY_OOB_2: () = unsafe {
+    let x = 0i32;
+    let dangle = (&x as *const i32).wrapping_add(10);
+    // Even if the second ptr is an int ptr and this is a ZST copy, we should detect dangling 1st ptrs.
+    copy_nonoverlapping(dangle, 0x100 as *mut i32, 0); //~ evaluation of constant value failed [E0080]
+    //~| memory access failed: pointer must be in-bounds
+};
+
+const COPY_SIZE_OVERFLOW: () = unsafe {
+    let x = 0;
+    let mut y = 0;
+    copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1)); //~ evaluation of constant value failed [E0080]
+    //~| overflow computing total size of `copy`
+};
+const COPY_NONOVERLAPPING_SIZE_OVERFLOW: () = unsafe {
+    let x = 0;
+    let mut y = 0;
+    copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1)); //~ evaluation of constant value failed [E0080]
+    //~| overflow computing total size of `copy_nonoverlapping`
+};
+
+fn main() {
+}
diff --git a/src/test/ui/consts/copy-intrinsic.stderr b/src/test/ui/consts/copy-intrinsic.stderr
new file mode 100644
index 00000000000..c1779743e8e
--- /dev/null
+++ b/src/test/ui/consts/copy-intrinsic.stderr
@@ -0,0 +1,27 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/copy-intrinsic.rs:27:5
+   |
+LL |     copy_nonoverlapping(0x100 as *const i32, dangle, 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 40, but is outside bounds of alloc4 which has size 4
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/copy-intrinsic.rs:33:5
+   |
+LL |     copy_nonoverlapping(dangle, 0x100 as *mut i32, 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 40, but is outside bounds of alloc6 which has size 4
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/copy-intrinsic.rs:40:5
+   |
+LL |     copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy`
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/copy-intrinsic.rs:46:5
+   |
+LL |     copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy_nonoverlapping`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/issues/issue-17756.rs b/src/test/ui/consts/issue-17756.rs
index 1835b177ff3..1835b177ff3 100644
--- a/src/test/ui/issues/issue-17756.rs
+++ b/src/test/ui/consts/issue-17756.rs
diff --git a/src/test/ui/issues/issue-69532.rs b/src/test/ui/consts/issue-69532.rs
index 81007b15074..81007b15074 100644
--- a/src/test/ui/issues/issue-69532.rs
+++ b/src/test/ui/consts/issue-69532.rs
diff --git a/src/test/ui/consts/issue-79690.64bit.stderr b/src/test/ui/consts/issue-79690.64bit.stderr
index 57e62d0b90f..cab111ab69c 100644
--- a/src/test/ui/consts/issue-79690.64bit.stderr
+++ b/src/test/ui/consts/issue-79690.64bit.stderr
@@ -6,7 +6,7 @@ LL | const G: Fat = unsafe { Transmute { t: FOO }.u };
    |
    = 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: 16, align: 8) {
-               ╾───────alloc2────────╼ ╾───────alloc3────────╼ │ ╾──────╼╾──────╼
+               ╾───────alloc2────────╼ ╾───────alloc5────────╼ │ ╾──────╼╾──────╼
            }
 
 error: aborting due to previous error
diff --git a/src/test/ui/consts/large_const_alloc.rs b/src/test/ui/consts/large_const_alloc.rs
new file mode 100644
index 00000000000..54abaab2247
--- /dev/null
+++ b/src/test/ui/consts/large_const_alloc.rs
@@ -0,0 +1,18 @@
+// only-64bit
+// on 32bit and 16bit platforms it is plausible that the maximum allocation size will succeed
+
+const FOO: () = {
+    // 128 TiB, unlikely anyone has that much RAM
+    let x = [0_u8; (1 << 47) - 1];
+    //~^ ERROR evaluation of constant value failed
+};
+
+static FOO2: () = {
+    let x = [0_u8; (1 << 47) - 1];
+    //~^ ERROR could not evaluate static initializer
+};
+
+fn main() {
+    let _ = FOO;
+    let _ = FOO2;
+}
diff --git a/src/test/ui/consts/large_const_alloc.stderr b/src/test/ui/consts/large_const_alloc.stderr
new file mode 100644
index 00000000000..25d660f1217
--- /dev/null
+++ b/src/test/ui/consts/large_const_alloc.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/large_const_alloc.rs:6:13
+   |
+LL |     let x = [0_u8; (1 << 47) - 1];
+   |             ^^^^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler
+
+error[E0080]: could not evaluate static initializer
+  --> $DIR/large_const_alloc.rs:11:13
+   |
+LL |     let x = [0_u8; (1 << 47) - 1];
+   |             ^^^^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr
index 5374088028b..e6db2eef955 100644
--- a/src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr
+++ b/src/test/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr
@@ -19,7 +19,7 @@ LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
    |
    = 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: 8, align: 4) {
-               ╾─alloc6──╼ ╾─alloc7──╼                         │ ╾──╼╾──╼
+               ╾─alloc6──╼ ╾─alloc8──╼                         │ ╾──╼╾──╼
            }
 
 error[E0080]: it is undefined behavior to use this value
diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr
index 7c4842db24c..f48978d4af6 100644
--- a/src/test/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr
+++ b/src/test/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr
@@ -19,7 +19,7 @@ LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
    |
    = 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: 16, align: 8) {
-               ╾───────alloc6────────╼ ╾───────alloc7────────╼ │ ╾──────╼╾──────╼
+               ╾───────alloc6────────╼ ╾───────alloc8────────╼ │ ╾──────╼╾──────╼
            }
 
 error[E0080]: it is undefined behavior to use this value
diff --git a/src/test/ui/crate-loading/missing-std.rs b/src/test/ui/crate-loading/missing-std.rs
index 442a7c01e5a..de4ccc18560 100644
--- a/src/test/ui/crate-loading/missing-std.rs
+++ b/src/test/ui/crate-loading/missing-std.rs
@@ -1,4 +1,5 @@
 // compile-flags: --target x86_64-unknown-uefi
+// needs-llvm-components: x86
 // rustc-env:CARGO=/usr/bin/cargo
 // rustc-env:RUSTUP_HOME=/home/bors/.rustup
 #![no_core]
diff --git a/src/test/ui/crate-loading/missing-std.stderr b/src/test/ui/crate-loading/missing-std.stderr
index 25808efdfa6..e61486fdc6f 100644
--- a/src/test/ui/crate-loading/missing-std.stderr
+++ b/src/test/ui/crate-loading/missing-std.stderr
@@ -1,5 +1,5 @@
 error[E0463]: can't find crate for `core`
-  --> $DIR/missing-std.rs:5:1
+  --> $DIR/missing-std.rs:6:1
    |
 LL | extern crate core;
    | ^^^^^^^^^^^^^^^^^^ can't find crate
diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed
index 4bbec203c4e..c815080fc4a 100644
--- a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed
+++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed
@@ -13,27 +13,27 @@
 mod outer_mod {
     pub mod r#dyn {
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
         pub struct r#dyn;
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
     }
 }
 use outer_mod::r#dyn::r#dyn;
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 //~| ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 
 fn main() {
     match r#dyn { r#dyn => {} }
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 //~| ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
     macro_defn::r#dyn();
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 
     macro_defn::boxed();
 }
@@ -43,7 +43,7 @@ mod macro_defn {
 
     macro_rules! r#dyn {
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 
         // Note that we do not lint nor fix occurrences under macros
         ($dyn:tt) => { (Box<dyn Trait>, Box<$dyn Trait>) }
@@ -51,23 +51,23 @@ mod macro_defn {
 
     pub fn r#dyn() -> ::outer_mod::r#dyn::r#dyn {
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 //~| ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 //~| ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
         ::outer_mod::r#dyn::r#dyn
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 //~| ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
     }
 
 
 
     pub fn boxed() -> r#dyn!(
         //~^ ERROR `dyn` is a keyword
-        //~| WARN was previously accepted
+        //~| WARN this is accepted in the current edition
 
             // Note that we do not lint nor fix occurrences under macros
             dyn
diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs
index bc1dd4d1d08..6cdc7071494 100644
--- a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs
+++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs
@@ -13,27 +13,27 @@
 mod outer_mod {
     pub mod dyn {
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
         pub struct dyn;
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
     }
 }
 use outer_mod::dyn::dyn;
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 //~| ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 
 fn main() {
     match dyn { dyn => {} }
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 //~| ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
     macro_defn::dyn();
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 
     macro_defn::boxed();
 }
@@ -43,7 +43,7 @@ mod macro_defn {
 
     macro_rules! dyn {
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 
         // Note that we do not lint nor fix occurrences under macros
         ($dyn:tt) => { (Box<dyn Trait>, Box<$dyn Trait>) }
@@ -51,23 +51,23 @@ mod macro_defn {
 
     pub fn dyn() -> ::outer_mod::dyn::dyn {
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 //~| ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 //~| ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
         ::outer_mod::dyn::dyn
 //~^ ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
 //~| ERROR `dyn` is a keyword
-//~| WARN was previously accepted
+//~| WARN this is accepted in the current edition
     }
 
 
 
     pub fn boxed() -> dyn!(
         //~^ ERROR `dyn` is a keyword
-        //~| WARN was previously accepted
+        //~| WARN this is accepted in the current edition
 
             // Note that we do not lint nor fix occurrences under macros
             dyn
diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr
index 32d690fa563..3eb5bb7b26d 100644
--- a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr
+++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(keyword_idents)]
    |         ^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -18,7 +18,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL |         pub struct dyn;
    |                    ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -27,7 +27,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL | use outer_mod::dyn::dyn;
    |                ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -36,7 +36,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL | use outer_mod::dyn::dyn;
    |                     ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -45,7 +45,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL |     match dyn { dyn => {} }
    |           ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -54,7 +54,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL |     match dyn { dyn => {} }
    |                 ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -63,7 +63,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL |     macro_defn::dyn();
    |                 ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -72,7 +72,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL |     macro_rules! dyn {
    |                  ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -81,7 +81,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL |     pub fn dyn() -> ::outer_mod::dyn::dyn {
    |            ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -90,7 +90,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL |     pub fn dyn() -> ::outer_mod::dyn::dyn {
    |                                  ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -99,7 +99,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL |     pub fn dyn() -> ::outer_mod::dyn::dyn {
    |                                       ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -108,7 +108,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL |         ::outer_mod::dyn::dyn
    |                      ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -117,7 +117,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL |         ::outer_mod::dyn::dyn
    |                           ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `dyn` is a keyword in the 2018 edition
@@ -126,7 +126,7 @@ error: `dyn` is a keyword in the 2018 edition
 LL |     pub fn boxed() -> dyn!(
    |                       ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: aborting due to 14 previous errors
diff --git a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.rs b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.rs
index 7c2babaf7ab..23ca36b71e0 100644
--- a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.rs
+++ b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.rs
@@ -3,12 +3,12 @@
 
 fn function(x: &SomeTrait, y: Box<SomeTrait>) {
     //~^ ERROR trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted
+    //~| WARN this is accepted in the current edition
     //~| ERROR trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted
+    //~| WARN this is accepted in the current edition
     let _x: &SomeTrait = todo!();
     //~^ ERROR trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted
+    //~| WARN this is accepted in the current edition
 }
 
 trait SomeTrait {}
diff --git a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr
index ea73e56d843..30f09e22792 100644
--- a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr
+++ b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #[deny(bare_trait_objects)]
    |        ^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: trait objects without an explicit `dyn` are deprecated
@@ -18,7 +18,7 @@ error: trait objects without an explicit `dyn` are deprecated
 LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
    |                                   ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: trait objects without an explicit `dyn` are deprecated
@@ -27,7 +27,7 @@ error: trait objects without an explicit `dyn` are deprecated
 LL |     let _x: &SomeTrait = todo!();
    |              ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/editions/edition-raw-pointer-method-2015.rs b/src/test/ui/editions/edition-raw-pointer-method-2015.rs
index 3631415fc5f..fcfe493c1a2 100644
--- a/src/test/ui/editions/edition-raw-pointer-method-2015.rs
+++ b/src/test/ui/editions/edition-raw-pointer-method-2015.rs
@@ -8,5 +8,5 @@ fn main() {
     let y = &x as *const _;
     let _ = y.is_null();
     //~^ error: type annotations needed [tyvar_behind_raw_pointer]
-    //~^^ warning: this was previously accepted
+    //~^^ warning: this is accepted in the current edition
 }
diff --git a/src/test/ui/editions/edition-raw-pointer-method-2015.stderr b/src/test/ui/editions/edition-raw-pointer-method-2015.stderr
index 1df582ee06c..417daf36fca 100644
--- a/src/test/ui/editions/edition-raw-pointer-method-2015.stderr
+++ b/src/test/ui/editions/edition-raw-pointer-method-2015.stderr
@@ -10,7 +10,7 @@ note: the lint level is defined here
 LL | #[deny(warnings)]
    |        ^^^^^^^^
    = note: `#[deny(tyvar_behind_raw_pointer)]` implied by `#[deny(warnings)]`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>
 
 error: aborting due to previous error
diff --git a/src/test/ui/extern/extern-main-issue-86110.rs b/src/test/ui/extern/extern-main-issue-86110.rs
new file mode 100644
index 00000000000..83af7a14ccc
--- /dev/null
+++ b/src/test/ui/extern/extern-main-issue-86110.rs
@@ -0,0 +1,7 @@
+// missing and missing2 exist to make sure that the error only happens on a `main` declaration
+extern "C" {
+    fn missing();
+    fn main();
+    //~^ the `main` function cannot be declared in an `extern` block
+    fn missing2();
+}
diff --git a/src/test/ui/extern/extern-main-issue-86110.stderr b/src/test/ui/extern/extern-main-issue-86110.stderr
new file mode 100644
index 00000000000..cd3de227dcf
--- /dev/null
+++ b/src/test/ui/extern/extern-main-issue-86110.stderr
@@ -0,0 +1,8 @@
+error: the `main` function cannot be declared in an `extern` block
+  --> $DIR/extern-main-issue-86110.rs:4:5
+   |
+LL |     fn main();
+   |     ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/extern/extern-types-distinct-types.stderr b/src/test/ui/extern/extern-types-distinct-types.stderr
index 32b45ee10ad..f69629232ae 100644
--- a/src/test/ui/extern/extern-types-distinct-types.stderr
+++ b/src/test/ui/extern/extern-types-distinct-types.stderr
@@ -6,6 +6,8 @@ LL |     type A;
 LL |     type B;
    |     ------- the expected foreign type
 ...
+LL | fn foo(r: &A) -> &B {
+   |                  -- expected `&B` because of return type
 LL |     r
    |     ^ expected extern type `B`, found extern type `A`
    |
diff --git a/src/test/ui/future-incompatible-lint-group.rs b/src/test/ui/future-incompatible-lint-group.rs
index 3630f08c937..bbd0e33d719 100644
--- a/src/test/ui/future-incompatible-lint-group.rs
+++ b/src/test/ui/future-incompatible-lint-group.rs
@@ -1,8 +1,18 @@
+// Ensure that the future_incompatible lint group only includes
+// lints for changes that are not tied to an edition
 #![deny(future_incompatible)]
 
 trait Tr {
-    fn f(u8) {} //~ ERROR anonymous parameters are deprecated
-                //~^ WARN this was previously accepted
+    // Warn only since this is not a `future_incompatible` lint
+    fn f(u8) {} //~ WARN anonymous parameters are deprecated
+                //~| WARN this is accepted in the current edition
+}
+
+pub mod submodule {
+    // Error since this is a `future_incompatible` lint
+    #![doc(test(some_test))]
+        //~^ ERROR this attribute can only be applied at the crate level
+        //~| WARN this was previously accepted by the compiler
 }
 
 fn main() {}
diff --git a/src/test/ui/future-incompatible-lint-group.stderr b/src/test/ui/future-incompatible-lint-group.stderr
index a19051e8bc0..cb9be88c9ee 100644
--- a/src/test/ui/future-incompatible-lint-group.stderr
+++ b/src/test/ui/future-incompatible-lint-group.stderr
@@ -1,17 +1,28 @@
-error: anonymous parameters are deprecated and will be removed in the next edition.
-  --> $DIR/future-incompatible-lint-group.rs:4:10
+warning: anonymous parameters are deprecated and will be removed in the next edition.
+  --> $DIR/future-incompatible-lint-group.rs:7:10
    |
 LL |     fn f(u8) {}
    |          ^^ help: try naming the parameter or explicitly ignoring it: `_: u8`
    |
+   = note: `#[warn(anonymous_parameters)]` on by default
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
+   = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
+
+error: this attribute can only be applied at the crate level
+  --> $DIR/future-incompatible-lint-group.rs:13:12
+   |
+LL |     #![doc(test(some_test))]
+   |            ^^^^^^^^^^^^^^^
+   |
 note: the lint level is defined here
-  --> $DIR/future-incompatible-lint-group.rs:1:9
+  --> $DIR/future-incompatible-lint-group.rs:3:9
    |
 LL | #![deny(future_incompatible)]
    |         ^^^^^^^^^^^^^^^^^^^
-   = note: `#[deny(anonymous_parameters)]` implied by `#[deny(future_incompatible)]`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
+   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(future_incompatible)]`
+   = 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 #82730 <https://github.com/rust-lang/rust/issues/82730>
+   = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information
 
-error: aborting due to previous error
+error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/generic-associated-types/collections-project-default.rs b/src/test/ui/generic-associated-types/collections-project-default.rs
index 5fbae02573c..65541fc3ae6 100644
--- a/src/test/ui/generic-associated-types/collections-project-default.rs
+++ b/src/test/ui/generic-associated-types/collections-project-default.rs
@@ -3,7 +3,7 @@
 #![feature(associated_type_defaults)]
 
 // A Collection trait and collection families. Based on
-// http://smallcultfollowing.com/babysteps/blog/2016/11/03/
+// https://smallcultfollowing.com/babysteps/blog/2016/11/03/
 // associated-type-constructors-part-2-family-traits/
 
 // check that we don't normalize with trait defaults.
diff --git a/src/test/ui/generic-associated-types/collections.rs b/src/test/ui/generic-associated-types/collections.rs
index 1b5b9c181fb..4e8f593c1fd 100644
--- a/src/test/ui/generic-associated-types/collections.rs
+++ b/src/test/ui/generic-associated-types/collections.rs
@@ -3,7 +3,7 @@
 #![feature(associated_type_defaults)]
 
 // A Collection trait and collection families. Based on
-// http://smallcultfollowing.com/babysteps/blog/2016/11/03/
+// https://smallcultfollowing.com/babysteps/blog/2016/11/03/
 // associated-type-constructors-part-2-family-traits/
 
 // run-pass
diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
index f1af6860284..b656382bced 100644
--- a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
+++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
@@ -11,6 +11,6 @@ fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
   //~| ERROR this associated type takes 0 generic arguments but 1 generic argument
   //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
   //~| WARNING: trait objects without an explicit `dyn` are deprecated
-  //~| WARNING: this was previously accepted by the compiler
+  //~| WARNING: this is accepted in the current edition
 
 fn main() {}
diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
index 400600a086c..34554d38520 100644
--- a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
+++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
@@ -26,7 +26,7 @@ LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
    |                             ^^ help: use `dyn`: `dyn 'a`
    |
    = note: `#[warn(bare_trait_objects)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
diff --git a/src/test/ui/generic-associated-types/issue-86483.rs b/src/test/ui/generic-associated-types/issue-86483.rs
new file mode 100644
index 00000000000..9d03c9dab8d
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-86483.rs
@@ -0,0 +1,15 @@
+// Regression test of #86483.
+
+#![feature(generic_associated_types)]
+#![allow(incomplete_features)]
+
+pub trait IceIce<T> //~ ERROR: the parameter type `T` may not live long enough
+where
+    for<'a> T: 'a,
+{
+    type Ice<'v>: IntoIterator<Item = &'v T>;
+    //~^ ERROR: the parameter type `T` may not live long enough
+    //~| ERROR: the parameter type `T` may not live long enough
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-86483.stderr b/src/test/ui/generic-associated-types/issue-86483.stderr
new file mode 100644
index 00000000000..c8efc2ed882
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-86483.stderr
@@ -0,0 +1,36 @@
+error[E0311]: the parameter type `T` may not live long enough
+  --> $DIR/issue-86483.rs:6:1
+   |
+LL |   pub trait IceIce<T>
+   |   ^                - help: consider adding an explicit lifetime bound...: `T: 'a`
+   |  _|
+   | |
+LL | | where
+LL | |     for<'a> T: 'a,
+LL | | {
+...  |
+LL | |
+LL | | }
+   | |_^ ...so that the type `T` will meet its required lifetime bounds
+
+error[E0311]: the parameter type `T` may not live long enough
+  --> $DIR/issue-86483.rs:10:5
+   |
+LL | pub trait IceIce<T>
+   |                  - help: consider adding an explicit lifetime bound...: `T: 'a`
+...
+LL |     type Ice<'v>: IntoIterator<Item = &'v T>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/issue-86483.rs:10:32
+   |
+LL | pub trait IceIce<T>
+   |                  - help: consider adding an explicit lifetime bound...: `T: 'v`
+...
+LL |     type Ice<'v>: IntoIterator<Item = &'v T>;
+   |                                ^^^^^^^^^^^^ ...so that the reference type `&'v T` does not outlive the data it points at
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/impl-trait/issues/universal-issue-48703.stderr b/src/test/ui/impl-trait/issues/universal-issue-48703.stderr
index 8f05ab3c494..6800b37b5b1 100644
--- a/src/test/ui/impl-trait/issues/universal-issue-48703.stderr
+++ b/src/test/ui/impl-trait/issues/universal-issue-48703.stderr
@@ -6,3 +6,4 @@ LL |     foo::<String>('a');
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0632`.
diff --git a/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr b/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr
index c980e9463e4..db66d461095 100644
--- a/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr
+++ b/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr
@@ -8,3 +8,4 @@ LL |     evt.handle_event::<TestEvent, fn(TestEvent)>(|_evt| {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0632`.
diff --git a/src/test/ui/inference/inference-variable-behind-raw-pointer.rs b/src/test/ui/inference/inference-variable-behind-raw-pointer.rs
index 1d508e8e820..6662e46b1c7 100644
--- a/src/test/ui/inference/inference-variable-behind-raw-pointer.rs
+++ b/src/test/ui/inference/inference-variable-behind-raw-pointer.rs
@@ -7,5 +7,5 @@ fn main() {
     let _ = &data as *const *const ();
     if data.is_null() {}
     //~^ WARNING type annotations needed
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~| WARNING this is accepted in the current edition
 }
diff --git a/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr b/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr
index 12848982b8d..c38f57912ad 100644
--- a/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr
+++ b/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr
@@ -5,7 +5,7 @@ LL |     if data.is_null() {}
    |             ^^^^^^^
    |
    = note: `#[warn(tyvar_behind_raw_pointer)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>
 
 warning: 1 warning emitted
diff --git a/src/test/ui/inference/issue-70703.rs b/src/test/ui/inference/issue-70703.rs
new file mode 100644
index 00000000000..d90498e96ea
--- /dev/null
+++ b/src/test/ui/inference/issue-70703.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+trait Factory {
+    type Product;
+}
+
+impl Factory for () {
+    type Product = ();
+}
+
+trait ProductConsumer<P> {
+    fn consume(self, product: P);
+}
+
+impl<P> ProductConsumer<P> for () {
+    fn consume(self, _: P) {}
+}
+
+fn make_product_consumer<F: Factory>(_: F) -> impl ProductConsumer<F::Product> {
+    ()
+}
+
+fn main() {
+    let consumer = make_product_consumer(());
+    consumer.consume(());
+}
diff --git a/src/test/ui/non-integer-atomic.rs b/src/test/ui/intrinsics/non-integer-atomic.rs
index 00a7f368a0f..00a7f368a0f 100644
--- a/src/test/ui/non-integer-atomic.rs
+++ b/src/test/ui/intrinsics/non-integer-atomic.rs
diff --git a/src/test/ui/non-integer-atomic.stderr b/src/test/ui/intrinsics/non-integer-atomic.stderr
index ee485c21cd6..ee485c21cd6 100644
--- a/src/test/ui/non-integer-atomic.stderr
+++ b/src/test/ui/intrinsics/non-integer-atomic.stderr
diff --git a/src/test/ui/invalid-compile-flags/codegen-option-without-group.rs b/src/test/ui/invalid-compile-flags/codegen-option-without-group.rs
new file mode 100644
index 00000000000..7bbf47a3839
--- /dev/null
+++ b/src/test/ui/invalid-compile-flags/codegen-option-without-group.rs
@@ -0,0 +1 @@
+// compile-flags: --llvm-args
diff --git a/src/test/ui/invalid-compile-flags/codegen-option-without-group.stderr b/src/test/ui/invalid-compile-flags/codegen-option-without-group.stderr
new file mode 100644
index 00000000000..c5a0c29cad9
--- /dev/null
+++ b/src/test/ui/invalid-compile-flags/codegen-option-without-group.stderr
@@ -0,0 +1,2 @@
+error: Unrecognized option: 'llvm-args'. Did you mean `-C llvm-args`?
+
diff --git a/src/test/ui/invalid-compile-flags/debug-option-without-group.rs b/src/test/ui/invalid-compile-flags/debug-option-without-group.rs
new file mode 100644
index 00000000000..86e40c17854
--- /dev/null
+++ b/src/test/ui/invalid-compile-flags/debug-option-without-group.rs
@@ -0,0 +1 @@
+// compile-flags: --unpretty=hir
diff --git a/src/test/ui/invalid-compile-flags/debug-option-without-group.stderr b/src/test/ui/invalid-compile-flags/debug-option-without-group.stderr
new file mode 100644
index 00000000000..0e57e31ad3d
--- /dev/null
+++ b/src/test/ui/invalid-compile-flags/debug-option-without-group.stderr
@@ -0,0 +1,2 @@
+error: Unrecognized option: 'unpretty'. Did you mean `-Z unpretty`?
+
diff --git a/src/test/ui/issues/issue-51714.rs b/src/test/ui/issues/issue-51714.rs
index 0dc588d75c6..8716524d6f4 100644
--- a/src/test/ui/issues/issue-51714.rs
+++ b/src/test/ui/issues/issue-51714.rs
@@ -1,13 +1,21 @@
 fn main() {
+//~^ NOTE: not the enclosing function body
+//~| NOTE: not the enclosing function body
+//~| NOTE: not the enclosing function body
+//~| NOTE: not the enclosing function body
     |_:  [_; return || {}] | {};
-    //~^ ERROR return statement outside of function body
+    //~^ ERROR: return statement outside of function body [E0572]
+    //~| NOTE: the return is part of this body...
 
     [(); return || {}];
-    //~^ ERROR return statement outside of function body
+    //~^ ERROR: return statement outside of function body [E0572]
+    //~| NOTE: the return is part of this body...
 
     [(); return |ice| {}];
-    //~^ ERROR return statement outside of function body
+    //~^ ERROR: return statement outside of function body [E0572]
+    //~| NOTE: the return is part of this body...
 
     [(); return while let Some(n) = Some(0) {}];
-    //~^ ERROR return statement outside of function body
+    //~^ ERROR: return statement outside of function body [E0572]
+    //~| NOTE: the return is part of this body...
 }
diff --git a/src/test/ui/issues/issue-51714.stderr b/src/test/ui/issues/issue-51714.stderr
index 023d9013ab4..514d69c1c7d 100644
--- a/src/test/ui/issues/issue-51714.stderr
+++ b/src/test/ui/issues/issue-51714.stderr
@@ -1,26 +1,62 @@
 error[E0572]: return statement outside of function body
-  --> $DIR/issue-51714.rs:2:14
+  --> $DIR/issue-51714.rs:6:14
    |
-LL |     |_:  [_; return || {}] | {};
-   |              ^^^^^^^^^^^^
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+LL | |
+LL | |     |_:  [_; return || {}] | {};
+   | |              ^^^^^^^^^^^^ the return is part of this body...
+...  |
+LL | |
+LL | | }
+   | |_- ...not the enclosing function body
 
 error[E0572]: return statement outside of function body
-  --> $DIR/issue-51714.rs:5:10
+  --> $DIR/issue-51714.rs:10:10
    |
-LL |     [(); return || {}];
-   |          ^^^^^^^^^^^^
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     [(); return || {}];
+   | |          ^^^^^^^^^^^^ the return is part of this body...
+...  |
+LL | |
+LL | | }
+   | |_- ...not the enclosing function body
 
 error[E0572]: return statement outside of function body
-  --> $DIR/issue-51714.rs:8:10
+  --> $DIR/issue-51714.rs:14:10
    |
-LL |     [(); return |ice| {}];
-   |          ^^^^^^^^^^^^^^^
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     [(); return |ice| {}];
+   | |          ^^^^^^^^^^^^^^^ the return is part of this body...
+...  |
+LL | |
+LL | | }
+   | |_- ...not the enclosing function body
 
 error[E0572]: return statement outside of function body
-  --> $DIR/issue-51714.rs:11:10
+  --> $DIR/issue-51714.rs:18:10
    |
-LL |     [(); return while let Some(n) = Some(0) {}];
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     [(); return while let Some(n) = Some(0) {}];
+   | |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body...
+LL | |
+LL | |
+LL | | }
+   | |_- ...not the enclosing function body
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/iterators/into-iter-on-arrays-2018.rs b/src/test/ui/iterators/into-iter-on-arrays-2018.rs
index 5661397b3c1..e56c2956a69 100644
--- a/src/test/ui/iterators/into-iter-on-arrays-2018.rs
+++ b/src/test/ui/iterators/into-iter-on-arrays-2018.rs
@@ -12,12 +12,12 @@ fn main() {
     // Before 2021, the method dispatched to `IntoIterator for &[T; N]`,
     // which we continue to support for compatibility.
     let _: Iter<'_, i32> = array.into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
 
     let _: Iter<'_, i32> = Box::new(array).into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
 
     // The `array_into_iter` lint doesn't cover other wrappers that deref to an array.
     let _: Iter<'_, i32> = Rc::new(array).into_iter();
@@ -25,6 +25,10 @@ fn main() {
 
     // But you can always use the trait method explicitly as an array.
     let _: IntoIter<i32, 10> = IntoIterator::into_iter(array);
+
+    for _ in [1, 2, 3].into_iter() {}
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
 }
 
 /// User type that dereferences to an array.
diff --git a/src/test/ui/iterators/into-iter-on-arrays-2018.stderr b/src/test/ui/iterators/into-iter-on-arrays-2018.stderr
index b43338382f2..3bd3ca6e875 100644
--- a/src/test/ui/iterators/into-iter-on-arrays-2018.stderr
+++ b/src/test/ui/iterators/into-iter-on-arrays-2018.stderr
@@ -1,42 +1,54 @@
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
   --> $DIR/into-iter-on-arrays-2018.rs:14:34
    |
 LL |     let _: Iter<'_, i32> = array.into_iter();
-   |                                  ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+   |                                  ^^^^^^^^^
    |
    = note: `#[warn(array_into_iter)]` 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!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
+   |
+LL |     let _: Iter<'_, i32> = array.iter();
+   |                                  ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
+   |
+LL |     let _: Iter<'_, i32> = IntoIterator::into_iter(array);
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^     ^
 
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
   --> $DIR/into-iter-on-arrays-2018.rs:18:44
    |
 LL |     let _: Iter<'_, i32> = Box::new(array).into_iter();
-   |                                            ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+   |                                            ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-warning: 2 warnings emitted
-
-Future incompatibility report: Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-2018.rs:14:34
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     let _: Iter<'_, i32> = array.into_iter();
-   |                                  ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     let _: Iter<'_, i32> = Box::new(array).iter();
+   |                                            ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-   = note: `#[warn(array_into_iter)]` 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     let _: Iter<'_, i32> = IntoIterator::into_iter(Box::new(array));
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^               ^
 
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-2018.rs:18:44
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-2018.rs:29:24
    |
-LL |     let _: Iter<'_, i32> = Box::new(array).into_iter();
-   |                                            ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     for _ in [1, 2, 3].into_iter() {}
+   |                        ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
+   |
+LL |     for _ in [1, 2, 3].iter() {}
+   |                        ^^^^
+help: or remove `.into_iter()` to iterate by value
+   |
+LL |     for _ in [1, 2, 3] {}
+   |                      --
+
+warning: 3 warnings emitted
 
diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.fixed b/src/test/ui/iterators/into-iter-on-arrays-lint.fixed
index 7f511bde3cb..0055758a6a4 100644
--- a/src/test/ui/iterators/into-iter-on-arrays-lint.fixed
+++ b/src/test/ui/iterators/into-iter-on-arrays-lint.fixed
@@ -1,5 +1,6 @@
 // run-pass
 // run-rustfix
+// rustfix-only-machine-applicable
 
 fn main() {
     let small = [1, 2];
@@ -7,43 +8,43 @@ fn main() {
 
     // Expressions that should trigger the lint
     small.iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     [1, 2].iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     big.iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     [0u8; 33].iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
 
     Box::new(small).iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     Box::new([1, 2]).iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     Box::new(big).iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     Box::new([0u8; 33]).iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
 
     Box::new(Box::new(small)).iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     Box::new(Box::new([1, 2])).iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     Box::new(Box::new(big)).iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     Box::new(Box::new([0u8; 33])).iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
 
     // Expressions that should not
     (&[1, 2]).into_iter();
diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.rs b/src/test/ui/iterators/into-iter-on-arrays-lint.rs
index d5fe83a7834..01857c78a73 100644
--- a/src/test/ui/iterators/into-iter-on-arrays-lint.rs
+++ b/src/test/ui/iterators/into-iter-on-arrays-lint.rs
@@ -1,5 +1,6 @@
 // run-pass
 // run-rustfix
+// rustfix-only-machine-applicable
 
 fn main() {
     let small = [1, 2];
@@ -7,43 +8,43 @@ fn main() {
 
     // Expressions that should trigger the lint
     small.into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     [1, 2].into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     big.into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     [0u8; 33].into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
 
     Box::new(small).into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     Box::new([1, 2]).into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     Box::new(big).into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     Box::new([0u8; 33]).into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
 
     Box::new(Box::new(small)).into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     Box::new(Box::new([1, 2])).into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     Box::new(Box::new(big)).into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
     Box::new(Box::new([0u8; 33])).into_iter();
-    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
-    //~| WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING this method call resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this changes meaning
 
     // Expressions that should not
     (&[1, 2]).into_iter();
diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.stderr b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr
index 211315c3fcf..01789e0e257 100644
--- a/src/test/ui/iterators/into-iter-on-arrays-lint.stderr
+++ b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr
@@ -1,247 +1,207 @@
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:9:11
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-lint.rs:10:11
    |
 LL |     small.into_iter();
-   |           ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+   |           ^^^^^^^^^
    |
    = note: `#[warn(array_into_iter)]` 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!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:12:12
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     [1, 2].into_iter();
-   |            ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     small.iter();
+   |           ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     IntoIterator::into_iter(small);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^     ^
 
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:15:9
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-lint.rs:13:12
    |
-LL |     big.into_iter();
-   |         ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     [1, 2].into_iter();
+   |            ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:18:15
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     [0u8; 33].into_iter();
-   |               ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     [1, 2].iter();
+   |            ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     IntoIterator::into_iter([1, 2]);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^      ^
 
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:22:21
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-lint.rs:16:9
    |
-LL |     Box::new(small).into_iter();
-   |                     ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     big.into_iter();
+   |         ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:25:22
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     Box::new([1, 2]).into_iter();
-   |                      ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     big.iter();
+   |         ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     IntoIterator::into_iter(big);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^   ^
 
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:28:19
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-lint.rs:19:15
    |
-LL |     Box::new(big).into_iter();
-   |                   ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
-   |
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:31:25
-   |
-LL |     Box::new([0u8; 33]).into_iter();
-   |                         ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     [0u8; 33].into_iter();
+   |               ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:35:31
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     Box::new(Box::new(small)).into_iter();
-   |                               ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     [0u8; 33].iter();
+   |               ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     IntoIterator::into_iter([0u8; 33]);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^         ^
 
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:38:32
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-lint.rs:23:21
    |
-LL |     Box::new(Box::new([1, 2])).into_iter();
-   |                                ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new(small).into_iter();
+   |                     ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:41:29
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     Box::new(Box::new(big)).into_iter();
-   |                             ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new(small).iter();
+   |                     ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     IntoIterator::into_iter(Box::new(small));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^               ^
 
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:44:35
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-lint.rs:26:22
    |
-LL |     Box::new(Box::new([0u8; 33])).into_iter();
-   |                                   ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new([1, 2]).into_iter();
+   |                      ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-warning: 12 warnings emitted
-
-Future incompatibility report: Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:9:11
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     small.into_iter();
-   |           ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new([1, 2]).iter();
+   |                      ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-   = note: `#[warn(array_into_iter)]` 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     IntoIterator::into_iter(Box::new([1, 2]));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^                ^
 
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:12:12
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-lint.rs:29:19
    |
-LL |     [1, 2].into_iter();
-   |            ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new(big).into_iter();
+   |                   ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:15:9
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     big.into_iter();
-   |         ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new(big).iter();
+   |                   ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     IntoIterator::into_iter(Box::new(big));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^             ^
 
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:18:15
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-lint.rs:32:25
    |
-LL |     [0u8; 33].into_iter();
-   |               ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new([0u8; 33]).into_iter();
+   |                         ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:22:21
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     Box::new(small).into_iter();
-   |                     ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new([0u8; 33]).iter();
+   |                         ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     IntoIterator::into_iter(Box::new([0u8; 33]));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^                   ^
 
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:25:22
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-lint.rs:36:31
    |
-LL |     Box::new([1, 2]).into_iter();
-   |                      ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new(Box::new(small)).into_iter();
+   |                               ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:28:19
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     Box::new(big).into_iter();
-   |                   ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new(Box::new(small)).iter();
+   |                               ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     IntoIterator::into_iter(Box::new(Box::new(small)));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^                         ^
 
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:31:25
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-lint.rs:39:32
    |
-LL |     Box::new([0u8; 33]).into_iter();
-   |                         ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new(Box::new([1, 2])).into_iter();
+   |                                ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:35:31
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     Box::new(Box::new(small)).into_iter();
-   |                               ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new(Box::new([1, 2])).iter();
+   |                                ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     IntoIterator::into_iter(Box::new(Box::new([1, 2])));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^                          ^
 
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:38:32
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-lint.rs:42:29
    |
-LL |     Box::new(Box::new([1, 2])).into_iter();
-   |                                ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new(Box::new(big)).into_iter();
+   |                             ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:41:29
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     Box::new(Box::new(big)).into_iter();
-   |                             ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new(Box::new(big)).iter();
+   |                             ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     IntoIterator::into_iter(Box::new(Box::new(big)));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^                       ^
 
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:44:35
+warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <[T; N] as IntoIterator>::into_iter in Rust 2021.
+  --> $DIR/into-iter-on-arrays-lint.rs:45:35
    |
 LL |     Box::new(Box::new([0u8; 33])).into_iter();
-   |                                   ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+   |                                   ^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = warning: this changes meaning in Rust 2021
    = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
-
-Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/into-iter-on-arrays-lint.rs:60:12
+help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
    |
-LL |     [0, 1].into_iter();
-   |            ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+LL |     Box::new(Box::new([0u8; 33])).iter();
+   |                                   ^^^^
+help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
    |
-note: the lint level is defined here
-  --> $DIR/into-iter-on-arrays-lint.rs:59:13
-   |
-LL |     #[allow(array_into_iter)]
-   |             ^^^^^^^^^^^^^^^
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
+LL |     IntoIterator::into_iter(Box::new(Box::new([0u8; 33])));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^                             ^
+
+warning: 12 warnings emitted
 
diff --git a/src/test/ui/issues/issue-36638.rs b/src/test/ui/keyword/keyword-self-as-type-param.rs
index 2e64853697a..785d64ec8ea 100644
--- a/src/test/ui/issues/issue-36638.rs
+++ b/src/test/ui/keyword/keyword-self-as-type-param.rs
@@ -1,3 +1,5 @@
+// Regression test of #36638.
+
 struct Foo<Self>(Self);
 //~^ ERROR expected identifier, found keyword `Self`
 //~^^ ERROR E0392
diff --git a/src/test/ui/issues/issue-36638.stderr b/src/test/ui/keyword/keyword-self-as-type-param.stderr
index 733fc4af534..cc3df2e36f7 100644
--- a/src/test/ui/issues/issue-36638.stderr
+++ b/src/test/ui/keyword/keyword-self-as-type-param.stderr
@@ -1,17 +1,17 @@
 error: expected identifier, found keyword `Self`
-  --> $DIR/issue-36638.rs:1:12
+  --> $DIR/keyword-self-as-type-param.rs:3:12
    |
 LL | struct Foo<Self>(Self);
    |            ^^^^ expected identifier, found keyword
 
 error: expected identifier, found keyword `Self`
-  --> $DIR/issue-36638.rs:5:11
+  --> $DIR/keyword-self-as-type-param.rs:7:11
    |
 LL | trait Bar<Self> {}
    |           ^^^^ expected identifier, found keyword
 
 error[E0392]: parameter `Self` is never used
-  --> $DIR/issue-36638.rs:1:12
+  --> $DIR/keyword-self-as-type-param.rs:3:12
    |
 LL | struct Foo<Self>(Self);
    |            ^^^^ unused parameter
diff --git a/src/test/ui/lint/bare-trait-objects-path.rs b/src/test/ui/lint/bare-trait-objects-path.rs
index 74f838e9ed1..0a7c5a8dbd1 100644
--- a/src/test/ui/lint/bare-trait-objects-path.rs
+++ b/src/test/ui/lint/bare-trait-objects-path.rs
@@ -13,12 +13,12 @@ impl Assoc for dyn Dyn {}
 fn main() {
     Dyn::func();
     //~^ WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     ::Dyn::func();
     //~^ WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     Dyn::CONST;
     //~^ WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     let _: Dyn::Ty; //~ ERROR ambiguous associated type
 }
diff --git a/src/test/ui/lint/bare-trait-objects-path.stderr b/src/test/ui/lint/bare-trait-objects-path.stderr
index 55c9ea234de..40fafc4b3b5 100644
--- a/src/test/ui/lint/bare-trait-objects-path.stderr
+++ b/src/test/ui/lint/bare-trait-objects-path.stderr
@@ -11,7 +11,7 @@ LL |     Dyn::func();
    |     ^^^ help: use `dyn`: `<dyn Dyn>`
    |
    = note: `#[warn(bare_trait_objects)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 warning: trait objects without an explicit `dyn` are deprecated
@@ -20,7 +20,7 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL |     ::Dyn::func();
    |     ^^^^^ help: use `dyn`: `<dyn (::Dyn)>`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 warning: trait objects without an explicit `dyn` are deprecated
@@ -29,7 +29,7 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL |     Dyn::CONST;
    |     ^^^ help: use `dyn`: `<dyn Dyn>`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: aborting due to previous error; 3 warnings emitted
diff --git a/src/test/ui/lint/force-warn/force-allowed-by-default-lint.stderr b/src/test/ui/lint/force-warn/force-allowed-by-default-lint.stderr
index 0e0e934c765..37c61e614f3 100644
--- a/src/test/ui/lint/force-warn/force-allowed-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/force-allowed-by-default-lint.stderr
@@ -4,7 +4,7 @@ warning: hidden lifetime parameters in types are deprecated
 LL | fn foo(x: &Foo) {}
    |            ^^^- help: indicate the anonymous lifetime: `<'_>`
    |
-   = note: warning forced by `force-warns` commandline option
+   = note: requested on the command line with `--force-warns elided-lifetimes-in-paths`
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.stderr
index bad12f94b18..56b2f0236a5 100644
--- a/src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.stderr
@@ -6,7 +6,7 @@ LL | const C: i32 = 1 / 0;
    |                |
    |                attempt to divide `1_i32` by zero
    |
-   = note: warning forced by `force-warns` commandline option
+   = note: requested on the command line with `--force-warns const-err`
    = 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>
 
diff --git a/src/test/ui/lint/force-warn/force-allowed-warning.stderr b/src/test/ui/lint/force-warn/force-allowed-warning.stderr
index 145798a32a9..7eb980a1297 100644
--- a/src/test/ui/lint/force-warn/force-allowed-warning.stderr
+++ b/src/test/ui/lint/force-warn/force-allowed-warning.stderr
@@ -4,7 +4,7 @@ warning: function is never used: `dead_function`
 LL | fn dead_function() {}
    |    ^^^^^^^^^^^^^
    |
-   = note: warning forced by `force-warns` commandline option
+   = note: requested on the command line with `--force-warns dead-code`
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/lint/force-warn/force-deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/force-deny-by-default-lint.stderr
index 4b004cf367d..8b9bb5a74cf 100644
--- a/src/test/ui/lint/force-warn/force-deny-by-default-lint.stderr
+++ b/src/test/ui/lint/force-warn/force-deny-by-default-lint.stderr
@@ -6,7 +6,7 @@ LL | const C: i32 = 1 / 0;
    |                |
    |                attempt to divide `1_i32` by zero
    |
-   = note: warning forced by `force-warns` commandline option
+   = note: requested on the command line with `--force-warns const-err`
    = 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>
 
diff --git a/src/test/ui/lint/force-warn/force-lint-allow-all-warnings.stderr b/src/test/ui/lint/force-warn/force-lint-allow-all-warnings.stderr
index 577dbe1fea8..ebdb022f2a2 100644
--- a/src/test/ui/lint/force-warn/force-lint-allow-all-warnings.stderr
+++ b/src/test/ui/lint/force-warn/force-lint-allow-all-warnings.stderr
@@ -4,7 +4,7 @@ warning: function is never used: `dead_function`
 LL | fn dead_function() {}
    |    ^^^^^^^^^^^^^
    |
-   = note: warning forced by `force-warns` commandline option
+   = note: requested on the command line with `--force-warns dead-code`
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.stderr b/src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.stderr
index 8665fa2610a..7429e77fe83 100644
--- a/src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.stderr
+++ b/src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.stderr
@@ -4,7 +4,7 @@ warning: function `FUNCTION` should have a snake case name
 LL | pub fn FUNCTION() {}
    |        ^^^^^^^^ help: convert the identifier to snake case: `function`
    |
-   = note: warning forced by `force-warns` commandline option
+   = note: `--force-warns non-snake-case` implied by `--force-warns nonstandard-style`
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs b/src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs
index bb2f394aef3..b4c2c505aa5 100644
--- a/src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs
+++ b/src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs
@@ -7,6 +7,6 @@ pub trait SomeTrait {}
 
 pub fn function(_x: Box<SomeTrait>) {}
 //~^ WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this was previously accepted by the compiler
+//~| WARN this is accepted in the current edition
 
 fn main() {}
diff --git a/src/test/ui/lint/force-warn/force-lint-in-allowed-group.stderr b/src/test/ui/lint/force-warn/force-lint-in-allowed-group.stderr
index 40750ffea8c..4f7bba6bba1 100644
--- a/src/test/ui/lint/force-warn/force-lint-in-allowed-group.stderr
+++ b/src/test/ui/lint/force-warn/force-lint-in-allowed-group.stderr
@@ -4,8 +4,8 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | pub fn function(_x: Box<SomeTrait>) {}
    |                         ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
    |
-   = note: warning forced by `force-warns` commandline option
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: requested on the command line with `--force-warns bare-trait-objects`
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 warning: 1 warning emitted
diff --git a/src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs b/src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs
index d8a81d73afb..83a1c078f06 100644
--- a/src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs
+++ b/src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs
@@ -7,6 +7,6 @@ pub trait SomeTrait {}
 
 pub fn function(_x: Box<SomeTrait>) {}
 //~^ WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this was previously accepted by the compiler
+//~| WARN this is accepted in the current edition
 
 fn main() {}
diff --git a/src/test/ui/lint/force-warn/force-warn-group-allow-warning.stderr b/src/test/ui/lint/force-warn/force-warn-group-allow-warning.stderr
index 88ae846caa0..65de6c9e287 100644
--- a/src/test/ui/lint/force-warn/force-warn-group-allow-warning.stderr
+++ b/src/test/ui/lint/force-warn/force-warn-group-allow-warning.stderr
@@ -4,8 +4,8 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | pub fn function(_x: Box<SomeTrait>) {}
    |                         ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
    |
-   = note: warning forced by `force-warns` commandline option
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: `--force-warns bare-trait-objects` implied by `--force-warns rust-2018-idioms`
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 warning: 1 warning emitted
diff --git a/src/test/ui/lint/force-warn/force-warn-group.rs b/src/test/ui/lint/force-warn/force-warn-group.rs
index c97eeabbd4e..5e5fda973d5 100644
--- a/src/test/ui/lint/force-warn/force-warn-group.rs
+++ b/src/test/ui/lint/force-warn/force-warn-group.rs
@@ -7,6 +7,6 @@ pub trait SomeTrait {}
 
 pub fn function(_x: Box<SomeTrait>) {}
 //~^ WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this was previously accepted by the compiler
+//~| WARN this is accepted in the current edition
 
 fn main() {}
diff --git a/src/test/ui/lint/force-warn/force-warn-group.stderr b/src/test/ui/lint/force-warn/force-warn-group.stderr
index f808727991e..fd3397c916a 100644
--- a/src/test/ui/lint/force-warn/force-warn-group.stderr
+++ b/src/test/ui/lint/force-warn/force-warn-group.stderr
@@ -4,8 +4,8 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL | pub fn function(_x: Box<SomeTrait>) {}
    |                         ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
    |
-   = note: warning forced by `force-warns` commandline option
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: `--force-warns bare-trait-objects` implied by `--force-warns rust-2018-idioms`
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 warning: 1 warning emitted
diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.fixed b/src/test/ui/lint/inclusive-range-pattern-syntax.fixed
index a1b738e33fa..bee5d4ae4b1 100644
--- a/src/test/ui/lint/inclusive-range-pattern-syntax.fixed
+++ b/src/test/ui/lint/inclusive-range-pattern-syntax.fixed
@@ -8,14 +8,14 @@ fn main() {
     match despondency {
         1..=2 => {}
         //~^ WARN `...` range patterns are deprecated
-        //~| WARN this was previously accepted by the compiler
+        //~| WARN this is accepted in the current edition
         _ => {}
     }
 
     match &despondency {
         &(1..=2) => {}
         //~^ WARN `...` range patterns are deprecated
-        //~| WARN this was previously accepted by the compiler
+        //~| WARN this is accepted in the current edition
         _ => {}
     }
 }
diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.rs b/src/test/ui/lint/inclusive-range-pattern-syntax.rs
index d3ebbf38e1c..d98c10c26c7 100644
--- a/src/test/ui/lint/inclusive-range-pattern-syntax.rs
+++ b/src/test/ui/lint/inclusive-range-pattern-syntax.rs
@@ -8,14 +8,14 @@ fn main() {
     match despondency {
         1...2 => {}
         //~^ WARN `...` range patterns are deprecated
-        //~| WARN this was previously accepted by the compiler
+        //~| WARN this is accepted in the current edition
         _ => {}
     }
 
     match &despondency {
         &1...2 => {}
         //~^ WARN `...` range patterns are deprecated
-        //~| WARN this was previously accepted by the compiler
+        //~| WARN this is accepted in the current edition
         _ => {}
     }
 }
diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.stderr b/src/test/ui/lint/inclusive-range-pattern-syntax.stderr
index ba4ae208e39..efa684a24e3 100644
--- a/src/test/ui/lint/inclusive-range-pattern-syntax.stderr
+++ b/src/test/ui/lint/inclusive-range-pattern-syntax.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![warn(ellipsis_inclusive_range_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 warning: `...` range patterns are deprecated
@@ -18,7 +18,7 @@ warning: `...` range patterns are deprecated
 LL |         &1...2 => {}
    |         ^^^^^^ help: use `..=` for an inclusive range: `&(1..=2)`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 warning: 2 warnings emitted
diff --git a/src/test/ui/lint/issue-78660-cap-lints-future-compat.rs b/src/test/ui/lint/issue-78660-cap-lints-future-compat.rs
deleted file mode 100644
index 4d98f0ad62d..00000000000
--- a/src/test/ui/lint/issue-78660-cap-lints-future-compat.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// compile-flags: -D warnings --cap-lints allow
-// check-pass
-
-// Regression test for issue #78660
-// Tests that we don't ICE when a future-incompat-report lint has
-// has a command-line source, but is capped to allow
-
-fn main() {
-    ["hi"].into_iter();
-}
diff --git a/src/test/ui/lint/issue-78660-cap-lints-future-compat.stderr b/src/test/ui/lint/issue-78660-cap-lints-future-compat.stderr
deleted file mode 100644
index 79958ba90d4..00000000000
--- a/src/test/ui/lint/issue-78660-cap-lints-future-compat.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-Future incompatibility report: Future breakage date: None, diagnostic:
-warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
-  --> $DIR/issue-78660-cap-lints-future-compat.rs:9:12
-   |
-LL |     ["hi"].into_iter();
-   |            ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
-   |
-   = note: `-D array-into-iter` implied by `-D warnings`
-   = 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
-
diff --git a/src/test/ui/lint/lint-pre-expansion-extern-module.stderr b/src/test/ui/lint/lint-pre-expansion-extern-module.stderr
index 6efd03f14a1..3355bb4e4ff 100644
--- a/src/test/ui/lint/lint-pre-expansion-extern-module.stderr
+++ b/src/test/ui/lint/lint-pre-expansion-extern-module.stderr
@@ -5,7 +5,7 @@ LL | pub fn try() {}
    |        ^^^ help: you can use a raw identifier to stay compatible: `r#try`
    |
    = note: `-W keyword-idents` implied by `-W rust-2018-compatibility`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 warning: 1 warning emitted
diff --git a/src/test/ui/macros/auxiliary/or-pattern.rs b/src/test/ui/macros/auxiliary/or-pattern.rs
new file mode 100644
index 00000000000..a319c405eb6
--- /dev/null
+++ b/src/test/ui/macros/auxiliary/or-pattern.rs
@@ -0,0 +1,6 @@
+#![crate_type = "lib"]
+
+#[macro_export]
+macro_rules! a {
+    ($x:pat|) => ();
+}
diff --git a/src/test/ui/issues/issue-52169.rs b/src/test/ui/macros/issue-52169.rs
index 60be97f0aee..60be97f0aee 100644
--- a/src/test/ui/issues/issue-52169.rs
+++ b/src/test/ui/macros/issue-52169.rs
diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.fixed b/src/test/ui/macros/macro-or-patterns-back-compat.fixed
index f4e81a6be2a..f5a42670fdd 100644
--- a/src/test/ui/macros/macro-or-patterns-back-compat.fixed
+++ b/src/test/ui/macros/macro-or-patterns-back-compat.fixed
@@ -1,23 +1,28 @@
 // run-rustfix
+// aux-build:or-pattern.rs
 
 #![deny(or_patterns_back_compat)]
 #![allow(unused_macros)]
 
+#[macro_use]
+extern crate or_pattern;
+
 macro_rules! foo { ($x:pat_param | $y:pat) => {} }
 //~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 macro_rules! bar { ($($x:pat_param)+ | $($y:pat)+) => {} }
 //~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
+
 macro_rules! baz { ($x:pat_param | $y:pat_param) => {} } // should be ok
 macro_rules! qux { ($x:pat_param | $y:pat) => {} } // should be ok
 macro_rules! ogg { ($x:pat_param | $y:pat_param) => {} }
 //~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 macro_rules! match_any {
     ( $expr:expr , $( $( $pat:pat_param )|+ => $expr_arm:expr ),+ ) => {
         //~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
-        //~| WARN this was previously accepted
+        //~| WARN this is accepted in the current edition
         match $expr {
             $(
                 $( $pat => $expr_arm, )+
@@ -30,4 +35,5 @@ fn main() {
     let result: Result<i64, i32> = Err(42);
     let int: i64 = match_any!(result, Ok(i) | Err(i) => i.into());
     assert_eq!(int, 42);
+    a!(1|);
 }
diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.rs b/src/test/ui/macros/macro-or-patterns-back-compat.rs
index 49affdd38da..d6620f45f62 100644
--- a/src/test/ui/macros/macro-or-patterns-back-compat.rs
+++ b/src/test/ui/macros/macro-or-patterns-back-compat.rs
@@ -1,23 +1,28 @@
 // run-rustfix
+// aux-build:or-pattern.rs
 
 #![deny(or_patterns_back_compat)]
 #![allow(unused_macros)]
 
+#[macro_use]
+extern crate or_pattern;
+
 macro_rules! foo { ($x:pat | $y:pat) => {} }
 //~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} }
 //~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
+
 macro_rules! baz { ($x:pat_param | $y:pat_param) => {} } // should be ok
 macro_rules! qux { ($x:pat_param | $y:pat) => {} } // should be ok
 macro_rules! ogg { ($x:pat | $y:pat_param) => {} }
 //~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 macro_rules! match_any {
     ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => {
         //~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
-        //~| WARN this was previously accepted
+        //~| WARN this is accepted in the current edition
         match $expr {
             $(
                 $( $pat => $expr_arm, )+
@@ -30,4 +35,5 @@ fn main() {
     let result: Result<i64, i32> = Err(42);
     let int: i64 = match_any!(result, Ok(i) | Err(i) => i.into());
     assert_eq!(int, 42);
+    a!(1|);
 }
diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.stderr b/src/test/ui/macros/macro-or-patterns-back-compat.stderr
index 62687eb36b8..a48c9263154 100644
--- a/src/test/ui/macros/macro-or-patterns-back-compat.stderr
+++ b/src/test/ui/macros/macro-or-patterns-back-compat.stderr
@@ -1,42 +1,42 @@
 error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
-  --> $DIR/macro-or-patterns-back-compat.rs:6:21
+  --> $DIR/macro-or-patterns-back-compat.rs:10:21
    |
 LL | macro_rules! foo { ($x:pat | $y:pat) => {} }
    |                     ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param`
    |
 note: the lint level is defined here
-  --> $DIR/macro-or-patterns-back-compat.rs:3:9
+  --> $DIR/macro-or-patterns-back-compat.rs:4:9
    |
 LL | #![deny(or_patterns_back_compat)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #84869 <https://github.com/rust-lang/rust/issues/84869>
 
 error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
-  --> $DIR/macro-or-patterns-back-compat.rs:9:23
+  --> $DIR/macro-or-patterns-back-compat.rs:13:23
    |
 LL | macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} }
    |                       ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #84869 <https://github.com/rust-lang/rust/issues/84869>
 
 error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
-  --> $DIR/macro-or-patterns-back-compat.rs:14:21
+  --> $DIR/macro-or-patterns-back-compat.rs:19:21
    |
 LL | macro_rules! ogg { ($x:pat | $y:pat_param) => {} }
    |                     ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #84869 <https://github.com/rust-lang/rust/issues/84869>
 
 error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
-  --> $DIR/macro-or-patterns-back-compat.rs:18:26
+  --> $DIR/macro-or-patterns-back-compat.rs:23:26
    |
 LL |     ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => {
    |                          ^^^^^^^^ help: use pat_param to preserve semantics: `$pat:pat_param`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #84869 <https://github.com/rust-lang/rust/issues/84869>
 
 error: aborting due to 4 previous errors
diff --git a/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.rs b/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.rs
index 0385a120ce2..86fd37e7814 100644
--- a/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.rs
+++ b/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.rs
@@ -1,6 +1,6 @@
 // Tests correct kind-checking of the reason stack closures without the :Copy
 // bound must be noncopyable. For details see
-// http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/
+// https://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/
 
 struct R<'a> {
     // This struct is needed to create the
diff --git a/src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs b/src/test/ui/nll/issue-24535-allow-mutable-borrow-in-match-guard.rs
index 7253d35ed2d..7253d35ed2d 100644
--- a/src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs
+++ b/src/test/ui/nll/issue-24535-allow-mutable-borrow-in-match-guard.rs
diff --git a/src/test/ui/issues/issue-45157.rs b/src/test/ui/nll/issue-45157.rs
index 8d2bf22a03c..8d2bf22a03c 100644
--- a/src/test/ui/issues/issue-45157.rs
+++ b/src/test/ui/nll/issue-45157.rs
diff --git a/src/test/ui/issues/issue-45157.stderr b/src/test/ui/nll/issue-45157.stderr
index 57fd8d49c88..57fd8d49c88 100644
--- a/src/test/ui/issues/issue-45157.stderr
+++ b/src/test/ui/nll/issue-45157.stderr
diff --git a/src/test/ui/non-fmt-panic.stderr b/src/test/ui/non-fmt-panic.stderr
index 3278eb5f023..0f451c1e0a9 100644
--- a/src/test/ui/non-fmt-panic.stderr
+++ b/src/test/ui/non-fmt-panic.stderr
@@ -61,7 +61,8 @@ warning: panic message is not a string literal
 LL |     assert!(false, S);
    |                    ^
    |
-   = note: this is no longer accepted in Rust 2021
+   = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
 help: add a "{}" format string to Display the message
    |
 LL |     assert!(false, "{}", S);
@@ -85,7 +86,8 @@ warning: panic message is not a string literal
 LL |     panic!(C);
    |            ^
    |
-   = note: this is no longer accepted in Rust 2021
+   = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
 help: add a "{}" format string to Display the message
    |
 LL |     panic!("{}", C);
@@ -101,7 +103,8 @@ warning: panic message is not a string literal
 LL |     panic!(S);
    |            ^
    |
-   = note: this is no longer accepted in Rust 2021
+   = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
 help: add a "{}" format string to Display the message
    |
 LL |     panic!("{}", S);
@@ -117,7 +120,8 @@ warning: panic message is not a string literal
 LL |     std::panic!(123);
    |                 ^^^
    |
-   = note: this is no longer accepted in Rust 2021
+   = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
 help: add a "{}" format string to Display the message
    |
 LL |     std::panic!("{}", 123);
@@ -133,7 +137,8 @@ warning: panic message is not a string literal
 LL |     core::panic!(&*"abc");
    |                  ^^^^^^^
    |
-   = note: this is no longer accepted in Rust 2021
+   = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
 help: add a "{}" format string to Display the message
    |
 LL |     core::panic!("{}", &*"abc");
@@ -181,7 +186,8 @@ warning: panic message is not a string literal
 LL |     fancy_panic::fancy_panic!(S);
    |                               ^
    |
-   = note: this is no longer accepted in Rust 2021
+   = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
 
 warning: panic message is not a string literal
   --> $DIR/non-fmt-panic.rs:36:12
@@ -189,7 +195,8 @@ warning: panic message is not a string literal
 LL |     panic!(a!());
    |            ^^^^
    |
-   = note: this is no longer accepted in Rust 2021
+   = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
 help: add a "{}" format string to Display the message
    |
 LL |     panic!("{}", a!());
@@ -205,7 +212,8 @@ warning: panic message is not a string literal
 LL |     panic!(format!("{}", 1));
    |            ^^^^^^^^^^^^^^^^
    |
-   = note: this is no longer accepted in Rust 2021
+   = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
    = note: the panic!() macro supports formatting, so there's no need for the format!() macro here
 help: remove the `format!(..)` macro call
    |
@@ -218,7 +226,8 @@ warning: panic message is not a string literal
 LL |     assert!(false, format!("{}", 1));
    |                    ^^^^^^^^^^^^^^^^
    |
-   = note: this is no longer accepted in Rust 2021
+   = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
    = note: the assert!() macro supports formatting, so there's no need for the format!() macro here
 help: remove the `format!(..)` macro call
    |
@@ -231,7 +240,8 @@ warning: panic message is not a string literal
 LL |     debug_assert!(false, format!("{}", 1));
    |                          ^^^^^^^^^^^^^^^^
    |
-   = note: this is no longer accepted in Rust 2021
+   = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
    = note: the debug_assert!() macro supports formatting, so there's no need for the format!() macro here
 help: remove the `format!(..)` macro call
    |
@@ -244,7 +254,8 @@ warning: panic message is not a string literal
 LL |     panic![123];
    |            ^^^
    |
-   = note: this is no longer accepted in Rust 2021
+   = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
 help: add a "{}" format string to Display the message
    |
 LL |     panic!["{}", 123];
@@ -260,7 +271,8 @@ warning: panic message is not a string literal
 LL |     panic!{123};
    |            ^^^
    |
-   = note: this is no longer accepted in Rust 2021
+   = note: this usage of panic!() is deprecated; it will be a hard error in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
 help: add a "{}" format string to Display the message
    |
 LL |     panic!{"{}", 123};
diff --git a/src/test/ui/nullable-pointer-iotareduction.rs b/src/test/ui/nullable-pointer-iotareduction.rs
index 4c6964f294b..568c3e144be 100644
--- a/src/test/ui/nullable-pointer-iotareduction.rs
+++ b/src/test/ui/nullable-pointer-iotareduction.rs
@@ -4,7 +4,7 @@
 
 // Iota-reduction is a rule in the Calculus of (Co-)Inductive Constructions,
 // which "says that a destructor applied to an object built from a constructor
-// behaves as expected".  -- http://coq.inria.fr/doc/Reference-Manual006.html
+// behaves as expected".  -- https://coq.inria.fr/doc/language/core/conversion.html#iota-reduction
 //
 // It's a little more complicated here, because of pointers and regions and
 // trying to get assert failure messages that at least identify which case
diff --git a/src/test/ui/issues/issue-27060-2.rs b/src/test/ui/packed/issue-27060-2.rs
index a001ce1e0ac..a001ce1e0ac 100644
--- a/src/test/ui/issues/issue-27060-2.rs
+++ b/src/test/ui/packed/issue-27060-2.rs
diff --git a/src/test/ui/issues/issue-27060-2.stderr b/src/test/ui/packed/issue-27060-2.stderr
index 5dbcc96e874..5dbcc96e874 100644
--- a/src/test/ui/issues/issue-27060-2.stderr
+++ b/src/test/ui/packed/issue-27060-2.stderr
diff --git a/src/test/ui/issues/issue-27060-rpass.rs b/src/test/ui/packed/issue-27060-rpass.rs
index d9159f6669d..d9159f6669d 100644
--- a/src/test/ui/issues/issue-27060-rpass.rs
+++ b/src/test/ui/packed/issue-27060-rpass.rs
diff --git a/src/test/ui/issues/issue-27060.rs b/src/test/ui/packed/issue-27060.rs
index 5317a616719..5317a616719 100644
--- a/src/test/ui/issues/issue-27060.rs
+++ b/src/test/ui/packed/issue-27060.rs
diff --git a/src/test/ui/issues/issue-27060.stderr b/src/test/ui/packed/issue-27060.stderr
index 09297884ed3..09297884ed3 100644
--- a/src/test/ui/issues/issue-27060.stderr
+++ b/src/test/ui/packed/issue-27060.stderr
diff --git a/src/test/ui/issues/issue-48636.fixed b/src/test/ui/parser/issue-48636.fixed
index 87c19a32d4c..87c19a32d4c 100644
--- a/src/test/ui/issues/issue-48636.fixed
+++ b/src/test/ui/parser/issue-48636.fixed
diff --git a/src/test/ui/issues/issue-48636.rs b/src/test/ui/parser/issue-48636.rs
index 8610dc2f72e..8610dc2f72e 100644
--- a/src/test/ui/issues/issue-48636.rs
+++ b/src/test/ui/parser/issue-48636.rs
diff --git a/src/test/ui/issues/issue-48636.stderr b/src/test/ui/parser/issue-48636.stderr
index 462723d1d93..462723d1d93 100644
--- a/src/test/ui/issues/issue-48636.stderr
+++ b/src/test/ui/parser/issue-48636.stderr
diff --git a/src/test/ui/issues/issue-54521-1.rs b/src/test/ui/parser/issue-54521-1.rs
index 8a682ef0a11..8a682ef0a11 100644
--- a/src/test/ui/issues/issue-54521-1.rs
+++ b/src/test/ui/parser/issue-54521-1.rs
diff --git a/src/test/ui/issues/issue-54521-2.fixed b/src/test/ui/parser/issue-54521-2.fixed
index a91c4fe43ea..a91c4fe43ea 100644
--- a/src/test/ui/issues/issue-54521-2.fixed
+++ b/src/test/ui/parser/issue-54521-2.fixed
diff --git a/src/test/ui/issues/issue-54521-2.rs b/src/test/ui/parser/issue-54521-2.rs
index 3639aac87ee..3639aac87ee 100644
--- a/src/test/ui/issues/issue-54521-2.rs
+++ b/src/test/ui/parser/issue-54521-2.rs
diff --git a/src/test/ui/issues/issue-54521-2.stderr b/src/test/ui/parser/issue-54521-2.stderr
index 9556b83b730..9556b83b730 100644
--- a/src/test/ui/issues/issue-54521-2.stderr
+++ b/src/test/ui/parser/issue-54521-2.stderr
diff --git a/src/test/ui/issues/issue-54521.fixed b/src/test/ui/parser/issue-54521-3.fixed
index 84ab6866cf1..84ab6866cf1 100644
--- a/src/test/ui/issues/issue-54521.fixed
+++ b/src/test/ui/parser/issue-54521-3.fixed
diff --git a/src/test/ui/issues/issue-54521.rs b/src/test/ui/parser/issue-54521-3.rs
index f1d68504178..f1d68504178 100644
--- a/src/test/ui/issues/issue-54521.rs
+++ b/src/test/ui/parser/issue-54521-3.rs
diff --git a/src/test/ui/issues/issue-54521.stderr b/src/test/ui/parser/issue-54521-3.stderr
index ffefbfd0348..0f23dd62107 100644
--- a/src/test/ui/issues/issue-54521.stderr
+++ b/src/test/ui/parser/issue-54521-3.stderr
@@ -1,23 +1,23 @@
 error: unmatched angle brackets
-  --> $DIR/issue-54521.rs:11:60
+  --> $DIR/issue-54521-3.rs:11:60
    |
 LL |     let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>>>();
    |                                                            ^^^^ help: remove extra angle brackets
 
 error: unmatched angle brackets
-  --> $DIR/issue-54521.rs:14:60
+  --> $DIR/issue-54521-3.rs:14:60
    |
 LL |     let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>>();
    |                                                            ^^^ help: remove extra angle brackets
 
 error: unmatched angle brackets
-  --> $DIR/issue-54521.rs:17:60
+  --> $DIR/issue-54521-3.rs:17:60
    |
 LL |     let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>>();
    |                                                            ^^ help: remove extra angle brackets
 
 error: unmatched angle bracket
-  --> $DIR/issue-54521.rs:20:60
+  --> $DIR/issue-54521-3.rs:20:60
    |
 LL |     let _ = vec![1, 2, 3].into_iter().collect::<Vec<usize>>>();
    |                                                            ^ help: remove extra angle bracket
diff --git a/src/test/ui/parser/issue-68890-2.rs b/src/test/ui/parser/issue-68890-2.rs
index 88527cc8783..0a6e26acfc7 100644
--- a/src/test/ui/parser/issue-68890-2.rs
+++ b/src/test/ui/parser/issue-68890-2.rs
@@ -4,4 +4,4 @@ type X<'a> = (?'a) +;
 //~^ ERROR `?` may only modify trait bounds, not lifetime bounds
 //~| ERROR at least one trait is required for an object type
 //~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this was previously accepted by the compiler
+//~| WARN this is accepted in the current edition
diff --git a/src/test/ui/parser/issue-68890-2.stderr b/src/test/ui/parser/issue-68890-2.stderr
index 37f38365b01..dce03e1a963 100644
--- a/src/test/ui/parser/issue-68890-2.stderr
+++ b/src/test/ui/parser/issue-68890-2.stderr
@@ -11,7 +11,7 @@ LL | type X<'a> = (?'a) +;
    |              ^^^^^^^ help: use `dyn`: `dyn (?'a) +`
    |
    = note: `#[warn(bare_trait_objects)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error[E0224]: at least one trait is required for an object type
diff --git a/src/test/ui/parser/issue-73568-lifetime-after-mut.rs b/src/test/ui/parser/issue-73568-lifetime-after-mut.rs
index 0733b2d2df7..e68ee747cfd 100644
--- a/src/test/ui/parser/issue-73568-lifetime-after-mut.rs
+++ b/src/test/ui/parser/issue-73568-lifetime-after-mut.rs
@@ -14,10 +14,10 @@ mac!('a);
 fn y<'a>(y: &mut 'a + Send) {
     //~^ ERROR expected a path on the left-hand side of `+`, not `&mut 'a`
     //~| WARNING trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     //~| ERROR at least one trait is required for an object type
     let z = y as &mut 'a + Send;
     //~^ ERROR expected value, found trait `Send`
     //~| WARNING trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
 }
diff --git a/src/test/ui/parser/issue-73568-lifetime-after-mut.stderr b/src/test/ui/parser/issue-73568-lifetime-after-mut.stderr
index f83b7944b1b..c10037d44e3 100644
--- a/src/test/ui/parser/issue-73568-lifetime-after-mut.stderr
+++ b/src/test/ui/parser/issue-73568-lifetime-after-mut.stderr
@@ -34,7 +34,7 @@ LL | fn y<'a>(y: &mut 'a + Send) {
    |                  ^^ help: use `dyn`: `dyn 'a`
    |
    = note: `#[warn(bare_trait_objects)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 warning: trait objects without an explicit `dyn` are deprecated
@@ -43,7 +43,7 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL |     let z = y as &mut 'a + Send;
    |                       ^^ help: use `dyn`: `dyn 'a`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error[E0224]: at least one trait is required for an object type
diff --git a/src/test/ui/parser/macro/trait-object-macro-matcher.rs b/src/test/ui/parser/macro/trait-object-macro-matcher.rs
index 0428ea0e2c1..663739f235a 100644
--- a/src/test/ui/parser/macro/trait-object-macro-matcher.rs
+++ b/src/test/ui/parser/macro/trait-object-macro-matcher.rs
@@ -12,5 +12,5 @@ fn main() {
     //~^ ERROR lifetime in trait object type must be followed by `+`
     //~| ERROR at least one trait is required for an object type
     //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
 }
diff --git a/src/test/ui/parser/macro/trait-object-macro-matcher.stderr b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr
index 8ae5611d89d..caca84f695d 100644
--- a/src/test/ui/parser/macro/trait-object-macro-matcher.stderr
+++ b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr
@@ -11,7 +11,7 @@ LL |     m!('static);
    |        ^^^^^^^ help: use `dyn`: `dyn 'static`
    |
    = note: `#[warn(bare_trait_objects)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error[E0224]: at least one trait is required for an object type
diff --git a/src/test/ui/parser/parser-unicode-whitespace.rs b/src/test/ui/parser/parser-unicode-whitespace.rs
index 2d1fa7dc42e..555cd68c3a7 100644
--- a/src/test/ui/parser/parser-unicode-whitespace.rs
+++ b/src/test/ui/parser/parser-unicode-whitespace.rs
@@ -1,7 +1,7 @@
 // run-pass
 // Beware editing: it has numerous whitespace characters which are important.
 // It contains one ranges from the 'PATTERN_WHITE_SPACE' property outlined in
-// http://unicode.org/Public/UNIDATA/PropList.txt
+// https://unicode.org/Public/UNIDATA/PropList.txt
 //
 // The characters in the first expression of the assertion can be generated
 // from: "4\u{0C}+\n\t\r7\t*\u{20}2\u{85}/\u{200E}3\u{200F}*\u{2028}2\u{2029}"
diff --git a/src/test/ui/parser/recover-range-pats.rs b/src/test/ui/parser/recover-range-pats.rs
index a10add6d9e5..2e5a991543f 100644
--- a/src/test/ui/parser/recover-range-pats.rs
+++ b/src/test/ui/parser/recover-range-pats.rs
@@ -41,30 +41,30 @@ fn inclusive_from_to() {
 fn inclusive2_from_to() {
     if let 0...3 = 0 {}
     //~^ ERROR `...` range patterns are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     if let 0...Y = 0 {}
     //~^ ERROR `...` range patterns are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     if let X...3 = 0 {}
     //~^ ERROR `...` range patterns are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     if let X...Y = 0 {}
     //~^ ERROR `...` range patterns are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     if let true...Y = 0 {} //~ ERROR only `char` and numeric types
     //~^ ERROR `...` range patterns are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     if let X...true = 0 {} //~ ERROR only `char` and numeric types
     //~^ ERROR `...` range patterns are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     if let .0...Y = 0 {} //~ ERROR mismatched types
     //~^ ERROR float literals must have an integer part
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     //~| ERROR `...` range patterns are deprecated
     if let X... .0 = 0 {} //~ ERROR mismatched types
     //~^ ERROR float literals must have an integer part
     //~| ERROR `...` range patterns are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
 }
 
 fn exclusive_from() {
@@ -137,7 +137,7 @@ fn with_macro_expr_var() {
             let $e1..$e2;
             let $e1...$e2;
             //~^ ERROR `...` range patterns are deprecated
-            //~| WARN this was previously accepted by the compiler
+            //~| WARN this is accepted in the current edition
             let $e1..=$e2;
         }
     }
diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr
index 3236ef0db28..2d8088432a2 100644
--- a/src/test/ui/parser/recover-range-pats.stderr
+++ b/src/test/ui/parser/recover-range-pats.stderr
@@ -204,7 +204,7 @@ note: the lint level is defined here
    |
 LL | #![deny(ellipsis_inclusive_range_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: `...` range patterns are deprecated
@@ -213,7 +213,7 @@ error: `...` range patterns are deprecated
 LL |     if let 0...Y = 0 {}
    |             ^^^ help: use `..=` for an inclusive range
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: `...` range patterns are deprecated
@@ -222,7 +222,7 @@ error: `...` range patterns are deprecated
 LL |     if let X...3 = 0 {}
    |             ^^^ help: use `..=` for an inclusive range
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: `...` range patterns are deprecated
@@ -231,7 +231,7 @@ error: `...` range patterns are deprecated
 LL |     if let X...Y = 0 {}
    |             ^^^ help: use `..=` for an inclusive range
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: `...` range patterns are deprecated
@@ -240,7 +240,7 @@ error: `...` range patterns are deprecated
 LL |     if let true...Y = 0 {}
    |                ^^^ help: use `..=` for an inclusive range
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: `...` range patterns are deprecated
@@ -249,7 +249,7 @@ error: `...` range patterns are deprecated
 LL |     if let X...true = 0 {}
    |             ^^^ help: use `..=` for an inclusive range
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: `...` range patterns are deprecated
@@ -258,7 +258,7 @@ error: `...` range patterns are deprecated
 LL |     if let .0...Y = 0 {}
    |              ^^^ help: use `..=` for an inclusive range
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: `...` range patterns are deprecated
@@ -267,7 +267,7 @@ error: `...` range patterns are deprecated
 LL |     if let X... .0 = 0 {}
    |             ^^^ help: use `..=` for an inclusive range
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: `...` range patterns are deprecated
@@ -279,7 +279,7 @@ LL |             let $e1...$e2;
 LL |     mac2!(0, 1);
    |     ------------ in this macro invocation
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
    = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/parser/trait-object-trait-parens.rs b/src/test/ui/parser/trait-object-trait-parens.rs
index 7d55da7d097..438034bc38a 100644
--- a/src/test/ui/parser/trait-object-trait-parens.rs
+++ b/src/test/ui/parser/trait-object-trait-parens.rs
@@ -9,15 +9,15 @@ fn main() {
     //~^ ERROR `?Trait` is not permitted in trait object types
     //~| ERROR only auto traits can be used as additional traits
     //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
     //~^ ERROR `?Trait` is not permitted in trait object types
     //~| ERROR only auto traits can be used as additional traits
     //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
     //~^ ERROR `?Trait` is not permitted in trait object types
     //~| ERROR only auto traits can be used as additional traits
     //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
 }
diff --git a/src/test/ui/parser/trait-object-trait-parens.stderr b/src/test/ui/parser/trait-object-trait-parens.stderr
index 79b6892dc07..9bfc4943fe9 100644
--- a/src/test/ui/parser/trait-object-trait-parens.stderr
+++ b/src/test/ui/parser/trait-object-trait-parens.stderr
@@ -23,7 +23,7 @@ LL |     let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)`
    |
    = note: `#[warn(bare_trait_objects)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 warning: trait objects without an explicit `dyn` are deprecated
@@ -32,7 +32,7 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL |     let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn ?Sized + (for<'a> Trait<'a>) + (Obj)`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 warning: trait objects without an explicit `dyn` are deprecated
@@ -41,7 +41,7 @@ warning: trait objects without an explicit `dyn` are deprecated
 LL |     let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn for<'a> Trait<'a> + (Obj) + (?Sized)`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
diff --git a/src/test/ui/process-termination/process-termination-blocking-io.rs b/src/test/ui/process-termination/process-termination-blocking-io.rs
index f306a61a538..b2dab5c9381 100644
--- a/src/test/ui/process-termination/process-termination-blocking-io.rs
+++ b/src/test/ui/process-termination/process-termination-blocking-io.rs
@@ -9,7 +9,7 @@ use std::{net::TcpListener, sync::mpsc, thread};
 fn main() {
     let (tx, rx) = mpsc::channel();
     thread::spawn(move || {
-        let listen = TcpListener::bind("0.0.0.0:0").unwrap();
+        let listen = TcpListener::bind("127.0.0.1:0").unwrap();
         tx.send(()).unwrap();
         while let Ok(_) = listen.accept() {}
     });
diff --git a/src/test/ui/range/range-inclusive-pattern-precedence.fixed b/src/test/ui/range/range-inclusive-pattern-precedence.fixed
index 6c012099676..8a4b8fc38e3 100644
--- a/src/test/ui/range/range-inclusive-pattern-precedence.fixed
+++ b/src/test/ui/range/range-inclusive-pattern-precedence.fixed
@@ -10,7 +10,7 @@ pub fn main() {
     match &12 {
         &(0..=9) => {}
         //~^ WARN `...` range patterns are deprecated
-        //~| WARN this was previously accepted by the compiler
+        //~| WARN this is accepted in the current edition
         //~| HELP use `..=` for an inclusive range
         &(10 ..=15) => {}
         //~^ ERROR the range pattern here has ambiguous interpretation
diff --git a/src/test/ui/range/range-inclusive-pattern-precedence.rs b/src/test/ui/range/range-inclusive-pattern-precedence.rs
index ce763ba2677..b294e436fa6 100644
--- a/src/test/ui/range/range-inclusive-pattern-precedence.rs
+++ b/src/test/ui/range/range-inclusive-pattern-precedence.rs
@@ -10,7 +10,7 @@ pub fn main() {
     match &12 {
         &0...9 => {}
         //~^ WARN `...` range patterns are deprecated
-        //~| WARN this was previously accepted by the compiler
+        //~| WARN this is accepted in the current edition
         //~| HELP use `..=` for an inclusive range
         &10..=15 => {}
         //~^ ERROR the range pattern here has ambiguous interpretation
diff --git a/src/test/ui/range/range-inclusive-pattern-precedence.stderr b/src/test/ui/range/range-inclusive-pattern-precedence.stderr
index ffb833535c2..3330ced1ebf 100644
--- a/src/test/ui/range/range-inclusive-pattern-precedence.stderr
+++ b/src/test/ui/range/range-inclusive-pattern-precedence.stderr
@@ -15,7 +15,7 @@ note: the lint level is defined here
    |
 LL | #![warn(ellipsis_inclusive_range_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: aborting due to previous error; 1 warning emitted
diff --git a/src/test/ui/range/range-inclusive-pattern-precedence2.rs b/src/test/ui/range/range-inclusive-pattern-precedence2.rs
index 7fa2698a496..bede9c57976 100644
--- a/src/test/ui/range/range-inclusive-pattern-precedence2.rs
+++ b/src/test/ui/range/range-inclusive-pattern-precedence2.rs
@@ -9,7 +9,7 @@ fn main() {
         // FIXME: can we add suggestions like `&(0..=9)`?
         box 0...9 => {}
         //~^ WARN `...` range patterns are deprecated
-        //~| WARN this was previously accepted by the compiler
+        //~| WARN this is accepted in the current edition
         //~| HELP use `..=` for an inclusive range
         box 10..=15 => {}
         //~^ ERROR the range pattern here has ambiguous interpretation
diff --git a/src/test/ui/range/range-inclusive-pattern-precedence2.stderr b/src/test/ui/range/range-inclusive-pattern-precedence2.stderr
index e8e62b485cc..90a4aa68222 100644
--- a/src/test/ui/range/range-inclusive-pattern-precedence2.stderr
+++ b/src/test/ui/range/range-inclusive-pattern-precedence2.stderr
@@ -15,7 +15,7 @@ note: the lint level is defined here
    |
 LL | #![warn(ellipsis_inclusive_range_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: aborting due to previous error; 1 warning emitted
diff --git a/src/test/ui/repr/repr-transparent.rs b/src/test/ui/repr/repr-transparent.rs
index 8fbdb4cc80b..8c9d1639c0a 100644
--- a/src/test/ui/repr/repr-transparent.rs
+++ b/src/test/ui/repr/repr-transparent.rs
@@ -8,27 +8,29 @@
 use std::marker::PhantomData;
 
 #[repr(transparent)]
-struct NoFields; //~ ERROR needs exactly one non-zero-sized field
+struct NoFields;
 
 #[repr(transparent)]
-struct ContainsOnlyZst(()); //~ ERROR needs exactly one non-zero-sized field
+struct ContainsOnlyZst(());
 
 #[repr(transparent)]
-struct ContainsOnlyZstArray([bool; 0]); //~ ERROR needs exactly one non-zero-sized field
+struct ContainsOnlyZstArray([bool; 0]);
 
 #[repr(transparent)]
 struct ContainsMultipleZst(PhantomData<*const i32>, NoFields);
-//~^ ERROR needs exactly one non-zero-sized field
 
 #[repr(transparent)]
-struct MultipleNonZst(u8, u8); //~ ERROR needs exactly one non-zero-sized field
+struct ContainsZstAndNonZst((), [i32; 2]);
+
+#[repr(transparent)]
+struct MultipleNonZst(u8, u8); //~ ERROR needs at most one non-zero-sized field
 
 trait Mirror { type It: ?Sized; }
 impl<T: ?Sized> Mirror for T { type It = Self; }
 
 #[repr(transparent)]
 pub struct StructWithProjection(f32, <f32 as Mirror>::It);
-//~^ ERROR needs exactly one non-zero-sized field
+//~^ ERROR needs at most one non-zero-sized field
 
 #[repr(transparent)]
 struct NontrivialAlignZst(u32, [u16; 0]); //~ ERROR alignment larger than 1
@@ -40,22 +42,26 @@ struct ZstAlign32<T>(PhantomData<T>);
 struct GenericAlign<T>(ZstAlign32<T>, u32); //~ ERROR alignment larger than 1
 
 #[repr(transparent)] //~ ERROR unsupported representation for zero-variant enum
-enum Void {}
-//~^ ERROR transparent enum needs exactly one variant, but has 0
+enum Void {} //~ ERROR transparent enum needs exactly one variant, but has 0
 
 #[repr(transparent)]
-enum FieldlessEnum { //~ ERROR transparent enum needs exactly one non-zero-sized field, but has 0
+enum FieldlessEnum {
     Foo,
 }
 
 #[repr(transparent)]
+enum UnitFieldEnum {
+    Foo(()),
+}
+
+#[repr(transparent)]
 enum TooManyFieldsEnum {
     Foo(u32, String),
 }
-//~^^^ ERROR transparent enum needs exactly one non-zero-sized field, but has 2
+//~^^^ ERROR transparent enum needs at most one non-zero-sized field, but has 2
 
 #[repr(transparent)]
-enum TooManyVariants { //~ ERROR transparent enum needs exactly one variant, but has 2
+enum MultipleVariants { //~ ERROR transparent enum needs exactly one variant, but has 2
     Foo(String),
     Bar,
 }
@@ -71,12 +77,12 @@ enum GenericAlignEnum<T> {
 }
 
 #[repr(transparent)]
-union UnitUnion { //~ ERROR transparent union needs exactly one non-zero-sized field, but has 0
+union UnitUnion {
     u: (),
 }
 
 #[repr(transparent)]
-union TooManyFields { //~ ERROR transparent union needs exactly one non-zero-sized field, but has 2
+union TooManyFields { //~ ERROR transparent union needs at most one non-zero-sized field, but has 2
     u: u32,
     s: i32
 }
diff --git a/src/test/ui/repr/repr-transparent.stderr b/src/test/ui/repr/repr-transparent.stderr
index cbc74fbb6a2..001a181881f 100644
--- a/src/test/ui/repr/repr-transparent.stderr
+++ b/src/test/ui/repr/repr-transparent.stderr
@@ -1,61 +1,37 @@
-error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
-  --> $DIR/repr-transparent.rs:11:1
-   |
-LL | struct NoFields;
-   | ^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0
-
-error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
-  --> $DIR/repr-transparent.rs:14:1
-   |
-LL | struct ContainsOnlyZst(());
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0
-
-error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
-  --> $DIR/repr-transparent.rs:17:1
-   |
-LL | struct ContainsOnlyZstArray([bool; 0]);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0
-
-error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
-  --> $DIR/repr-transparent.rs:20:1
-   |
-LL | struct ContainsMultipleZst(PhantomData<*const i32>, NoFields);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0
-
-error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 2
-  --> $DIR/repr-transparent.rs:24:1
+error[E0690]: transparent struct needs at most one non-zero-sized field, but has 2
+  --> $DIR/repr-transparent.rs:26:1
    |
 LL | struct MultipleNonZst(u8, u8);
    | ^^^^^^^^^^^^^^^^^^^^^^--^^--^^
    | |                     |   |
    | |                     |   this field is non-zero-sized
    | |                     this field is non-zero-sized
-   | needs exactly one non-zero-sized field, but has 2
+   | needs at most one non-zero-sized field, but has 2
 
-error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 2
-  --> $DIR/repr-transparent.rs:30:1
+error[E0690]: transparent struct needs at most one non-zero-sized field, but has 2
+  --> $DIR/repr-transparent.rs:32:1
    |
 LL | pub struct StructWithProjection(f32, <f32 as Mirror>::It);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^-------------------^^
    | |                               |    |
    | |                               |    this field is non-zero-sized
    | |                               this field is non-zero-sized
-   | needs exactly one non-zero-sized field, but has 2
+   | needs at most one non-zero-sized field, but has 2
 
 error[E0691]: zero-sized field in transparent struct has alignment larger than 1
-  --> $DIR/repr-transparent.rs:34:32
+  --> $DIR/repr-transparent.rs:36:32
    |
 LL | struct NontrivialAlignZst(u32, [u16; 0]);
    |                                ^^^^^^^^ has alignment larger than 1
 
 error[E0691]: zero-sized field in transparent struct has alignment larger than 1
-  --> $DIR/repr-transparent.rs:40:24
+  --> $DIR/repr-transparent.rs:42:24
    |
 LL | struct GenericAlign<T>(ZstAlign32<T>, u32);
    |                        ^^^^^^^^^^^^^ has alignment larger than 1
 
 error[E0084]: unsupported representation for zero-variant enum
-  --> $DIR/repr-transparent.rs:42:1
+  --> $DIR/repr-transparent.rs:44:1
    |
 LL | #[repr(transparent)]
    | ^^^^^^^^^^^^^^^^^^^^
@@ -63,66 +39,54 @@ LL | enum Void {}
    | ------------ zero-variant enum
 
 error[E0731]: transparent enum needs exactly one variant, but has 0
-  --> $DIR/repr-transparent.rs:43:1
+  --> $DIR/repr-transparent.rs:45:1
    |
 LL | enum Void {}
    | ^^^^^^^^^ needs exactly one variant, but has 0
 
-error[E0690]: the variant of a transparent enum needs exactly one non-zero-sized field, but has 0
-  --> $DIR/repr-transparent.rs:47:1
-   |
-LL | enum FieldlessEnum {
-   | ^^^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0
-
-error[E0690]: the variant of a transparent enum needs exactly one non-zero-sized field, but has 2
-  --> $DIR/repr-transparent.rs:52:1
+error[E0690]: the variant of a transparent enum needs at most one non-zero-sized field, but has 2
+  --> $DIR/repr-transparent.rs:58:1
    |
 LL | enum TooManyFieldsEnum {
-   | ^^^^^^^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 2
+   | ^^^^^^^^^^^^^^^^^^^^^^ needs at most one non-zero-sized field, but has 2
 LL |     Foo(u32, String),
    |         ---  ------ this field is non-zero-sized
    |         |
    |         this field is non-zero-sized
 
 error[E0731]: transparent enum needs exactly one variant, but has 2
-  --> $DIR/repr-transparent.rs:58:1
+  --> $DIR/repr-transparent.rs:64:1
    |
-LL | enum TooManyVariants {
-   | ^^^^^^^^^^^^^^^^^^^^ needs exactly one variant, but has 2
+LL | enum MultipleVariants {
+   | ^^^^^^^^^^^^^^^^^^^^^ needs exactly one variant, but has 2
 LL |     Foo(String),
    |     -----------
 LL |     Bar,
-   |     --- too many variants in `TooManyVariants`
+   |     --- too many variants in `MultipleVariants`
 
 error[E0691]: zero-sized field in transparent enum has alignment larger than 1
-  --> $DIR/repr-transparent.rs:65:14
+  --> $DIR/repr-transparent.rs:71:14
    |
 LL |     Foo(u32, [u16; 0]),
    |              ^^^^^^^^ has alignment larger than 1
 
 error[E0691]: zero-sized field in transparent enum has alignment larger than 1
-  --> $DIR/repr-transparent.rs:70:11
+  --> $DIR/repr-transparent.rs:76:11
    |
 LL |     Foo { bar: ZstAlign32<T>, baz: u32 }
    |           ^^^^^^^^^^^^^^^^^^ has alignment larger than 1
 
-error[E0690]: transparent union needs exactly one non-zero-sized field, but has 0
-  --> $DIR/repr-transparent.rs:74:1
-   |
-LL | union UnitUnion {
-   | ^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0
-
-error[E0690]: transparent union needs exactly one non-zero-sized field, but has 2
-  --> $DIR/repr-transparent.rs:79:1
+error[E0690]: transparent union needs at most one non-zero-sized field, but has 2
+  --> $DIR/repr-transparent.rs:85:1
    |
 LL | union TooManyFields {
-   | ^^^^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 2
+   | ^^^^^^^^^^^^^^^^^^^ needs at most one non-zero-sized field, but has 2
 LL |     u: u32,
    |     ------ this field is non-zero-sized
 LL |     s: i32
    |     ------ this field is non-zero-sized
 
-error: aborting due to 17 previous errors
+error: aborting due to 11 previous errors
 
 Some errors have detailed explanations: E0084, E0690, E0691, E0731.
 For more information about an error, try `rustc --explain E0084`.
diff --git a/src/test/ui/resolve/use_suggestion_placement.fixed b/src/test/ui/resolve/use_suggestion_placement.fixed
new file mode 100644
index 00000000000..63676327aa0
--- /dev/null
+++ b/src/test/ui/resolve/use_suggestion_placement.fixed
@@ -0,0 +1,39 @@
+// run-rustfix
+#![allow(dead_code)]
+
+use m::A;
+
+use std::collections::HashMap;
+
+macro_rules! y {
+    () => {}
+}
+
+mod m {
+    pub const A: i32 = 0;
+}
+
+mod foo {
+    // FIXME: UsePlacementFinder is broken because active attributes are
+    // removed, and thus the `derive` attribute here is not in the AST.
+    // An inert attribute should work, though.
+    // #[derive(Debug)]
+    use std::path::Path;
+
+#[allow(warnings)]
+    pub struct Foo;
+
+    // test whether the use suggestion isn't
+    // placed into the expansion of `#[derive(Debug)]
+    type Bar = Path; //~ ERROR cannot find
+}
+
+fn main() {
+    y!();
+    let _ = A; //~ ERROR cannot find
+    foo();
+}
+
+fn foo() {
+    type Dict<K, V> = HashMap<K, V>; //~ ERROR cannot find
+}
diff --git a/src/test/ui/resolve/use_suggestion_placement.rs b/src/test/ui/resolve/use_suggestion_placement.rs
index 56d4b8d6d11..ecc74d78167 100644
--- a/src/test/ui/resolve/use_suggestion_placement.rs
+++ b/src/test/ui/resolve/use_suggestion_placement.rs
@@ -1,3 +1,6 @@
+// run-rustfix
+#![allow(dead_code)]
+
 macro_rules! y {
     () => {}
 }
@@ -7,7 +10,11 @@ mod m {
 }
 
 mod foo {
-    #[derive(Debug)]
+    // FIXME: UsePlacementFinder is broken because active attributes are
+    // removed, and thus the `derive` attribute here is not in the AST.
+    // An inert attribute should work, though.
+    // #[derive(Debug)]
+    #[allow(warnings)]
     pub struct Foo;
 
     // test whether the use suggestion isn't
diff --git a/src/test/ui/resolve/use_suggestion_placement.stderr b/src/test/ui/resolve/use_suggestion_placement.stderr
index af0495a57a1..217c08a560b 100644
--- a/src/test/ui/resolve/use_suggestion_placement.stderr
+++ b/src/test/ui/resolve/use_suggestion_placement.stderr
@@ -1,5 +1,5 @@
 error[E0412]: cannot find type `Path` in this scope
-  --> $DIR/use_suggestion_placement.rs:15:16
+  --> $DIR/use_suggestion_placement.rs:22:16
    |
 LL |     type Bar = Path;
    |                ^^^^ not found in this scope
@@ -10,7 +10,7 @@ LL |     use std::path::Path;
    |
 
 error[E0425]: cannot find value `A` in this scope
-  --> $DIR/use_suggestion_placement.rs:20:13
+  --> $DIR/use_suggestion_placement.rs:27:13
    |
 LL |     let _ = A;
    |             ^ not found in this scope
@@ -21,7 +21,7 @@ LL | use m::A;
    |
 
 error[E0412]: cannot find type `HashMap` in this scope
-  --> $DIR/use_suggestion_placement.rs:25:23
+  --> $DIR/use_suggestion_placement.rs:32:23
    |
 LL |     type Dict<K, V> = HashMap<K, V>;
    |                       ^^^^^^^ not found in this scope
diff --git a/src/test/ui/retslot-cast.stderr b/src/test/ui/retslot-cast.stderr
index 9b5f11ce667..798ce1199a9 100644
--- a/src/test/ui/retslot-cast.stderr
+++ b/src/test/ui/retslot-cast.stderr
@@ -1,6 +1,9 @@
 error[E0308]: mismatched types
   --> $DIR/retslot-cast.rs:13:5
    |
+LL |             -> Option<&Iterator<Item=()>> {
+   |                -------------------------- expected `Option<&dyn Iterator<Item = ()>>` because of return type
+...
 LL |     inner(x)
    |     ^^^^^^^^ expected trait `Iterator<Item = ()>`, found trait `Iterator<Item = ()> + Send`
    |
diff --git a/src/test/ui/return/issue-86188-return-not-in-fn-body.rs b/src/test/ui/return/issue-86188-return-not-in-fn-body.rs
new file mode 100644
index 00000000000..4f076fa0693
--- /dev/null
+++ b/src/test/ui/return/issue-86188-return-not-in-fn-body.rs
@@ -0,0 +1,41 @@
+// Due to a compiler bug, if a return occurs outside of a function body
+// (e.g. in an AnonConst body), the return value expression would not be
+// type-checked, leading to an ICE. This test checks that the ICE no
+// longer happens, and that an appropriate error message is issued that
+// also explains why the return is considered "outside of a function body"
+// if it seems to be inside one, as in the main function below.
+
+const C: [(); 42] = {
+    [(); return || {
+    //~^ ERROR: return statement outside of function body [E0572]
+        let tx;
+    }]
+};
+
+struct S {}
+trait Tr {
+    fn foo();
+    fn bar() {
+    //~^ NOTE: ...not the enclosing function body
+        [(); return];
+        //~^ ERROR: return statement outside of function body [E0572]
+        //~| NOTE: the return is part of this body...
+    }
+}
+impl Tr for S {
+    fn foo() {
+    //~^ NOTE: ...not the enclosing function body
+        [(); return];
+        //~^ ERROR: return statement outside of function body [E0572]
+        //~| NOTE: the return is part of this body...
+    }
+}
+
+fn main() {
+//~^ NOTE: ...not the enclosing function body
+    [(); return || {
+    //~^ ERROR: return statement outside of function body [E0572]
+    //~| NOTE: the return is part of this body...
+        let tx;
+    }];
+}
diff --git a/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr b/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr
new file mode 100644
index 00000000000..d7eeb3a7290
--- /dev/null
+++ b/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr
@@ -0,0 +1,52 @@
+error[E0572]: return statement outside of function body
+  --> $DIR/issue-86188-return-not-in-fn-body.rs:9:10
+   |
+LL |       [(); return || {
+   |  __________^
+LL | |
+LL | |         let tx;
+LL | |     }]
+   | |_____^
+
+error[E0572]: return statement outside of function body
+  --> $DIR/issue-86188-return-not-in-fn-body.rs:20:14
+   |
+LL | /     fn bar() {
+LL | |
+LL | |         [(); return];
+   | |              ^^^^^^ the return is part of this body...
+LL | |
+LL | |
+LL | |     }
+   | |_____- ...not the enclosing function body
+
+error[E0572]: return statement outside of function body
+  --> $DIR/issue-86188-return-not-in-fn-body.rs:28:14
+   |
+LL | /     fn foo() {
+LL | |
+LL | |         [(); return];
+   | |              ^^^^^^ the return is part of this body...
+LL | |
+LL | |
+LL | |     }
+   | |_____- ...not the enclosing function body
+
+error[E0572]: return statement outside of function body
+  --> $DIR/issue-86188-return-not-in-fn-body.rs:36:10
+   |
+LL |  / fn main() {
+LL |  |
+LL |  |     [(); return || {
+   |  |__________^
+LL | ||
+LL | ||
+LL | ||         let tx;
+LL | ||     }];
+   | ||_____^ the return is part of this body...
+LL |  | }
+   |  |_- ...not the enclosing function body
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0572`.
diff --git a/src/test/ui/return/return-match-array-const.rs b/src/test/ui/return/return-match-array-const.rs
index f21eac37c17..b619a4d57f9 100644
--- a/src/test/ui/return/return-match-array-const.rs
+++ b/src/test/ui/return/return-match-array-const.rs
@@ -1,10 +1,19 @@
 fn main() {
+//~^ NOTE: not the enclosing function body
+//~| NOTE: not the enclosing function body
+//~| NOTE: not the enclosing function body
     [(); return match 0 { n => n }];
-    //~^ ERROR: return statement outside of function body
+    //~^ ERROR: return statement outside of function body [E0572]
+    //~| NOTE: the return is part of this body...
 
     [(); return match 0 { 0 => 0 }];
-    //~^ ERROR: return statement outside of function body
+    //~^ ERROR: return statement outside of function body [E0572]
+    //~| NOTE: the return is part of this body...
 
     [(); return match () { 'a' => 0, _ => 0 }];
-    //~^ ERROR: return statement outside of function body
+    //~^ ERROR: return statement outside of function body [E0572]
+    //~| NOTE: the return is part of this body...
+    //~| ERROR: mismatched types [E0308]
+    //~| NOTE: expected `()`, found `char`
+    //~| NOTE: this expression has type `()`
 }
diff --git a/src/test/ui/return/return-match-array-const.stderr b/src/test/ui/return/return-match-array-const.stderr
index 8e801e3fbb7..85a733adfee 100644
--- a/src/test/ui/return/return-match-array-const.stderr
+++ b/src/test/ui/return/return-match-array-const.stderr
@@ -1,21 +1,56 @@
 error[E0572]: return statement outside of function body
-  --> $DIR/return-match-array-const.rs:2:10
+  --> $DIR/return-match-array-const.rs:5:10
    |
-LL |     [(); return match 0 { n => n }];
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+LL | |     [(); return match 0 { n => n }];
+   | |          ^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body...
+...  |
+LL | |
+LL | | }
+   | |_- ...not the enclosing function body
 
 error[E0572]: return statement outside of function body
-  --> $DIR/return-match-array-const.rs:5:10
+  --> $DIR/return-match-array-const.rs:9:10
    |
-LL |     [(); return match 0 { 0 => 0 }];
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     [(); return match 0 { 0 => 0 }];
+   | |          ^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body...
+...  |
+LL | |
+LL | | }
+   | |_- ...not the enclosing function body
 
 error[E0572]: return statement outside of function body
-  --> $DIR/return-match-array-const.rs:8:10
+  --> $DIR/return-match-array-const.rs:13:10
+   |
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     [(); return match () { 'a' => 0, _ => 0 }];
+   | |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body...
+...  |
+LL | |
+LL | | }
+   | |_- ...not the enclosing function body
+
+error[E0308]: mismatched types
+  --> $DIR/return-match-array-const.rs:13:28
    |
 LL |     [(); return match () { 'a' => 0, _ => 0 }];
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       --   ^^^ expected `()`, found `char`
+   |                       |
+   |                       this expression has type `()`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0572`.
+Some errors have detailed explanations: E0308, E0572.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
new file mode 100644
index 00000000000..4285eaf18aa
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
@@ -0,0 +1,22 @@
+#![feature(const_trait_impl)]
+#![allow(incomplete_features)]
+
+pub trait MyTrait {
+    fn func(self);
+}
+
+pub struct NonConst;
+
+impl MyTrait for NonConst {
+    fn func(self) {
+
+    }
+}
+
+pub struct Const;
+
+impl const MyTrait for Const {
+    fn func(self) {
+
+    }
+}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
new file mode 100644
index 00000000000..734ce17001e
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
@@ -0,0 +1,22 @@
+#![feature(const_trait_impl)]
+#![allow(incomplete_features)]
+
+#![feature(staged_api)]
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait MyTrait {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn func();
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Unstable;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "staged", issue = "none")]
+impl const MyTrait for Unstable {
+    fn func() {
+
+    }
+}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs
index ec6f45f956d..44814b0654e 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs
@@ -17,6 +17,9 @@ impl const PartialEq for Int {
     fn eq(&self, rhs: &Self) -> bool {
         self.0 == rhs.0
     }
+    fn ne(&self, other: &Self) -> bool {
+        !self.eq(other)
+    }
 }
 
 pub trait Plus {
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs
index c37990b1af3..47eed89d03d 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs
@@ -12,6 +12,9 @@ impl const PartialEq for S {
     fn eq(&self, _: &S) -> bool {
         true
     }
+    fn ne(&self, other: &S) -> bool {
+        !self.eq(other)
+    }
 }
 
 const fn equals_self<T: PartialEq>(t: &T) -> bool {
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs
index d553b2ab8ec..00a3c7f51fe 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs
@@ -11,6 +11,9 @@ impl const PartialEq for S {
     fn eq(&self, _: &S) -> bool {
         true
     }
+    fn ne(&self, other: &S) -> bool {
+        !self.eq(other)
+    }
 }
 
 // This duplicate bound should not result in ambiguities. It should be equivalent to a single const
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs
index 74b0d5fbe47..953a6511199 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs
@@ -12,6 +12,9 @@ impl const PartialEq for S {
     fn eq(&self, _: &S) -> bool {
         true
     }
+    fn ne(&self, other: &S) -> bool {
+        !self.eq(other)
+    }
 }
 
 const fn equals_self<T: PartialEq>(t: &T) -> bool {
diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr
new file mode 100644
index 00000000000..30baa385475
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr
@@ -0,0 +1,9 @@
+error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+  --> $DIR/cross-crate.rs:16:5
+   |
+LL |     NonConst.func();
+   |     ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.rs b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.rs
new file mode 100644
index 00000000000..c28ff638958
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.rs
@@ -0,0 +1,22 @@
+// revisions: stock gated
+#![cfg_attr(gated, feature(const_trait_impl))]
+#![allow(incomplete_features)]
+
+// aux-build: cross-crate.rs
+extern crate cross_crate;
+
+use cross_crate::*;
+
+fn non_const_context() {
+    NonConst.func();
+    Const.func();
+}
+
+const fn const_context() {
+    NonConst.func();
+    //~^ ERROR: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+    Const.func();
+    //[stock]~^ ERROR: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr
new file mode 100644
index 00000000000..e6a86f251ca
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr
@@ -0,0 +1,15 @@
+error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+  --> $DIR/cross-crate.rs:16:5
+   |
+LL |     NonConst.func();
+   |     ^^^^^^^^^^^^^^^
+
+error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+  --> $DIR/cross-crate.rs:18:5
+   |
+LL |     Const.func();
+   |     ^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.rs b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.rs
new file mode 100644
index 00000000000..4ff4fa0d83b
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.rs
@@ -0,0 +1,20 @@
+#![feature(const_trait_impl)]
+#![allow(incomplete_features)]
+
+trait Tr {
+    fn req(&self);
+
+    fn prov(&self) {
+        println!("lul");
+        self.req();
+    }
+}
+
+struct S;
+
+impl const Tr for S {
+    fn req(&self) {}
+}
+//~^^^ ERROR const trait implementations may not use default functions
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.stderr b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.stderr
new file mode 100644
index 00000000000..51a7b18fa8d
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.stderr
@@ -0,0 +1,10 @@
+error: const trait implementations may not use default functions
+  --> $DIR/impl-with-default-fn.rs:15:1
+   |
+LL | / impl const Tr for S {
+LL | |     fn req(&self) {}
+LL | | }
+   | |_^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api.rs b/src/test/ui/rfc-2632-const-trait-impl/staged-api.rs
new file mode 100644
index 00000000000..39a1b6066de
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/staged-api.rs
@@ -0,0 +1,39 @@
+// revisions: stock staged
+#![cfg_attr(staged, feature(staged))]
+
+#![feature(const_trait_impl)]
+#![allow(incomplete_features)]
+
+#![feature(staged_api)]
+#![stable(feature = "rust1", since = "1.0.0")]
+
+// aux-build: staged-api.rs
+extern crate staged_api;
+
+use staged_api::*;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Stable;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(staged, rustc_const_stable(feature = "rust1", since = "1.0.0"))]
+// ^ should trigger error with or without the attribute
+impl const MyTrait for Stable {
+    fn func() { //~ ERROR trait methods cannot be stable const fn
+
+    }
+}
+
+fn non_const_context() {
+    Unstable::func();
+    Stable::func();
+}
+
+#[unstable(feature = "none", issue = "none")]
+const fn const_context() {
+    Unstable::func();
+    //[stock]~^ ERROR `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
+    Stable::func();
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api.staged.stderr b/src/test/ui/rfc-2632-const-trait-impl/staged-api.staged.stderr
new file mode 100644
index 00000000000..d2ff4ce2001
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/staged-api.staged.stderr
@@ -0,0 +1,10 @@
+error: trait methods cannot be stable const fn
+  --> $DIR/staged-api.rs:22:5
+   |
+LL | /     fn func() {
+LL | |
+LL | |     }
+   | |_____^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/staged-api.stock.stderr
new file mode 100644
index 00000000000..91c5469bd90
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/staged-api.stock.stderr
@@ -0,0 +1,18 @@
+error: trait methods cannot be stable const fn
+  --> $DIR/staged-api.rs:22:5
+   |
+LL | /     fn func() {
+LL | |
+LL | |     }
+   | |_____^
+
+error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
+  --> $DIR/staged-api.rs:34:5
+   |
+LL |     Unstable::func();
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(staged)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/rust-2018/async-ident-allowed.rs b/src/test/ui/rust-2018/async-ident-allowed.rs
index 9d961214afc..8efcfbb7074 100644
--- a/src/test/ui/rust-2018/async-ident-allowed.rs
+++ b/src/test/ui/rust-2018/async-ident-allowed.rs
@@ -7,5 +7,5 @@
 
 fn main() {
     let async = 3; //~ ERROR: is a keyword
-    //~^ WARN previously accepted
+    //~^ WARN this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2018/async-ident-allowed.stderr b/src/test/ui/rust-2018/async-ident-allowed.stderr
index 43fc3f5e334..5b63eab8e46 100644
--- a/src/test/ui/rust-2018/async-ident-allowed.stderr
+++ b/src/test/ui/rust-2018/async-ident-allowed.stderr
@@ -10,7 +10,7 @@ note: the lint level is defined here
 LL | #![deny(rust_2018_compatibility)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    = note: `#[deny(keyword_idents)]` implied by `#[deny(rust_2018_compatibility)]`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: aborting due to previous error
diff --git a/src/test/ui/rust-2018/async-ident.fixed b/src/test/ui/rust-2018/async-ident.fixed
index 3d6f6ff8c49..f4ae518c71d 100644
--- a/src/test/ui/rust-2018/async-ident.fixed
+++ b/src/test/ui/rust-2018/async-ident.fixed
@@ -5,20 +5,20 @@
 // run-rustfix
 
 fn r#async() {} //~ ERROR async
-//~^ WARN hard error in the 2018 edition
+//~^ WARN this is accepted in the current edition
 
 macro_rules! foo {
     ($foo:ident) => {};
     ($r#async:expr, r#async) => {};
     //~^ ERROR async
     //~| ERROR async
-    //~| WARN hard error in the 2018 edition
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
+    //~| WARN this is accepted in the current edition
 }
 
 foo!(r#async);
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 
 mod dont_lint_raw {
     fn r#async() {}
@@ -27,53 +27,53 @@ mod dont_lint_raw {
 mod async_trait {
     trait r#async {}
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
     struct MyStruct;
     impl r#async for MyStruct {}
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 }
 
 mod async_static {
     static r#async: u32 = 0;
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 }
 
 mod async_const {
     const r#async: u32 = 0;
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 }
 
 struct Foo;
 impl Foo { fn r#async() {} }
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 
 fn main() {
     struct r#async {}
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
     let r#async: r#async = r#async {};
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
     //~| ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
     //~| ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 }
 
 #[macro_export]
 macro_rules! produces_async {
     () => (pub fn r#async() {})
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 }
 
 #[macro_export]
 macro_rules! consumes_async {
     (r#async) => (1)
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2018/async-ident.rs b/src/test/ui/rust-2018/async-ident.rs
index 6e8d33d237d..79c73dafac7 100644
--- a/src/test/ui/rust-2018/async-ident.rs
+++ b/src/test/ui/rust-2018/async-ident.rs
@@ -5,20 +5,20 @@
 // run-rustfix
 
 fn async() {} //~ ERROR async
-//~^ WARN hard error in the 2018 edition
+//~^ WARN this is accepted in the current edition
 
 macro_rules! foo {
     ($foo:ident) => {};
     ($async:expr, async) => {};
     //~^ ERROR async
     //~| ERROR async
-    //~| WARN hard error in the 2018 edition
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
+    //~| WARN this is accepted in the current edition
 }
 
 foo!(async);
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 
 mod dont_lint_raw {
     fn r#async() {}
@@ -27,53 +27,53 @@ mod dont_lint_raw {
 mod async_trait {
     trait async {}
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
     struct MyStruct;
     impl async for MyStruct {}
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 }
 
 mod async_static {
     static async: u32 = 0;
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 }
 
 mod async_const {
     const async: u32 = 0;
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 }
 
 struct Foo;
 impl Foo { fn async() {} }
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 
 fn main() {
     struct async {}
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
     let async: async = async {};
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
     //~| ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
     //~| ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 }
 
 #[macro_export]
 macro_rules! produces_async {
     () => (pub fn async() {})
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 }
 
 #[macro_export]
 macro_rules! consumes_async {
     (async) => (1)
     //~^ ERROR async
-    //~| WARN hard error in the 2018 edition
+    //~| WARN this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2018/async-ident.stderr b/src/test/ui/rust-2018/async-ident.stderr
index 6051c81f77c..6396e9deee2 100644
--- a/src/test/ui/rust-2018/async-ident.stderr
+++ b/src/test/ui/rust-2018/async-ident.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(keyword_idents)]
    |         ^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -18,7 +18,7 @@ error: `async` is a keyword in the 2018 edition
 LL |     ($async:expr, async) => {};
    |       ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -27,7 +27,7 @@ error: `async` is a keyword in the 2018 edition
 LL |     ($async:expr, async) => {};
    |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -36,7 +36,7 @@ error: `async` is a keyword in the 2018 edition
 LL | foo!(async);
    |      ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -45,7 +45,7 @@ error: `async` is a keyword in the 2018 edition
 LL |     trait async {}
    |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -54,7 +54,7 @@ error: `async` is a keyword in the 2018 edition
 LL |     impl async for MyStruct {}
    |          ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -63,7 +63,7 @@ error: `async` is a keyword in the 2018 edition
 LL |     static async: u32 = 0;
    |            ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -72,7 +72,7 @@ error: `async` is a keyword in the 2018 edition
 LL |     const async: u32 = 0;
    |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -81,7 +81,7 @@ error: `async` is a keyword in the 2018 edition
 LL | impl Foo { fn async() {} }
    |               ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -90,7 +90,7 @@ error: `async` is a keyword in the 2018 edition
 LL |     struct async {}
    |            ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -99,7 +99,7 @@ error: `async` is a keyword in the 2018 edition
 LL |     let async: async = async {};
    |         ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -108,7 +108,7 @@ error: `async` is a keyword in the 2018 edition
 LL |     let async: async = async {};
    |                ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -117,7 +117,7 @@ error: `async` is a keyword in the 2018 edition
 LL |     let async: async = async {};
    |                        ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -126,7 +126,7 @@ error: `async` is a keyword in the 2018 edition
 LL |     () => (pub fn async() {})
    |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `async` is a keyword in the 2018 edition
@@ -135,7 +135,7 @@ error: `async` is a keyword in the 2018 edition
 LL |     (async) => (1)
    |      ^^^^^ help: you can use a raw identifier to stay compatible: `r#async`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: aborting due to 15 previous errors
diff --git a/src/test/ui/rust-2018/dyn-keyword.fixed b/src/test/ui/rust-2018/dyn-keyword.fixed
index e9cda1af939..044824cbbd3 100644
--- a/src/test/ui/rust-2018/dyn-keyword.fixed
+++ b/src/test/ui/rust-2018/dyn-keyword.fixed
@@ -6,5 +6,5 @@
 
 fn main() {
     let r#dyn = (); //~ ERROR dyn
-    //~^ WARN hard error in the 2018 edition
+    //~^ WARN this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2018/dyn-keyword.rs b/src/test/ui/rust-2018/dyn-keyword.rs
index bdd3a90cab9..5989cfa1c79 100644
--- a/src/test/ui/rust-2018/dyn-keyword.rs
+++ b/src/test/ui/rust-2018/dyn-keyword.rs
@@ -6,5 +6,5 @@
 
 fn main() {
     let dyn = (); //~ ERROR dyn
-    //~^ WARN hard error in the 2018 edition
+    //~^ WARN this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2018/dyn-keyword.stderr b/src/test/ui/rust-2018/dyn-keyword.stderr
index 0fe11168c44..699242f2dcb 100644
--- a/src/test/ui/rust-2018/dyn-keyword.stderr
+++ b/src/test/ui/rust-2018/dyn-keyword.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(keyword_idents)]
    |         ^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: aborting due to previous error
diff --git a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.fixed b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.fixed
index 76fbfa66031..37847a98ac7 100644
--- a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.fixed
+++ b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.fixed
@@ -8,20 +8,19 @@ mod foo {
         type Bar;
     }
 
-    crate struct Baz { }
+    crate struct Baz {}
 
     impl Foo for Baz {
         type Bar = ();
     }
 }
 
-
 fn main() {
     let _: <foo::Baz as crate::foo::Foo>::Bar = ();
     //~^ ERROR absolute paths must start with
-    //~| this was previously accepted
+    //~| this is accepted in the current edition
 
     let _: <crate::foo::Baz as foo::Foo>::Bar = ();
     //~^ ERROR absolute paths must start with
-    //~| this was previously accepted
+    //~| this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.rs b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.rs
index ace90a180d6..36efa14601d 100644
--- a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.rs
+++ b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.rs
@@ -8,20 +8,19 @@ mod foo {
         type Bar;
     }
 
-    crate struct Baz { }
+    crate struct Baz {}
 
     impl Foo for Baz {
         type Bar = ();
     }
 }
 
-
 fn main() {
     let _: <foo::Baz as ::foo::Foo>::Bar = ();
     //~^ ERROR absolute paths must start with
-    //~| this was previously accepted
+    //~| this is accepted in the current edition
 
     let _: <::foo::Baz as foo::Foo>::Bar = ();
     //~^ ERROR absolute paths must start with
-    //~| this was previously accepted
+    //~| this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr
index 0b400786d35..6f529fa9114 100644
--- a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr
+++ b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr
@@ -1,5 +1,5 @@
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
-  --> $DIR/edition-lint-fully-qualified-paths.rs:20:25
+  --> $DIR/edition-lint-fully-qualified-paths.rs:19:25
    |
 LL |     let _: <foo::Baz as ::foo::Foo>::Bar = ();
    |                         ^^^^^^^^^^ help: use `crate`: `crate::foo::Foo`
@@ -9,16 +9,16 @@ note: the lint level is defined here
    |
 LL | #![deny(absolute_paths_not_starting_with_crate)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
-  --> $DIR/edition-lint-fully-qualified-paths.rs:24:13
+  --> $DIR/edition-lint-fully-qualified-paths.rs:23:13
    |
 LL |     let _: <::foo::Baz as foo::Foo>::Bar = ();
    |             ^^^^^^^^^^ help: use `crate`: `crate::foo::Baz`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed
index 77478e8c608..03d15cea280 100644
--- a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed
+++ b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.fixed
@@ -16,15 +16,15 @@ crate mod foo {
 
 use crate::foo::{bar::{baz::{}}};
 //~^ ERROR absolute paths must start with
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 
 use crate::foo::{bar::{XX, baz::{}}};
 //~^ ERROR absolute paths must start with
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 
 use crate::foo::{bar::{baz::{}, baz1::{}}};
 //~^ ERROR absolute paths must start with
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 
 fn main() {
 }
diff --git a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs
index 69bd4e3a187..d898daaba59 100644
--- a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs
+++ b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.rs
@@ -16,15 +16,15 @@ crate mod foo {
 
 use foo::{bar::{baz::{}}};
 //~^ ERROR absolute paths must start with
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 
 use foo::{bar::{XX, baz::{}}};
 //~^ ERROR absolute paths must start with
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 
 use foo::{bar::{baz::{}, baz1::{}}};
 //~^ ERROR absolute paths must start with
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 
 fn main() {
 }
diff --git a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr
index d554cc28621..54a4fed5cf9 100644
--- a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr
+++ b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(absolute_paths_not_starting_with_crate)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
@@ -18,7 +18,7 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c
 LL | use foo::{bar::{XX, baz::{}}};
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{XX, baz::{}}}`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
@@ -27,7 +27,7 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c
 LL | use foo::{bar::{baz::{}, baz1::{}}};
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}, baz1::{}}}`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/rust-2018/edition-lint-nested-paths.fixed b/src/test/ui/rust-2018/edition-lint-nested-paths.fixed
index da7524a63e2..7c6e4a71a37 100644
--- a/src/test/ui/rust-2018/edition-lint-nested-paths.fixed
+++ b/src/test/ui/rust-2018/edition-lint-nested-paths.fixed
@@ -5,7 +5,7 @@
 
 use crate::foo::{a, b};
 //~^ ERROR absolute paths must start with
-//~| this was previously accepted
+//~| this is accepted in the current edition
 
 mod foo {
     crate fn a() {}
@@ -20,7 +20,7 @@ fn main() {
     {
         use crate::foo::{self as x, c};
         //~^ ERROR absolute paths must start with
-        //~| this was previously accepted
+        //~| this is accepted in the current edition
         x::a();
         c();
     }
diff --git a/src/test/ui/rust-2018/edition-lint-nested-paths.rs b/src/test/ui/rust-2018/edition-lint-nested-paths.rs
index e13b7d00864..3925f76391a 100644
--- a/src/test/ui/rust-2018/edition-lint-nested-paths.rs
+++ b/src/test/ui/rust-2018/edition-lint-nested-paths.rs
@@ -5,7 +5,7 @@
 
 use foo::{a, b};
 //~^ ERROR absolute paths must start with
-//~| this was previously accepted
+//~| this is accepted in the current edition
 
 mod foo {
     crate fn a() {}
@@ -20,7 +20,7 @@ fn main() {
     {
         use foo::{self as x, c};
         //~^ ERROR absolute paths must start with
-        //~| this was previously accepted
+        //~| this is accepted in the current edition
         x::a();
         c();
     }
diff --git a/src/test/ui/rust-2018/edition-lint-nested-paths.stderr b/src/test/ui/rust-2018/edition-lint-nested-paths.stderr
index 040aa4a5480..c2f91e342f5 100644
--- a/src/test/ui/rust-2018/edition-lint-nested-paths.stderr
+++ b/src/test/ui/rust-2018/edition-lint-nested-paths.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(absolute_paths_not_starting_with_crate)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
@@ -18,7 +18,7 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c
 LL |         use foo::{self as x, c};
    |             ^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{self as x, c}`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/rust-2018/edition-lint-paths.fixed b/src/test/ui/rust-2018/edition-lint-paths.fixed
index de16291fea6..f91405929ee 100644
--- a/src/test/ui/rust-2018/edition-lint-paths.fixed
+++ b/src/test/ui/rust-2018/edition-lint-paths.fixed
@@ -11,30 +11,29 @@ pub mod foo {
     use edition_lint_paths;
     use crate::bar::Bar;
     //~^ ERROR absolute
-    //~| WARN this was previously accepted
+    //~| WARN this is accepted in the current edition
     use super::bar::Bar2;
     use crate::bar::Bar3;
 
     use crate::bar;
     //~^ ERROR absolute
-    //~| WARN this was previously accepted
-    use crate::{bar as something_else};
+    //~| WARN this is accepted in the current edition
+    use crate::bar as something_else;
 
-    use crate::{Bar as SomethingElse, main};
+    use crate::{main, Bar as SomethingElse};
     //~^ ERROR absolute
-    //~| WARN this was previously accepted
+    //~| WARN this is accepted in the current edition
 
-    use crate::{Bar as SomethingElse2, main as another_main};
+    use crate::{main as another_main, Bar as SomethingElse2};
 
-    pub fn test() {
-    }
+    pub fn test() {}
 
-    pub trait SomeTrait { }
+    pub trait SomeTrait {}
 }
 
 use crate::bar::Bar;
 //~^ ERROR absolute
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 
 pub mod bar {
     use edition_lint_paths as foo;
@@ -46,17 +45,17 @@ pub mod bar {
 mod baz {
     use crate::*;
     //~^ ERROR absolute
-    //~| WARN this was previously accepted
+    //~| WARN this is accepted in the current edition
 }
 
-impl crate::foo::SomeTrait for u32 { }
+impl crate::foo::SomeTrait for u32 {}
 //~^ ERROR absolute
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 
 fn main() {
     let x = crate::bar::Bar;
     //~^ ERROR absolute
-    //~| WARN this was previously accepted
+    //~| WARN this is accepted in the current edition
     let x = bar::Bar;
     let x = crate::bar::Bar;
     let x = self::bar::Bar;
diff --git a/src/test/ui/rust-2018/edition-lint-paths.rs b/src/test/ui/rust-2018/edition-lint-paths.rs
index c5b4be5a3ac..52c97c7a253 100644
--- a/src/test/ui/rust-2018/edition-lint-paths.rs
+++ b/src/test/ui/rust-2018/edition-lint-paths.rs
@@ -9,32 +9,31 @@ extern crate edition_lint_paths;
 
 pub mod foo {
     use edition_lint_paths;
-    use ::bar::Bar;
+    use bar::Bar;
     //~^ ERROR absolute
-    //~| WARN this was previously accepted
+    //~| WARN this is accepted in the current edition
     use super::bar::Bar2;
     use crate::bar::Bar3;
 
     use bar;
     //~^ ERROR absolute
-    //~| WARN this was previously accepted
-    use crate::{bar as something_else};
+    //~| WARN this is accepted in the current edition
+    use crate::bar as something_else;
 
-    use {Bar as SomethingElse, main};
+    use {main, Bar as SomethingElse};
     //~^ ERROR absolute
-    //~| WARN this was previously accepted
+    //~| WARN this is accepted in the current edition
 
-    use crate::{Bar as SomethingElse2, main as another_main};
+    use crate::{main as another_main, Bar as SomethingElse2};
 
-    pub fn test() {
-    }
+    pub fn test() {}
 
-    pub trait SomeTrait { }
+    pub trait SomeTrait {}
 }
 
 use bar::Bar;
 //~^ ERROR absolute
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 
 pub mod bar {
     use edition_lint_paths as foo;
@@ -46,17 +45,17 @@ pub mod bar {
 mod baz {
     use *;
     //~^ ERROR absolute
-    //~| WARN this was previously accepted
+    //~| WARN this is accepted in the current edition
 }
 
-impl ::foo::SomeTrait for u32 { }
+impl ::foo::SomeTrait for u32 {}
 //~^ ERROR absolute
-//~| WARN this was previously accepted
+//~| WARN this is accepted in the current edition
 
 fn main() {
     let x = ::bar::Bar;
     //~^ ERROR absolute
-    //~| WARN this was previously accepted
+    //~| WARN this is accepted in the current edition
     let x = bar::Bar;
     let x = crate::bar::Bar;
     let x = self::bar::Bar;
diff --git a/src/test/ui/rust-2018/edition-lint-paths.stderr b/src/test/ui/rust-2018/edition-lint-paths.stderr
index dd36d07da56..23deeda14a4 100644
--- a/src/test/ui/rust-2018/edition-lint-paths.stderr
+++ b/src/test/ui/rust-2018/edition-lint-paths.stderr
@@ -1,15 +1,15 @@
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
   --> $DIR/edition-lint-paths.rs:12:9
    |
-LL |     use ::bar::Bar;
-   |         ^^^^^^^^^^ help: use `crate`: `crate::bar::Bar`
+LL |     use bar::Bar;
+   |         ^^^^^^^^ help: use `crate`: `crate::bar::Bar`
    |
 note: the lint level is defined here
   --> $DIR/edition-lint-paths.rs:5:9
    |
 LL | #![deny(absolute_paths_not_starting_with_crate)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
@@ -18,52 +18,52 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c
 LL |     use bar;
    |         ^^^ help: use `crate`: `crate::bar`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
   --> $DIR/edition-lint-paths.rs:23:9
    |
-LL |     use {Bar as SomethingElse, main};
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{Bar as SomethingElse, main}`
+LL |     use {main, Bar as SomethingElse};
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
-  --> $DIR/edition-lint-paths.rs:35:5
+  --> $DIR/edition-lint-paths.rs:34:5
    |
 LL | use bar::Bar;
    |     ^^^^^^^^ help: use `crate`: `crate::bar::Bar`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
-  --> $DIR/edition-lint-paths.rs:47:9
+  --> $DIR/edition-lint-paths.rs:46:9
    |
 LL |     use *;
    |         ^ help: use `crate`: `crate::*`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
-  --> $DIR/edition-lint-paths.rs:52:6
+  --> $DIR/edition-lint-paths.rs:51:6
    |
-LL | impl ::foo::SomeTrait for u32 { }
+LL | impl ::foo::SomeTrait for u32 {}
    |      ^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::SomeTrait`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
-  --> $DIR/edition-lint-paths.rs:57:13
+  --> $DIR/edition-lint-paths.rs:56:13
    |
 LL |     let x = ::bar::Bar;
    |             ^^^^^^^^^^ help: use `crate`: `crate::bar::Bar`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: aborting due to 7 previous errors
diff --git a/src/test/ui/rust-2018/extern-crate-rename.fixed b/src/test/ui/rust-2018/extern-crate-rename.fixed
index c4c9bdf58c3..ea832ef3e7d 100644
--- a/src/test/ui/rust-2018/extern-crate-rename.fixed
+++ b/src/test/ui/rust-2018/extern-crate-rename.fixed
@@ -11,7 +11,7 @@ extern crate edition_lint_paths as my_crate;
 
 use crate::my_crate::foo;
 //~^ ERROR absolute paths must start
-//~| WARNING this was previously accepted
+//~| WARNING this is accepted in the current edition
 
 fn main() {
     foo();
diff --git a/src/test/ui/rust-2018/extern-crate-rename.rs b/src/test/ui/rust-2018/extern-crate-rename.rs
index 8f14f2f1fec..b1f617dd884 100644
--- a/src/test/ui/rust-2018/extern-crate-rename.rs
+++ b/src/test/ui/rust-2018/extern-crate-rename.rs
@@ -11,7 +11,7 @@ extern crate edition_lint_paths as my_crate;
 
 use my_crate::foo;
 //~^ ERROR absolute paths must start
-//~| WARNING this was previously accepted
+//~| WARNING this is accepted in the current edition
 
 fn main() {
     foo();
diff --git a/src/test/ui/rust-2018/extern-crate-rename.stderr b/src/test/ui/rust-2018/extern-crate-rename.stderr
index 6ea762ed999..4bccbc51223 100644
--- a/src/test/ui/rust-2018/extern-crate-rename.stderr
+++ b/src/test/ui/rust-2018/extern-crate-rename.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(absolute_paths_not_starting_with_crate)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: aborting due to previous error
diff --git a/src/test/ui/rust-2018/extern-crate-submod.fixed b/src/test/ui/rust-2018/extern-crate-submod.fixed
index 2a8e24db0bd..9b0b0dd8ee1 100644
--- a/src/test/ui/rust-2018/extern-crate-submod.fixed
+++ b/src/test/ui/rust-2018/extern-crate-submod.fixed
@@ -18,7 +18,7 @@ mod m {
 // *could* rewrite it to `use edition_lint_paths::foo`
 use crate::m::edition_lint_paths::foo;
 //~^ ERROR absolute paths must start
-//~| WARNING this was previously accepted
+//~| WARNING this is accepted in the current edition
 
 fn main() {
     foo();
diff --git a/src/test/ui/rust-2018/extern-crate-submod.rs b/src/test/ui/rust-2018/extern-crate-submod.rs
index f3a357917cc..dfce9128c51 100644
--- a/src/test/ui/rust-2018/extern-crate-submod.rs
+++ b/src/test/ui/rust-2018/extern-crate-submod.rs
@@ -18,7 +18,7 @@ mod m {
 // *could* rewrite it to `use edition_lint_paths::foo`
 use m::edition_lint_paths::foo;
 //~^ ERROR absolute paths must start
-//~| WARNING this was previously accepted
+//~| WARNING this is accepted in the current edition
 
 fn main() {
     foo();
diff --git a/src/test/ui/rust-2018/extern-crate-submod.stderr b/src/test/ui/rust-2018/extern-crate-submod.stderr
index 87a0d492675..3c75319aeda 100644
--- a/src/test/ui/rust-2018/extern-crate-submod.stderr
+++ b/src/test/ui/rust-2018/extern-crate-submod.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(absolute_paths_not_starting_with_crate)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>
 
 error: aborting due to previous error
diff --git a/src/test/ui/rust-2018/try-ident.fixed b/src/test/ui/rust-2018/try-ident.fixed
index 13f6f8e2829..985348665c9 100644
--- a/src/test/ui/rust-2018/try-ident.fixed
+++ b/src/test/ui/rust-2018/try-ident.fixed
@@ -6,10 +6,10 @@
 fn main() {
     r#try();
     //~^ WARNING `try` is a keyword in the 2018 edition
-    //~| WARNING it will become a hard error in the 2018 edition!
+    //~| WARNING this is accepted in the current edition
 }
 
 fn r#try() {
     //~^ WARNING `try` is a keyword in the 2018 edition
-    //~| WARNING it will become a hard error in the 2018 edition!
+    //~| WARNING this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2018/try-ident.rs b/src/test/ui/rust-2018/try-ident.rs
index bed7118011e..2c02b75960e 100644
--- a/src/test/ui/rust-2018/try-ident.rs
+++ b/src/test/ui/rust-2018/try-ident.rs
@@ -6,10 +6,10 @@
 fn main() {
     try();
     //~^ WARNING `try` is a keyword in the 2018 edition
-    //~| WARNING it will become a hard error in the 2018 edition!
+    //~| WARNING this is accepted in the current edition
 }
 
 fn try() {
     //~^ WARNING `try` is a keyword in the 2018 edition
-    //~| WARNING it will become a hard error in the 2018 edition!
+    //~| WARNING this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2018/try-ident.stderr b/src/test/ui/rust-2018/try-ident.stderr
index 2939dc1df70..3d93b433cf2 100644
--- a/src/test/ui/rust-2018/try-ident.stderr
+++ b/src/test/ui/rust-2018/try-ident.stderr
@@ -10,7 +10,7 @@ note: the lint level is defined here
 LL | #![warn(rust_2018_compatibility)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    = note: `#[warn(keyword_idents)]` implied by `#[warn(rust_2018_compatibility)]`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 warning: `try` is a keyword in the 2018 edition
@@ -19,7 +19,7 @@ warning: `try` is a keyword in the 2018 edition
 LL | fn try() {
    |    ^^^ help: you can use a raw identifier to stay compatible: `r#try`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 warning: 2 warnings emitted
diff --git a/src/test/ui/rust-2018/try-macro.fixed b/src/test/ui/rust-2018/try-macro.fixed
index 5c899378b94..3308870f654 100644
--- a/src/test/ui/rust-2018/try-macro.fixed
+++ b/src/test/ui/rust-2018/try-macro.fixed
@@ -11,8 +11,8 @@ fn foo() -> Result<usize, ()> {
     let x: Result<usize, ()> = Ok(22);
     r#try!(x);
     //~^ WARNING `try` is a keyword in the 2018 edition
-    //~| WARNING this was previously accepted
+    //~| WARNING this is accepted in the current edition
     Ok(44)
 }
 
-fn main() { }
+fn main() {}
diff --git a/src/test/ui/rust-2018/try-macro.rs b/src/test/ui/rust-2018/try-macro.rs
index db8a198d282..69e87a1ff62 100644
--- a/src/test/ui/rust-2018/try-macro.rs
+++ b/src/test/ui/rust-2018/try-macro.rs
@@ -11,8 +11,8 @@ fn foo() -> Result<usize, ()> {
     let x: Result<usize, ()> = Ok(22);
     try!(x);
     //~^ WARNING `try` is a keyword in the 2018 edition
-    //~| WARNING this was previously accepted
+    //~| WARNING this is accepted in the current edition
     Ok(44)
 }
 
-fn main() { }
+fn main() {}
diff --git a/src/test/ui/rust-2018/try-macro.stderr b/src/test/ui/rust-2018/try-macro.stderr
index cdbb215605e..f315b4d4a9e 100644
--- a/src/test/ui/rust-2018/try-macro.stderr
+++ b/src/test/ui/rust-2018/try-macro.stderr
@@ -10,7 +10,7 @@ note: the lint level is defined here
 LL | #![warn(rust_2018_compatibility)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    = note: `#[warn(keyword_idents)]` implied by `#[warn(rust_2018_compatibility)]`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 warning: 1 warning emitted
diff --git a/src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2018.rs b/src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2018.rs
new file mode 100644
index 00000000000..eb301e5e1be
--- /dev/null
+++ b/src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2018.rs
@@ -0,0 +1,25 @@
+// force-host
+// edition:2018
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+use std::str::FromStr;
+
+#[proc_macro]
+pub fn number_of_tokens_in_a_prefixed_integer_literal(_: TokenStream) -> TokenStream {
+    TokenStream::from_str("hey#123").unwrap().into_iter().count().to_string().parse().unwrap()
+}
+
+#[proc_macro]
+pub fn number_of_tokens_in_a_prefixed_char_literal(_: TokenStream) -> TokenStream {
+    TokenStream::from_str("hey#'a'").unwrap().into_iter().count().to_string().parse().unwrap()
+}
+
+#[proc_macro]
+pub fn number_of_tokens_in_a_prefixed_string_literal(_: TokenStream) -> TokenStream {
+    TokenStream::from_str("hey#\"abc\"").unwrap().into_iter().count().to_string().parse().unwrap()
+}
diff --git a/src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2021.rs b/src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2021.rs
new file mode 100644
index 00000000000..691bfdc15c3
--- /dev/null
+++ b/src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2021.rs
@@ -0,0 +1,25 @@
+// force-host
+// edition:2021
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+use std::str::FromStr;
+
+#[proc_macro]
+pub fn number_of_tokens_in_a_prefixed_integer_literal(_: TokenStream) -> TokenStream {
+    TokenStream::from_str("hey#123").unwrap().into_iter().count().to_string().parse().unwrap()
+}
+
+#[proc_macro]
+pub fn number_of_tokens_in_a_prefixed_char_literal(_: TokenStream) -> TokenStream {
+    TokenStream::from_str("hey#'a'").unwrap().into_iter().count().to_string().parse().unwrap()
+}
+
+#[proc_macro]
+pub fn number_of_tokens_in_a_prefixed_string_literal(_: TokenStream) -> TokenStream {
+    TokenStream::from_str("hey#\"abc\"").unwrap().into_iter().count().to_string().parse().unwrap()
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.fixed b/src/test/ui/rust-2021/future-prelude-collision-imported.fixed
index 4f8fd9b345b..725d5aa234e 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-imported.fixed
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.fixed
@@ -26,7 +26,7 @@ mod a {
         // In this case, we can just use `TryIntoU32`
         let _: u32 = TryIntoU32::try_into(3u8).unwrap();
         //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-        //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+        //~^^ WARNING this is accepted in the current edition
     }
 }
 
@@ -39,7 +39,7 @@ mod b {
         // the path `crate::m::TryIntoU32` (with which it was imported).
         let _: u32 = crate::m::TryIntoU32::try_into(3u8).unwrap();
         //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-        //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+        //~^^ WARNING this is accepted in the current edition
     }
 }
 
@@ -52,7 +52,7 @@ mod c {
         // the path `super::m::TryIntoU32` (with which it was imported).
         let _: u32 = super::m::TryIntoU32::try_into(3u8).unwrap();
         //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-        //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+        //~^^ WARNING this is accepted in the current edition
     }
 }
 
diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.rs b/src/test/ui/rust-2021/future-prelude-collision-imported.rs
index 2ce1be6151b..6ca9a919f3c 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-imported.rs
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.rs
@@ -26,7 +26,7 @@ mod a {
         // In this case, we can just use `TryIntoU32`
         let _: u32 = 3u8.try_into().unwrap();
         //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-        //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+        //~^^ WARNING this is accepted in the current edition
     }
 }
 
@@ -39,7 +39,7 @@ mod b {
         // the path `crate::m::TryIntoU32` (with which it was imported).
         let _: u32 = 3u8.try_into().unwrap();
         //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-        //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+        //~^^ WARNING this is accepted in the current edition
     }
 }
 
@@ -52,7 +52,7 @@ mod c {
         // the path `super::m::TryIntoU32` (with which it was imported).
         let _: u32 = 3u8.try_into().unwrap();
         //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-        //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+        //~^^ WARNING this is accepted in the current edition
     }
 }
 
diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.stderr b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr
index 3903cbfe824..8889485c917 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-imported.stderr
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![warn(future_prelude_collision)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: trait method `try_into` will become ambiguous in Rust 2021
@@ -18,7 +18,7 @@ warning: trait method `try_into` will become ambiguous in Rust 2021
 LL |         let _: u32 = 3u8.try_into().unwrap();
    |                      ^^^^^^^^^^^^^^ help: disambiguate the associated function: `crate::m::TryIntoU32::try_into(3u8)`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: trait method `try_into` will become ambiguous in Rust 2021
@@ -27,7 +27,7 @@ warning: trait method `try_into` will become ambiguous in Rust 2021
 LL |         let _: u32 = 3u8.try_into().unwrap();
    |                      ^^^^^^^^^^^^^^ help: disambiguate the associated function: `super::m::TryIntoU32::try_into(3u8)`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: 3 warnings emitted
diff --git a/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs b/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs
new file mode 100644
index 00000000000..a4a5b6667df
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs
@@ -0,0 +1,16 @@
+// edition:2018
+// check-pass
+#![allow(unused)]
+#![deny(future_prelude_collision)]
+
+struct S;
+
+impl S {
+    fn try_into(self) -> S { S }
+}
+
+// See https://github.com/rust-lang/rust/issues/86633
+fn main() {
+    let s = S;
+    let s2 = s.try_into();
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision.fixed b/src/test/ui/rust-2021/future-prelude-collision.fixed
index 9ede9f3a2fb..4bcbe6b094a 100644
--- a/src/test/ui/rust-2021/future-prelude-collision.fixed
+++ b/src/test/ui/rust-2021/future-prelude-collision.fixed
@@ -38,12 +38,14 @@ impl TryIntoU32 for *const u16 {
 
 trait FromByteIterator {
     fn from_iter<T>(iter: T) -> Self
-        where T: Iterator<Item = u8>;
+    where
+        T: Iterator<Item = u8>;
 }
 
 impl FromByteIterator for Vec<u8> {
     fn from_iter<T>(iter: T) -> Self
-        where T: Iterator<Item = u8>
+    where
+        T: Iterator<Item = u8>,
     {
         iter.collect()
     }
@@ -53,17 +55,17 @@ fn main() {
     // test dot-call that will break in 2021 edition
     let _: u32 = TryIntoU32::try_into(3u8).unwrap();
     //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     // test associated function call that will break in 2021 edition
     let _ = <u32 as TryFromU8>::try_from(3u8).unwrap();
     //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     // test reverse turbofish too
     let _ = <Vec<u8> as FromByteIterator>::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter());
     //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     // negative testing lint (this line should *not* emit a warning)
     let _: u32 = TryFromU8::try_from(3u8).unwrap();
@@ -71,26 +73,26 @@ fn main() {
     // test type omission
     let _: u32 = <_ as TryFromU8>::try_from(3u8).unwrap();
     //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     // test autoderef
     let _: u32 = TryIntoU32::try_into(*(&3u8)).unwrap();
     //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     // test autoref
     let _: u32 = TryIntoU32::try_into(&3.0).unwrap();
     //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     let mut data = 3u16;
     let mut_ptr = std::ptr::addr_of_mut!(data);
     let _: u32 = TryIntoU32::try_into(mut_ptr as *const _).unwrap();
     //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     type U32Alias = u32;
     let _ = <U32Alias as TryFromU8>::try_from(3u8).unwrap();
     //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2021/future-prelude-collision.rs b/src/test/ui/rust-2021/future-prelude-collision.rs
index 914e910396a..bc23a8a92a6 100644
--- a/src/test/ui/rust-2021/future-prelude-collision.rs
+++ b/src/test/ui/rust-2021/future-prelude-collision.rs
@@ -38,12 +38,14 @@ impl TryIntoU32 for *const u16 {
 
 trait FromByteIterator {
     fn from_iter<T>(iter: T) -> Self
-        where T: Iterator<Item = u8>;
+    where
+        T: Iterator<Item = u8>;
 }
 
 impl FromByteIterator for Vec<u8> {
     fn from_iter<T>(iter: T) -> Self
-        where T: Iterator<Item = u8>
+    where
+        T: Iterator<Item = u8>,
     {
         iter.collect()
     }
@@ -53,17 +55,17 @@ fn main() {
     // test dot-call that will break in 2021 edition
     let _: u32 = 3u8.try_into().unwrap();
     //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     // test associated function call that will break in 2021 edition
     let _ = u32::try_from(3u8).unwrap();
     //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     // test reverse turbofish too
     let _ = <Vec<u8>>::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter());
     //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     // negative testing lint (this line should *not* emit a warning)
     let _: u32 = TryFromU8::try_from(3u8).unwrap();
@@ -71,26 +73,26 @@ fn main() {
     // test type omission
     let _: u32 = <_>::try_from(3u8).unwrap();
     //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     // test autoderef
     let _: u32 = (&3u8).try_into().unwrap();
     //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     // test autoref
     let _: u32 = 3.0.try_into().unwrap();
     //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     let mut data = 3u16;
     let mut_ptr = std::ptr::addr_of_mut!(data);
     let _: u32 = mut_ptr.try_into().unwrap();
     //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 
     type U32Alias = u32;
     let _ = U32Alias::try_from(3u8).unwrap();
     //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2021/future-prelude-collision.stderr b/src/test/ui/rust-2021/future-prelude-collision.stderr
index 190145ef4db..e167468ab19 100644
--- a/src/test/ui/rust-2021/future-prelude-collision.stderr
+++ b/src/test/ui/rust-2021/future-prelude-collision.stderr
@@ -1,5 +1,5 @@
 warning: trait method `try_into` will become ambiguous in Rust 2021
-  --> $DIR/future-prelude-collision.rs:54:18
+  --> $DIR/future-prelude-collision.rs:56:18
    |
 LL |     let _: u32 = 3u8.try_into().unwrap();
    |                  ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)`
@@ -9,70 +9,70 @@ note: the lint level is defined here
    |
 LL | #![warn(future_prelude_collision)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: trait-associated function `try_from` will become ambiguous in Rust 2021
-  --> $DIR/future-prelude-collision.rs:59:13
+  --> $DIR/future-prelude-collision.rs:61:13
    |
 LL |     let _ = u32::try_from(3u8).unwrap();
    |             ^^^^^^^^^^^^^ help: disambiguate the associated function: `<u32 as TryFromU8>::try_from`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
-  --> $DIR/future-prelude-collision.rs:64:13
+  --> $DIR/future-prelude-collision.rs:66:13
    |
 LL |     let _ = <Vec<u8>>::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter());
    |             ^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Vec<u8> as FromByteIterator>::from_iter`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: trait-associated function `try_from` will become ambiguous in Rust 2021
-  --> $DIR/future-prelude-collision.rs:72:18
+  --> $DIR/future-prelude-collision.rs:74:18
    |
 LL |     let _: u32 = <_>::try_from(3u8).unwrap();
    |                  ^^^^^^^^^^^^^ help: disambiguate the associated function: `<_ as TryFromU8>::try_from`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: trait method `try_into` will become ambiguous in Rust 2021
-  --> $DIR/future-prelude-collision.rs:77:18
+  --> $DIR/future-prelude-collision.rs:79:18
    |
 LL |     let _: u32 = (&3u8).try_into().unwrap();
    |                  ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(*(&3u8))`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: trait method `try_into` will become ambiguous in Rust 2021
-  --> $DIR/future-prelude-collision.rs:82:18
+  --> $DIR/future-prelude-collision.rs:84:18
    |
 LL |     let _: u32 = 3.0.try_into().unwrap();
    |                  ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(&3.0)`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: trait method `try_into` will become ambiguous in Rust 2021
-  --> $DIR/future-prelude-collision.rs:88:18
+  --> $DIR/future-prelude-collision.rs:90:18
    |
 LL |     let _: u32 = mut_ptr.try_into().unwrap();
    |                  ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(mut_ptr as *const _)`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: trait-associated function `try_from` will become ambiguous in Rust 2021
-  --> $DIR/future-prelude-collision.rs:93:13
+  --> $DIR/future-prelude-collision.rs:95:13
    |
 LL |     let _ = U32Alias::try_from(3u8).unwrap();
    |             ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<U32Alias as TryFromU8>::try_from`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: 8 warnings emitted
diff --git a/src/test/ui/rust-2021/generic-type-collision.fixed b/src/test/ui/rust-2021/generic-type-collision.fixed
index 00fb128a981..d1a085f23a0 100644
--- a/src/test/ui/rust-2021/generic-type-collision.fixed
+++ b/src/test/ui/rust-2021/generic-type-collision.fixed
@@ -14,5 +14,5 @@ impl<T> MyTrait<()> for Vec<T> {
 fn main() {
     <Vec<i32> as MyTrait<_>>::from_iter(None);
     //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2021/generic-type-collision.rs b/src/test/ui/rust-2021/generic-type-collision.rs
index 406fba4d247..5069fba396e 100644
--- a/src/test/ui/rust-2021/generic-type-collision.rs
+++ b/src/test/ui/rust-2021/generic-type-collision.rs
@@ -14,5 +14,5 @@ impl<T> MyTrait<()> for Vec<T> {
 fn main() {
     <Vec<i32>>::from_iter(None);
     //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
-    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    //~^^ WARNING this is accepted in the current edition
 }
diff --git a/src/test/ui/rust-2021/generic-type-collision.stderr b/src/test/ui/rust-2021/generic-type-collision.stderr
index 9374379d247..05591c3d448 100644
--- a/src/test/ui/rust-2021/generic-type-collision.stderr
+++ b/src/test/ui/rust-2021/generic-type-collision.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![warn(future_prelude_collision)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: 1 warning emitted
diff --git a/src/test/ui/rust-2021/inherent-dyn-collision.fixed b/src/test/ui/rust-2021/inherent-dyn-collision.fixed
index cbb6e9659df..cf6287a758f 100644
--- a/src/test/ui/rust-2021/inherent-dyn-collision.fixed
+++ b/src/test/ui/rust-2021/inherent-dyn-collision.fixed
@@ -40,7 +40,7 @@ mod inner {
     pub fn test() -> u32 {
         (&*get_dyn_trait()).try_into().unwrap()
         //~^ WARNING trait method `try_into` will become ambiguous
-        //~| WARNING this was previously accepted
+        //~| WARNING this is accepted in the current edition
     }
 }
 
diff --git a/src/test/ui/rust-2021/inherent-dyn-collision.rs b/src/test/ui/rust-2021/inherent-dyn-collision.rs
index 1c9929eff91..0349ad5b641 100644
--- a/src/test/ui/rust-2021/inherent-dyn-collision.rs
+++ b/src/test/ui/rust-2021/inherent-dyn-collision.rs
@@ -40,7 +40,7 @@ mod inner {
     pub fn test() -> u32 {
         get_dyn_trait().try_into().unwrap()
         //~^ WARNING trait method `try_into` will become ambiguous
-        //~| WARNING this was previously accepted
+        //~| WARNING this is accepted in the current edition
     }
 }
 
diff --git a/src/test/ui/rust-2021/inherent-dyn-collision.stderr b/src/test/ui/rust-2021/inherent-dyn-collision.stderr
index 3d7637100c2..9e95419715e 100644
--- a/src/test/ui/rust-2021/inherent-dyn-collision.stderr
+++ b/src/test/ui/rust-2021/inherent-dyn-collision.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![warn(future_prelude_collision)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
 
 warning: 1 warning emitted
diff --git a/src/test/ui/rust-2021/reserved-prefixes-migration.fixed b/src/test/ui/rust-2021/reserved-prefixes-migration.fixed
new file mode 100644
index 00000000000..dbc2ec6d42e
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes-migration.fixed
@@ -0,0 +1,38 @@
+// check-pass
+// run-rustfix
+// compile-flags: -Z unstable-options --edition 2018
+
+#![warn(reserved_prefix)]
+
+macro_rules! m2 {
+    ($a:tt $b:tt) => {};
+}
+
+macro_rules! m3 {
+    ($a:tt $b:tt $c:tt) => {};
+}
+
+fn main() {
+    m2!(z "hey");
+    //~^ WARNING prefix `z` is unknown [reserved_prefix]
+    //~| WARNING hard error in Rust 2021
+    m2!(prefix "hey");
+    //~^ WARNING prefix `prefix` is unknown [reserved_prefix]
+    //~| WARNING hard error in Rust 2021
+    m3!(hey #123);
+    //~^ WARNING prefix `hey` is unknown [reserved_prefix]
+    //~| WARNING hard error in Rust 2021
+    m3!(hey #hey);
+    //~^ WARNING prefix `hey` is unknown [reserved_prefix]
+    //~| WARNING hard error in Rust 2021
+}
+
+macro_rules! quote {
+    (# name = # kind # value) => {};
+}
+
+quote! {
+    #name = #kind #value
+    //~^ WARNING prefix `kind` is unknown [reserved_prefix]
+    //~| WARNING hard error in Rust 2021
+}
diff --git a/src/test/ui/rust-2021/reserved-prefixes-migration.rs b/src/test/ui/rust-2021/reserved-prefixes-migration.rs
new file mode 100644
index 00000000000..6f7e3eb7a43
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes-migration.rs
@@ -0,0 +1,38 @@
+// check-pass
+// run-rustfix
+// compile-flags: -Z unstable-options --edition 2018
+
+#![warn(reserved_prefix)]
+
+macro_rules! m2 {
+    ($a:tt $b:tt) => {};
+}
+
+macro_rules! m3 {
+    ($a:tt $b:tt $c:tt) => {};
+}
+
+fn main() {
+    m2!(z"hey");
+    //~^ WARNING prefix `z` is unknown [reserved_prefix]
+    //~| WARNING hard error in Rust 2021
+    m2!(prefix"hey");
+    //~^ WARNING prefix `prefix` is unknown [reserved_prefix]
+    //~| WARNING hard error in Rust 2021
+    m3!(hey#123);
+    //~^ WARNING prefix `hey` is unknown [reserved_prefix]
+    //~| WARNING hard error in Rust 2021
+    m3!(hey#hey);
+    //~^ WARNING prefix `hey` is unknown [reserved_prefix]
+    //~| WARNING hard error in Rust 2021
+}
+
+macro_rules! quote {
+    (# name = # kind # value) => {};
+}
+
+quote! {
+    #name = #kind#value
+    //~^ WARNING prefix `kind` is unknown [reserved_prefix]
+    //~| WARNING hard error in Rust 2021
+}
diff --git a/src/test/ui/rust-2021/reserved-prefixes-migration.stderr b/src/test/ui/rust-2021/reserved-prefixes-migration.stderr
new file mode 100644
index 00000000000..28ac1966a1b
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes-migration.stderr
@@ -0,0 +1,72 @@
+warning: prefix `z` is unknown
+  --> $DIR/reserved-prefixes-migration.rs:16:9
+   |
+LL |     m2!(z"hey");
+   |         ^ unknown prefix
+   |
+note: the lint level is defined here
+  --> $DIR/reserved-prefixes-migration.rs:5:9
+   |
+LL | #![warn(reserved_prefix)]
+   |         ^^^^^^^^^^^^^^^
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see issue #84978 <https://github.com/rust-lang/rust/issues/84978>
+help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
+   |
+LL |     m2!(z "hey");
+   |          --
+
+warning: prefix `prefix` is unknown
+  --> $DIR/reserved-prefixes-migration.rs:19:9
+   |
+LL |     m2!(prefix"hey");
+   |         ^^^^^^ unknown prefix
+   |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see issue #84978 <https://github.com/rust-lang/rust/issues/84978>
+help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
+   |
+LL |     m2!(prefix "hey");
+   |               --
+
+warning: prefix `hey` is unknown
+  --> $DIR/reserved-prefixes-migration.rs:22:9
+   |
+LL |     m3!(hey#123);
+   |         ^^^ unknown prefix
+   |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see issue #84978 <https://github.com/rust-lang/rust/issues/84978>
+help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
+   |
+LL |     m3!(hey #123);
+   |            --
+
+warning: prefix `hey` is unknown
+  --> $DIR/reserved-prefixes-migration.rs:25:9
+   |
+LL |     m3!(hey#hey);
+   |         ^^^ unknown prefix
+   |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see issue #84978 <https://github.com/rust-lang/rust/issues/84978>
+help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
+   |
+LL |     m3!(hey #hey);
+   |            --
+
+warning: prefix `kind` is unknown
+  --> $DIR/reserved-prefixes-migration.rs:35:14
+   |
+LL |     #name = #kind#value
+   |              ^^^^ unknown prefix
+   |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see issue #84978 <https://github.com/rust-lang/rust/issues/84978>
+help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
+   |
+LL |     #name = #kind #value
+   |                  --
+
+warning: 5 warnings emitted
+
diff --git a/src/test/ui/rust-2021/reserved-prefixes-via-macro-2.rs b/src/test/ui/rust-2021/reserved-prefixes-via-macro-2.rs
new file mode 100644
index 00000000000..74f20660613
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes-via-macro-2.rs
@@ -0,0 +1,21 @@
+// edition:2018
+// aux-build:reserved-prefixes-macro-2018.rs
+// aux-build:reserved-prefixes-macro-2021.rs
+
+extern crate reserved_prefixes_macro_2018 as m2018;
+extern crate reserved_prefixes_macro_2021 as m2021;
+
+fn main() {
+    // Ok:
+    m2018::number_of_tokens_in_a_prefixed_integer_literal!();
+    m2018::number_of_tokens_in_a_prefixed_char_literal!();
+    m2018::number_of_tokens_in_a_prefixed_string_literal!();
+
+    // Error, even though *this* crate is 2018:
+    m2021::number_of_tokens_in_a_prefixed_integer_literal!();
+    //~^ ERROR prefix `hey` is unknown
+    m2021::number_of_tokens_in_a_prefixed_char_literal!();
+    //~^ ERROR prefix `hey` is unknown
+    m2021::number_of_tokens_in_a_prefixed_string_literal!();
+    //~^ ERROR prefix `hey` is unknown
+}
diff --git a/src/test/ui/rust-2021/reserved-prefixes-via-macro-2.stderr b/src/test/ui/rust-2021/reserved-prefixes-via-macro-2.stderr
new file mode 100644
index 00000000000..9d7ca570c4c
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes-via-macro-2.stderr
@@ -0,0 +1,29 @@
+error: prefix `hey` is unknown
+  --> $DIR/reserved-prefixes-via-macro-2.rs:15:5
+   |
+LL |     m2021::number_of_tokens_in_a_prefixed_integer_literal!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+   = note: this error originates in the macro `m2021::number_of_tokens_in_a_prefixed_integer_literal` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: prefix `hey` is unknown
+  --> $DIR/reserved-prefixes-via-macro-2.rs:17:5
+   |
+LL |     m2021::number_of_tokens_in_a_prefixed_char_literal!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+   = note: this error originates in the macro `m2021::number_of_tokens_in_a_prefixed_char_literal` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: prefix `hey` is unknown
+  --> $DIR/reserved-prefixes-via-macro-2.rs:19:5
+   |
+LL |     m2021::number_of_tokens_in_a_prefixed_string_literal!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+   = note: this error originates in the macro `m2021::number_of_tokens_in_a_prefixed_string_literal` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/rust-2021/reserved-prefixes-via-macro.rs b/src/test/ui/rust-2021/reserved-prefixes-via-macro.rs
new file mode 100644
index 00000000000..110b6d64ccc
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes-via-macro.rs
@@ -0,0 +1,12 @@
+// run-pass
+// edition:2021
+// aux-build:reserved-prefixes-macro-2018.rs
+
+extern crate reserved_prefixes_macro_2018 as m2018;
+
+fn main() {
+    // Ok, even though *this* crate is 2021:
+    assert_eq!(m2018::number_of_tokens_in_a_prefixed_integer_literal!(), 3);
+    assert_eq!(m2018::number_of_tokens_in_a_prefixed_char_literal!(), 3);
+    assert_eq!(m2018::number_of_tokens_in_a_prefixed_string_literal!(), 3);
+}
diff --git a/src/test/ui/rust-2021/reserved-prefixes.rs b/src/test/ui/rust-2021/reserved-prefixes.rs
new file mode 100644
index 00000000000..5882c7d83d8
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes.rs
@@ -0,0 +1,36 @@
+// compile-flags: -Z unstable-options --edition 2021
+
+macro_rules! demo2 {
+    ( $a:tt $b:tt ) => { println!("two tokens") };
+}
+
+macro_rules! demo3 {
+    ( $a:tt $b:tt $c:tt ) => { println!("three tokens") };
+}
+
+macro_rules! demo4 {
+    ( $a:tt $b:tt $c:tt $d:tt ) => { println!("four tokens") };
+}
+
+fn main() {
+    demo3!(foo#bar);   //~ ERROR prefix `foo` is unknown
+    demo2!(foo"bar");  //~ ERROR prefix `foo` is unknown
+    demo2!(foo'b');    //~ ERROR prefix `foo` is unknown
+
+    demo2!(foo'b);     //~ ERROR prefix `foo` is unknown
+    demo3!(foo# bar);  //~ ERROR prefix `foo` is unknown
+    demo4!(foo#! bar); //~ ERROR prefix `foo` is unknown
+    demo4!(foo## bar); //~ ERROR prefix `foo` is unknown
+
+    demo4!(foo#bar#);
+    //~^ ERROR prefix `foo` is unknown
+    //~| ERROR prefix `bar` is unknown
+
+    demo3!(foo # bar);
+    demo3!(foo #bar);
+    demo4!(foo!#bar);
+    demo4!(foo ##bar);
+
+    demo3!(r"foo"#bar);
+    demo3!(r#foo#bar);
+}
diff --git a/src/test/ui/rust-2021/reserved-prefixes.stderr b/src/test/ui/rust-2021/reserved-prefixes.stderr
new file mode 100644
index 00000000000..32e18563329
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes.stderr
@@ -0,0 +1,110 @@
+error: prefix `foo` is unknown
+  --> $DIR/reserved-prefixes.rs:16:12
+   |
+LL |     demo3!(foo#bar);
+   |            ^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+   |
+LL |     demo3!(foo #bar);
+   |               --
+
+error: prefix `foo` is unknown
+  --> $DIR/reserved-prefixes.rs:17:12
+   |
+LL |     demo2!(foo"bar");
+   |            ^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+   |
+LL |     demo2!(foo "bar");
+   |               --
+
+error: prefix `foo` is unknown
+  --> $DIR/reserved-prefixes.rs:18:12
+   |
+LL |     demo2!(foo'b');
+   |            ^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+   |
+LL |     demo2!(foo 'b');
+   |               --
+
+error: prefix `foo` is unknown
+  --> $DIR/reserved-prefixes.rs:20:12
+   |
+LL |     demo2!(foo'b);
+   |            ^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+   |
+LL |     demo2!(foo 'b);
+   |               --
+
+error: prefix `foo` is unknown
+  --> $DIR/reserved-prefixes.rs:21:12
+   |
+LL |     demo3!(foo# bar);
+   |            ^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+   |
+LL |     demo3!(foo # bar);
+   |               --
+
+error: prefix `foo` is unknown
+  --> $DIR/reserved-prefixes.rs:22:12
+   |
+LL |     demo4!(foo#! bar);
+   |            ^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+   |
+LL |     demo4!(foo #! bar);
+   |               --
+
+error: prefix `foo` is unknown
+  --> $DIR/reserved-prefixes.rs:23:12
+   |
+LL |     demo4!(foo## bar);
+   |            ^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+   |
+LL |     demo4!(foo ## bar);
+   |               --
+
+error: prefix `foo` is unknown
+  --> $DIR/reserved-prefixes.rs:25:12
+   |
+LL |     demo4!(foo#bar#);
+   |            ^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+   |
+LL |     demo4!(foo #bar#);
+   |               --
+
+error: prefix `bar` is unknown
+  --> $DIR/reserved-prefixes.rs:25:16
+   |
+LL |     demo4!(foo#bar#);
+   |                ^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+   |
+LL |     demo4!(foo#bar #);
+   |                   --
+
+error: aborting due to 9 previous errors
+
diff --git a/src/test/ui/sanitize/crt-static.rs b/src/test/ui/sanitize/crt-static.rs
index f5dd2a40cc4..7a6b9eda3fa 100644
--- a/src/test/ui/sanitize/crt-static.rs
+++ b/src/test/ui/sanitize/crt-static.rs
@@ -1,4 +1,5 @@
 // compile-flags: -Z sanitizer=address -C target-feature=+crt-static --target x86_64-unknown-linux-gnu
+// needs-llvm-components: x86
 
 #![feature(no_core)]
 #![no_core]
diff --git a/src/test/ui/sanitize/incompatible.rs b/src/test/ui/sanitize/incompatible.rs
index 4947f3b3d8b..bcafc2891fd 100644
--- a/src/test/ui/sanitize/incompatible.rs
+++ b/src/test/ui/sanitize/incompatible.rs
@@ -1,4 +1,5 @@
 // compile-flags: -Z sanitizer=address -Z sanitizer=memory --target x86_64-unknown-linux-gnu
+// needs-llvm-components: x86
 // error-pattern: error: `-Zsanitizer=address` is incompatible with `-Zsanitizer=memory`
 
 #![feature(no_core)]
diff --git a/src/test/ui/sanitize/unsupported-target.rs b/src/test/ui/sanitize/unsupported-target.rs
index 3fb749815f7..9f29c76353b 100644
--- a/src/test/ui/sanitize/unsupported-target.rs
+++ b/src/test/ui/sanitize/unsupported-target.rs
@@ -1,4 +1,5 @@
 // compile-flags: -Z sanitizer=leak --target i686-unknown-linux-gnu
+// needs-llvm-components: x86
 // error-pattern: error: leak sanitizer is not supported for this target
 #![feature(no_core)]
 #![no_core]
diff --git a/src/test/ui/simd-intrinsic/issue-85855.rs b/src/test/ui/simd-intrinsic/issue-85855.rs
new file mode 100644
index 00000000000..f276fbd6694
--- /dev/null
+++ b/src/test/ui/simd-intrinsic/issue-85855.rs
@@ -0,0 +1,19 @@
+// Check that appropriate errors are reported if an intrinsic is defined
+// with the wrong number of generic lifetime/type/const parameters, and
+// that no ICE occurs in these cases.
+
+#![feature(platform_intrinsics)]
+#![crate_type="lib"]
+
+extern "platform-intrinsic" {
+    fn simd_saturating_add<'a, T: 'a>(x: T, y: T);
+    //~^ ERROR: intrinsic has wrong number of lifetime parameters
+
+    fn simd_add<'a, T>(x: T, y: T) -> T;
+
+    fn simd_sub<T, U>(x: T, y: U);
+    //~^ ERROR: intrinsic has wrong number of type parameters
+
+    fn simd_mul<T, const N: usize>(x: T, y: T);
+    //~^ ERROR: intrinsic has wrong number of const parameters
+}
diff --git a/src/test/ui/simd-intrinsic/issue-85855.stderr b/src/test/ui/simd-intrinsic/issue-85855.stderr
new file mode 100644
index 00000000000..fb2f1fbc5b1
--- /dev/null
+++ b/src/test/ui/simd-intrinsic/issue-85855.stderr
@@ -0,0 +1,21 @@
+error[E0094]: intrinsic has wrong number of lifetime parameters: found 1, expected 0
+  --> $DIR/issue-85855.rs:9:27
+   |
+LL |     fn simd_saturating_add<'a, T: 'a>(x: T, y: T);
+   |                           ^^^^^^^^^^^ expected 0 lifetime parameters
+
+error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1
+  --> $DIR/issue-85855.rs:14:16
+   |
+LL |     fn simd_sub<T, U>(x: T, y: U);
+   |                ^^^^^^ expected 1 type parameter
+
+error[E0094]: intrinsic has wrong number of const parameters: found 1, expected 0
+  --> $DIR/issue-85855.rs:17:16
+   |
+LL |     fn simd_mul<T, const N: usize>(x: T, y: T);
+   |                ^^^^^^^^^^^^^^^^^^^ expected 0 const parameters
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0094`.
diff --git a/src/test/ui/suggestions/issue-61963.rs b/src/test/ui/suggestions/issue-61963.rs
index b5c379ebc6e..d31ed01b191 100644
--- a/src/test/ui/suggestions/issue-61963.rs
+++ b/src/test/ui/suggestions/issue-61963.rs
@@ -17,11 +17,11 @@ pub struct Qux<T>(T);
 #[dom_struct]
 pub struct Foo {
     //~^ ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
     qux: Qux<Qux<Baz>>,
     bar: Box<Bar>,
     //~^ ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
 }
 
 fn main() {}
diff --git a/src/test/ui/suggestions/issue-61963.stderr b/src/test/ui/suggestions/issue-61963.stderr
index f8c58b61734..6282a693855 100644
--- a/src/test/ui/suggestions/issue-61963.stderr
+++ b/src/test/ui/suggestions/issue-61963.stderr
@@ -9,7 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(bare_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: trait objects without an explicit `dyn` are deprecated
@@ -18,7 +18,7 @@ error: trait objects without an explicit `dyn` are deprecated
 LL | pub struct Foo {
    | ^^^ help: use `dyn`: `dyn pub`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/suggestions/issue-86667.rs b/src/test/ui/suggestions/issue-86667.rs
new file mode 100644
index 00000000000..6aceb137469
--- /dev/null
+++ b/src/test/ui/suggestions/issue-86667.rs
@@ -0,0 +1,16 @@
+// Regression test for #86667, where a garbled suggestion was issued for
+// a missing named lifetime parameter.
+
+// compile-flags: --edition 2018
+
+async fn a(s1: &str, s2: &str) -> &str {
+//~^ ERROR: missing lifetime specifier [E0106]
+    s1
+}
+
+fn b(s1: &str, s2: &str) -> &str {
+//~^ ERROR: missing lifetime specifier [E0106]
+    s1
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-86667.stderr b/src/test/ui/suggestions/issue-86667.stderr
new file mode 100644
index 00000000000..77f7f874a4e
--- /dev/null
+++ b/src/test/ui/suggestions/issue-86667.stderr
@@ -0,0 +1,27 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/issue-86667.rs:6:35
+   |
+LL | async fn a(s1: &str, s2: &str) -> &str {
+   |                ----      ----     ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `s1` or `s2`
+help: consider introducing a named lifetime parameter
+   |
+LL | async fn a<'a>(s1: &'a str, s2: &'a str) -> &'a str {
+   |           ^^^^     ^^^^^^^      ^^^^^^^     ^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/issue-86667.rs:11:29
+   |
+LL | fn b(s1: &str, s2: &str) -> &str {
+   |          ----      ----     ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `s1` or `s2`
+help: consider introducing a named lifetime parameter
+   |
+LL | fn b<'a>(s1: &'a str, s2: &'a str) -> &'a str {
+   |     ^^^^     ^^^^^^^      ^^^^^^^     ^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/suggestions/use-placement-resolve.fixed b/src/test/ui/suggestions/use-placement-resolve.fixed
new file mode 100644
index 00000000000..afe74cff2e9
--- /dev/null
+++ b/src/test/ui/suggestions/use-placement-resolve.fixed
@@ -0,0 +1,13 @@
+// compile-flags: --test
+// run-rustfix
+// Checks that the `use` suggestion appears *below* this inner attribute.
+// There was an issue where the test synthetic #[allow(dead)] attribute on
+// main which has a dummy span caused the suggestion to be placed at the top
+// of the file.
+#![allow(unused)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+fn foobar<T: Debug>(x: T) {} //~ ERROR expected trait, found derive macro
diff --git a/src/test/ui/suggestions/use-placement-resolve.rs b/src/test/ui/suggestions/use-placement-resolve.rs
new file mode 100644
index 00000000000..b30ddb3af07
--- /dev/null
+++ b/src/test/ui/suggestions/use-placement-resolve.rs
@@ -0,0 +1,11 @@
+// compile-flags: --test
+// run-rustfix
+// Checks that the `use` suggestion appears *below* this inner attribute.
+// There was an issue where the test synthetic #[allow(dead)] attribute on
+// main which has a dummy span caused the suggestion to be placed at the top
+// of the file.
+#![allow(unused)]
+
+fn main() {}
+
+fn foobar<T: Debug>(x: T) {} //~ ERROR expected trait, found derive macro
diff --git a/src/test/ui/suggestions/use-placement-resolve.stderr b/src/test/ui/suggestions/use-placement-resolve.stderr
new file mode 100644
index 00000000000..9da9e8e2702
--- /dev/null
+++ b/src/test/ui/suggestions/use-placement-resolve.stderr
@@ -0,0 +1,14 @@
+error[E0404]: expected trait, found derive macro `Debug`
+  --> $DIR/use-placement-resolve.rs:11:14
+   |
+LL | fn foobar<T: Debug>(x: T) {}
+   |              ^^^^^ not a trait
+   |
+help: consider importing this trait instead
+   |
+LL | use std::fmt::Debug;
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0404`.
diff --git a/src/test/ui/suggestions/use-placement-typeck.fixed b/src/test/ui/suggestions/use-placement-typeck.fixed
new file mode 100644
index 00000000000..40c55d1dd06
--- /dev/null
+++ b/src/test/ui/suggestions/use-placement-typeck.fixed
@@ -0,0 +1,22 @@
+// compile-flags: --test
+// run-rustfix
+// Checks that the `use` suggestion appears *below* this inner attribute.
+// There was an issue where the test synthetic #[allow(dead)] attribute on
+// main which has a dummy span caused the suggestion to be placed at the top
+// of the file.
+#![allow(unused)]
+
+use m::Foo;
+
+fn main() {
+    let s = m::S;
+    s.abc(); //~ ERROR no method named `abc`
+}
+
+mod m {
+    pub trait Foo {
+        fn abc(&self) {}
+    }
+    pub struct S;
+    impl Foo for S{}
+}
diff --git a/src/test/ui/suggestions/use-placement-typeck.rs b/src/test/ui/suggestions/use-placement-typeck.rs
new file mode 100644
index 00000000000..aab20d2e90a
--- /dev/null
+++ b/src/test/ui/suggestions/use-placement-typeck.rs
@@ -0,0 +1,20 @@
+// compile-flags: --test
+// run-rustfix
+// Checks that the `use` suggestion appears *below* this inner attribute.
+// There was an issue where the test synthetic #[allow(dead)] attribute on
+// main which has a dummy span caused the suggestion to be placed at the top
+// of the file.
+#![allow(unused)]
+
+fn main() {
+    let s = m::S;
+    s.abc(); //~ ERROR no method named `abc`
+}
+
+mod m {
+    pub trait Foo {
+        fn abc(&self) {}
+    }
+    pub struct S;
+    impl Foo for S{}
+}
diff --git a/src/test/ui/suggestions/use-placement-typeck.stderr b/src/test/ui/suggestions/use-placement-typeck.stderr
new file mode 100644
index 00000000000..21f22dade2c
--- /dev/null
+++ b/src/test/ui/suggestions/use-placement-typeck.stderr
@@ -0,0 +1,21 @@
+error[E0599]: no method named `abc` found for struct `S` in the current scope
+  --> $DIR/use-placement-typeck.rs:11:7
+   |
+LL |     s.abc();
+   |       ^^^ method not found in `S`
+...
+LL |         fn abc(&self) {}
+   |            --- the method is available for `S` here
+LL |     }
+LL |     pub struct S;
+   |     ------------- method `abc` not found for this
+   |
+   = help: items from traits can only be used if the trait is in scope
+help: the following trait is implemented but not in scope; perhaps add a `use` for it:
+   |
+LL | use m::Foo;
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/synthetic-param.stderr b/src/test/ui/synthetic-param.stderr
index 951d7edb7f5..101132d05fa 100644
--- a/src/test/ui/synthetic-param.stderr
+++ b/src/test/ui/synthetic-param.stderr
@@ -18,3 +18,4 @@ LL |     Bar::<i8>::func::<u8>(42);
 
 error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0632`.
diff --git a/src/test/ui/test-panic-abort-disabled.rs b/src/test/ui/test-attrs/test-panic-abort-disabled.rs
index 874dbdb42c3..874dbdb42c3 100644
--- a/src/test/ui/test-panic-abort-disabled.rs
+++ b/src/test/ui/test-attrs/test-panic-abort-disabled.rs
diff --git a/src/test/ui/test-panic-abort-disabled.stderr b/src/test/ui/test-attrs/test-panic-abort-disabled.stderr
index 9c65c7360c1..9c65c7360c1 100644
--- a/src/test/ui/test-panic-abort-disabled.stderr
+++ b/src/test/ui/test-attrs/test-panic-abort-disabled.stderr
diff --git a/src/test/ui/test-panic-abort-nocapture.rs b/src/test/ui/test-attrs/test-panic-abort-nocapture.rs
index af530cc1a0b..af530cc1a0b 100644
--- a/src/test/ui/test-panic-abort-nocapture.rs
+++ b/src/test/ui/test-attrs/test-panic-abort-nocapture.rs
diff --git a/src/test/ui/test-panic-abort-nocapture.run.stderr b/src/test/ui/test-attrs/test-panic-abort-nocapture.run.stderr
index 727e9691c53..727e9691c53 100644
--- a/src/test/ui/test-panic-abort-nocapture.run.stderr
+++ b/src/test/ui/test-attrs/test-panic-abort-nocapture.run.stderr
diff --git a/src/test/ui/test-panic-abort-nocapture.run.stdout b/src/test/ui/test-attrs/test-panic-abort-nocapture.run.stdout
index 8a91732a754..8a91732a754 100644
--- a/src/test/ui/test-panic-abort-nocapture.run.stdout
+++ b/src/test/ui/test-attrs/test-panic-abort-nocapture.run.stdout
diff --git a/src/test/ui/test-panic-abort.rs b/src/test/ui/test-attrs/test-panic-abort.rs
index 931b7993c81..931b7993c81 100644
--- a/src/test/ui/test-panic-abort.rs
+++ b/src/test/ui/test-attrs/test-panic-abort.rs
diff --git a/src/test/ui/test-panic-abort.run.stdout b/src/test/ui/test-attrs/test-panic-abort.run.stdout
index f608a8cdc55..f608a8cdc55 100644
--- a/src/test/ui/test-panic-abort.run.stdout
+++ b/src/test/ui/test-attrs/test-panic-abort.run.stdout
diff --git a/src/test/ui/test-panic-while-printing.rs b/src/test/ui/test-attrs/test-panic-while-printing.rs
index 23f45407c1a..23f45407c1a 100644
--- a/src/test/ui/test-panic-while-printing.rs
+++ b/src/test/ui/test-attrs/test-panic-while-printing.rs
diff --git a/src/test/ui/test-passed-wasm.rs b/src/test/ui/test-attrs/test-passed-wasm.rs
index 578aa4b1760..578aa4b1760 100644
--- a/src/test/ui/test-passed-wasm.rs
+++ b/src/test/ui/test-attrs/test-passed-wasm.rs
diff --git a/src/test/ui/test-passed-wasm.run.stdout b/src/test/ui/test-attrs/test-passed-wasm.run.stdout
index c3005a77983..c3005a77983 100644
--- a/src/test/ui/test-passed-wasm.run.stdout
+++ b/src/test/ui/test-attrs/test-passed-wasm.run.stdout
diff --git a/src/test/ui/test-passed.rs b/src/test/ui/test-attrs/test-passed.rs
index f65f0003022..f65f0003022 100644
--- a/src/test/ui/test-passed.rs
+++ b/src/test/ui/test-attrs/test-passed.rs
diff --git a/src/test/ui/test-passed.run.stdout b/src/test/ui/test-attrs/test-passed.run.stdout
index 17f70d60749..17f70d60749 100644
--- a/src/test/ui/test-passed.run.stdout
+++ b/src/test/ui/test-attrs/test-passed.run.stdout
diff --git a/src/test/ui/test-thread-capture.rs b/src/test/ui/test-attrs/test-thread-capture.rs
index edc972837a3..edc972837a3 100644
--- a/src/test/ui/test-thread-capture.rs
+++ b/src/test/ui/test-attrs/test-thread-capture.rs
diff --git a/src/test/ui/test-thread-capture.run.stdout b/src/test/ui/test-attrs/test-thread-capture.run.stdout
index 487cfb55eb4..487cfb55eb4 100644
--- a/src/test/ui/test-thread-capture.run.stdout
+++ b/src/test/ui/test-attrs/test-thread-capture.run.stdout
diff --git a/src/test/ui/test-thread-nocapture.rs b/src/test/ui/test-attrs/test-thread-nocapture.rs
index 8e8e9bbfdf0..8e8e9bbfdf0 100644
--- a/src/test/ui/test-thread-nocapture.rs
+++ b/src/test/ui/test-attrs/test-thread-nocapture.rs
diff --git a/src/test/ui/test-thread-nocapture.run.stderr b/src/test/ui/test-attrs/test-thread-nocapture.run.stderr
index 06495681b3e..06495681b3e 100644
--- a/src/test/ui/test-thread-nocapture.run.stderr
+++ b/src/test/ui/test-attrs/test-thread-nocapture.run.stderr
diff --git a/src/test/ui/test-thread-nocapture.run.stdout b/src/test/ui/test-attrs/test-thread-nocapture.run.stdout
index 9d2da50826c..9d2da50826c 100644
--- a/src/test/ui/test-thread-nocapture.run.stdout
+++ b/src/test/ui/test-attrs/test-thread-nocapture.run.stdout
diff --git a/src/test/ui/thread-local-static.rs b/src/test/ui/thread-local-static.rs
index dc542fe2db9..c7fee9e6b4c 100644
--- a/src/test/ui/thread-local-static.rs
+++ b/src/test/ui/thread-local-static.rs
@@ -11,7 +11,6 @@ const fn g(x: &mut [u32; 8]) {
     //~| ERROR mutable references are not allowed
     //~| ERROR use of mutable static is unsafe
     //~| constant functions cannot refer to statics
-    //~| ERROR calls in constant functions are limited to constant functions
 }
 
 fn main() {}
diff --git a/src/test/ui/thread-local-static.stderr b/src/test/ui/thread-local-static.stderr
index a213282eb85..08bf593a5a7 100644
--- a/src/test/ui/thread-local-static.stderr
+++ b/src/test/ui/thread-local-static.stderr
@@ -30,12 +30,6 @@ LL |     std::mem::swap(x, &mut STATIC_VAR_2)
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
-error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/thread-local-static.rs:9:5
-   |
-LL |     std::mem::swap(x, &mut STATIC_VAR_2)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0133]: use of mutable static is unsafe and requires unsafe function or block
   --> $DIR/thread-local-static.rs:9:23
    |
@@ -44,7 +38,7 @@ LL |     std::mem::swap(x, &mut STATIC_VAR_2)
    |
    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0013, E0015, E0133, E0658.
+Some errors have detailed explanations: E0013, E0133, E0658.
 For more information about an error, try `rustc --explain E0013`.
diff --git a/src/test/ui/traits/bound/not-on-bare-trait.rs b/src/test/ui/traits/bound/not-on-bare-trait.rs
index 08355a55630..daf18c6702e 100644
--- a/src/test/ui/traits/bound/not-on-bare-trait.rs
+++ b/src/test/ui/traits/bound/not-on-bare-trait.rs
@@ -7,7 +7,7 @@ trait Foo {
 fn foo(_x: Foo + Send) {
     //~^ ERROR the size for values of type
     //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this was previously accepted by the compiler
+    //~| WARN this is accepted in the current edition
 }
 
 fn main() {}
diff --git a/src/test/ui/traits/bound/not-on-bare-trait.stderr b/src/test/ui/traits/bound/not-on-bare-trait.stderr
index 418e67d56ea..e65b8989e0b 100644
--- a/src/test/ui/traits/bound/not-on-bare-trait.stderr
+++ b/src/test/ui/traits/bound/not-on-bare-trait.stderr
@@ -5,7 +5,7 @@ LL | fn foo(_x: Foo + Send) {
    |            ^^^^^^^^^^ help: use `dyn`: `dyn Foo + Send`
    |
    = note: `#[warn(bare_trait_objects)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time
diff --git a/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.rs b/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.rs
index e186570167d..1be0b05fa2b 100644
--- a/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.rs
+++ b/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.rs
@@ -17,8 +17,8 @@ pub struct Second {
     d: Vec<First>,
 }
 
-struct Third<f> {
-    g: Vec<f>,
+struct Third<'a, f> {
+    g: Vec<(f, &'a f)>,
 }
 
 enum Ty {
@@ -38,29 +38,29 @@ struct Sixth {
 }
 
 #[rustc_evaluate_where_clauses]
-fn forward()
+fn forward<'a>()
 where
     Vec<First>: Unpin,
-    Third<Ty>: Unpin,
+    Third<'a, Ty>: Unpin,
 {
 }
 
 #[rustc_evaluate_where_clauses]
-fn reverse()
+fn reverse<'a>()
 where
-    Third<Ty>: Unpin,
+    Third<'a, Ty>: Unpin,
     Vec<First>: Unpin,
 {
 }
 
 fn main() {
-    // Key is that Vec<First> is "ok" and Third<Ty> is "ok modulo regions":
+    // Key is that Vec<First> is "ok" and Third<'_, Ty> is "ok modulo regions":
 
     forward();
     //~^ ERROR evaluate(Binder(TraitPredicate(<std::vec::Vec<First> as std::marker::Unpin>), [])) = Ok(EvaluatedToOk)
-    //~| ERROR evaluate(Binder(TraitPredicate(<Third<Ty> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
+    //~| ERROR evaluate(Binder(TraitPredicate(<Third<'_, Ty> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
 
     reverse();
     //~^ ERROR evaluate(Binder(TraitPredicate(<std::vec::Vec<First> as std::marker::Unpin>), [])) = Ok(EvaluatedToOk)
-    //~| ERROR evaluate(Binder(TraitPredicate(<Third<Ty> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
+    //~| ERROR evaluate(Binder(TraitPredicate(<Third<'_, Ty> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
 }
diff --git a/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.stderr b/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.stderr
index bfe3e76b214..43acc66fd73 100644
--- a/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.stderr
+++ b/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.stderr
@@ -7,20 +7,20 @@ LL |     Vec<First>: Unpin,
 LL |     forward();
    |     ^^^^^^^
 
-error: evaluate(Binder(TraitPredicate(<Third<Ty> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
+error: evaluate(Binder(TraitPredicate(<Third<'_, Ty> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
   --> $DIR/issue-83538-tainted-cache-after-cycle.rs:59:5
    |
-LL |     Third<Ty>: Unpin,
-   |                ----- predicate
+LL |     Third<'a, Ty>: Unpin,
+   |                    ----- predicate
 ...
 LL |     forward();
    |     ^^^^^^^
 
-error: evaluate(Binder(TraitPredicate(<Third<Ty> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
+error: evaluate(Binder(TraitPredicate(<Third<'_, Ty> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
   --> $DIR/issue-83538-tainted-cache-after-cycle.rs:63:5
    |
-LL |     Third<Ty>: Unpin,
-   |                ----- predicate
+LL |     Third<'a, Ty>: Unpin,
+   |                    ----- predicate
 ...
 LL |     reverse();
    |     ^^^^^^^
diff --git a/src/test/ui/traits/reservation-impl/non-lattice-ok.rs b/src/test/ui/traits/reservation-impl/non-lattice-ok.rs
index f14589ccf84..b894577c1f7 100644
--- a/src/test/ui/traits/reservation-impl/non-lattice-ok.rs
+++ b/src/test/ui/traits/reservation-impl/non-lattice-ok.rs
@@ -28,7 +28,7 @@
 // go with a known approach, we should go with a "marker trait overlap"-style
 // approach.
 //
-// [ii]: http://smallcultfollowing.com/babysteps/blog/2016/09/24/intersection-impls/
+// [ii]: https://smallcultfollowing.com/babysteps/blog/2016/09/24/intersection-impls/
 
 #![feature(rustc_attrs, never_type)]
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-65384.rs b/src/test/ui/type-alias-impl-trait/issue-65384.rs
new file mode 100644
index 00000000000..63666c497c6
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-65384.rs
@@ -0,0 +1,16 @@
+#![feature(min_type_alias_impl_trait)]
+#![feature(type_alias_impl_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait {}
+
+impl MyTrait for () {}
+
+type Bar = impl MyTrait;
+
+impl MyTrait for Bar {}
+//~^ ERROR: cannot implement trait on type alias impl trait
+
+fn bazr() -> Bar { }
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-65384.stderr b/src/test/ui/type-alias-impl-trait/issue-65384.stderr
new file mode 100644
index 00000000000..01d037266ec
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-65384.stderr
@@ -0,0 +1,14 @@
+error: cannot implement trait on type alias impl trait
+  --> $DIR/issue-65384.rs:11:1
+   |
+LL | impl MyTrait for Bar {}
+   | ^^^^^^^^^^^^^^^^^^^^
+   |
+note: type alias impl trait defined here
+  --> $DIR/issue-65384.rs:9:12
+   |
+LL | type Bar = impl MyTrait;
+   |            ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/conversion-methods.rs b/src/test/ui/typeck/conversion-methods.rs
index 46c2e511f33..46c2e511f33 100644
--- a/src/test/ui/conversion-methods.rs
+++ b/src/test/ui/typeck/conversion-methods.rs
diff --git a/src/test/ui/conversion-methods.stderr b/src/test/ui/typeck/conversion-methods.stderr
index 4f47e1fd0ff..4f47e1fd0ff 100644
--- a/src/test/ui/conversion-methods.stderr
+++ b/src/test/ui/typeck/conversion-methods.stderr
diff --git a/src/test/ui/typeck/issue-84160.rs b/src/test/ui/typeck/issue-84160.rs
new file mode 100644
index 00000000000..7b444df8528
--- /dev/null
+++ b/src/test/ui/typeck/issue-84160.rs
@@ -0,0 +1,9 @@
+fn mismatched_types_with_reference(x: &u32) -> &u32 {
+    if false {
+        return x;
+    }
+    return "test";
+    //~^ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/issue-84160.stderr b/src/test/ui/typeck/issue-84160.stderr
new file mode 100644
index 00000000000..24c188b3fcb
--- /dev/null
+++ b/src/test/ui/typeck/issue-84160.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-84160.rs:5:12
+   |
+LL | fn mismatched_types_with_reference(x: &u32) -> &u32 {
+   |                                                ---- expected `&u32` because of return type
+...
+LL |     return "test";
+   |            ^^^^^^ expected `u32`, found `str`
+   |
+   = note: expected reference `&u32`
+              found reference `&'static str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/typeck/issue-86721-return-expr-ice.rev1.stderr b/src/test/ui/typeck/issue-86721-return-expr-ice.rev1.stderr
new file mode 100644
index 00000000000..b1111fcf148
--- /dev/null
+++ b/src/test/ui/typeck/issue-86721-return-expr-ice.rev1.stderr
@@ -0,0 +1,9 @@
+error[E0572]: return statement outside of function body
+  --> $DIR/issue-86721-return-expr-ice.rs:9:22
+   |
+LL |     const U: usize = return;
+   |                      ^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0572`.
diff --git a/src/test/ui/typeck/issue-86721-return-expr-ice.rev2.stderr b/src/test/ui/typeck/issue-86721-return-expr-ice.rev2.stderr
new file mode 100644
index 00000000000..f489ae2002a
--- /dev/null
+++ b/src/test/ui/typeck/issue-86721-return-expr-ice.rev2.stderr
@@ -0,0 +1,9 @@
+error[E0572]: return statement outside of function body
+  --> $DIR/issue-86721-return-expr-ice.rs:15:20
+   |
+LL |     fn foo(a: [(); return]);
+   |                    ^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0572`.
diff --git a/src/test/ui/typeck/issue-86721-return-expr-ice.rs b/src/test/ui/typeck/issue-86721-return-expr-ice.rs
new file mode 100644
index 00000000000..cd7135f18b1
--- /dev/null
+++ b/src/test/ui/typeck/issue-86721-return-expr-ice.rs
@@ -0,0 +1,17 @@
+// Regression test for the ICE described in #86721.
+
+// revisions: rev1 rev2
+#![cfg_attr(any(), rev1, rev2)]
+#![crate_type="lib"]
+
+#[cfg(any(rev1))]
+trait T {
+    const U: usize = return;
+    //[rev1]~^ ERROR: return statement outside of function body [E0572]
+}
+
+#[cfg(any(rev2))]
+trait T2 {
+    fn foo(a: [(); return]);
+    //[rev2]~^ ERROR: return statement outside of function body [E0572]
+}
diff --git a/src/test/ui/unpretty-expr-fn-arg.rs b/src/test/ui/unpretty-expr-fn-arg.rs
new file mode 100644
index 00000000000..6e1132a3372
--- /dev/null
+++ b/src/test/ui/unpretty-expr-fn-arg.rs
@@ -0,0 +1,13 @@
+// Regression test for the ICE described in #82328. The pretty-printer for
+// `-Zunpretty=hir,typed` would previously retrieve type-checking results
+// when entering a body, which means that type information was not available
+// for expressions occurring in function signatures, as in the `foo` example
+// below, leading to an ICE.
+
+// check-pass
+// compile-flags: -Zunpretty=hir,typed
+#![allow(dead_code)]
+
+fn main() {}
+
+fn foo(-128..=127: i8) {}
diff --git a/src/test/ui/unpretty-expr-fn-arg.stdout b/src/test/ui/unpretty-expr-fn-arg.stdout
new file mode 100644
index 00000000000..cb04dfead73
--- /dev/null
+++ b/src/test/ui/unpretty-expr-fn-arg.stdout
@@ -0,0 +1,17 @@
+// Regression test for the ICE described in #82328. The pretty-printer for
+// `-Zunpretty=hir,typed` would previously retrieve type-checking results
+// when entering a body, which means that type information was not available
+// for expressions occurring in function signatures, as in the `foo` example
+// below, leading to an ICE.
+
+// check-pass
+// compile-flags: -Zunpretty=hir,typed
+#![allow(dead_code)]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+fn main() ({ } as ())
+
+fn foo((-(128 as i8) as i8) ...(127 as i8): i8) ({ } as ())
diff --git a/src/test/ui/unsized/unsized3-rpass.rs b/src/test/ui/unsized/unsized3-rpass.rs
index 65efbd6b520..c5c5ed26c73 100644
--- a/src/test/ui/unsized/unsized3-rpass.rs
+++ b/src/test/ui/unsized/unsized3-rpass.rs
@@ -1,12 +1,11 @@
 // run-pass
 // Test structs with always-unsized fields.
 
-
 #![allow(warnings)]
-#![feature(box_syntax, unsize, raw)]
+#![feature(box_syntax, unsize, ptr_metadata)]
 
 use std::mem;
-use std::raw;
+use std::ptr;
 use std::slice;
 
 struct Foo<T> {
@@ -28,7 +27,7 @@ trait Tr {
 }
 
 struct St {
-    f: usize
+    f: usize,
 }
 
 impl Tr for St {
@@ -38,7 +37,7 @@ impl Tr for St {
 }
 
 struct Qux<'a> {
-    f: Tr+'a
+    f: Tr + 'a,
 }
 
 pub fn main() {
@@ -56,10 +55,10 @@ pub fn main() {
 
     unsafe {
         struct Foo_<T> {
-            f: [T; 3]
+            f: [T; 3],
         }
 
-        let data: Box<Foo_<i32>> = box Foo_{f: [1, 2, 3] };
+        let data: Box<Foo_<i32>> = box Foo_ { f: [1, 2, 3] };
         let x: &Foo<i32> = mem::transmute(slice::from_raw_parts(&*data, 3));
         assert_eq!(x.f.len(), 3);
         assert_eq!(x.f[0], 1);
@@ -69,8 +68,8 @@ pub fn main() {
             f2: [u8; 5],
         }
 
-        let data: Box<_> = box Baz_ {
-            f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] };
+        let data: Box<_> =
+            box Baz_ { f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] };
         let x: &Baz = mem::transmute(slice::from_raw_parts(&*data, 5));
         assert_eq!(x.f1, 42);
         let chs: Vec<char> = x.f2.chars().collect();
@@ -82,15 +81,13 @@ pub fn main() {
         assert_eq!(chs[4], 'e');
 
         struct Qux_ {
-            f: St
+            f: St,
         }
 
         let obj: Box<St> = box St { f: 42 };
         let obj: &Tr = &*obj;
-        let obj: raw::TraitObject = mem::transmute(&*obj);
-        let data: Box<_> = box Qux_{ f: St { f: 234 } };
-        let x: &Qux = mem::transmute(raw::TraitObject { vtable: obj.vtable,
-                                                        data: mem::transmute(&*data) });
+        let data: Box<_> = box Qux_ { f: St { f: 234 } };
+        let x: &Qux = &*ptr::from_raw_parts::<Qux>((&*data as *const _).cast(), ptr::metadata(obj));
         assert_eq!(x.f.foo(), 234);
     }
 }
diff --git a/src/test/ui/unused/unused-doc-comments-edge-cases.rs b/src/test/ui/unused/unused-doc-comments-edge-cases.rs
new file mode 100644
index 00000000000..fd9baf8c6b9
--- /dev/null
+++ b/src/test/ui/unused/unused-doc-comments-edge-cases.rs
@@ -0,0 +1,29 @@
+#![deny(unused_doc_comments)]
+
+fn doc_comment_on_match_arms(num: u8) -> bool {
+    match num {
+        3 => true,
+        /// useless doc comment
+        //~^ ERROR: unused doc comment
+        _ => false,
+    }
+}
+
+fn doc_comment_between_if_else(num: u8) -> bool {
+    if num == 3 {
+        true //~ ERROR: mismatched types
+    }
+    /// useless doc comment
+    else { //~ ERROR: expected expression, found keyword `else`
+        false
+    }
+}
+
+fn doc_comment_on_expr(num: u8) -> bool {
+    /// useless doc comment
+    //~^ ERROR: attributes on expressions are experimental
+    //~| ERROR: unused doc comment
+    num == 3
+}
+
+fn main() {}
diff --git a/src/test/ui/unused/unused-doc-comments-edge-cases.stderr b/src/test/ui/unused/unused-doc-comments-edge-cases.stderr
new file mode 100644
index 00000000000..14db5f64b0c
--- /dev/null
+++ b/src/test/ui/unused/unused-doc-comments-edge-cases.stderr
@@ -0,0 +1,61 @@
+error: expected expression, found keyword `else`
+  --> $DIR/unused-doc-comments-edge-cases.rs:17:5
+   |
+LL |     else {
+   |     ^^^^ expected expression
+
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/unused-doc-comments-edge-cases.rs:23:5
+   |
+LL |     /// useless doc comment
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+   = help: `///` is for documentation comments. For a plain comment, use `//`.
+
+error: unused doc comment
+  --> $DIR/unused-doc-comments-edge-cases.rs:6:9
+   |
+LL |         /// useless doc comment
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |         _ => false,
+   |         ---------- rustdoc does not generate documentation for match arms
+   |
+note: the lint level is defined here
+  --> $DIR/unused-doc-comments-edge-cases.rs:1:9
+   |
+LL | #![deny(unused_doc_comments)]
+   |         ^^^^^^^^^^^^^^^^^^^
+   = help: use `//` for a plain comment
+
+error: unused doc comment
+  --> $DIR/unused-doc-comments-edge-cases.rs:23:5
+   |
+LL |     /// useless doc comment
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |     num == 3
+   |     --- rustdoc does not generate documentation for expressions
+   |
+   = help: use `//` for a plain comment
+
+error[E0308]: mismatched types
+  --> $DIR/unused-doc-comments-edge-cases.rs:14:9
+   |
+LL | /     if num == 3 {
+LL | |         true
+   | |         ^^^^ expected `()`, found `bool`
+LL | |     }
+   | |_____- expected this to be `()`
+   |
+help: you might have meant to return this value
+   |
+LL |         return true;
+   |         ^^^^^^     ^
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0308, E0658.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/unused/useless-comment.stderr b/src/test/ui/unused/useless-comment.stderr
index 5a0af8db7c5..0054426fb1e 100644
--- a/src/test/ui/unused/useless-comment.stderr
+++ b/src/test/ui/unused/useless-comment.stderr
@@ -26,6 +26,8 @@ LL |     /// a
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |     let x = 12;
    |     ----------- rustdoc does not generate documentation for statements
+   |
+   = help: use `//` for a plain comment
 
 error: unused doc comment
   --> $DIR/useless-comment.rs:16:5
@@ -40,6 +42,8 @@ LL | |         1 => {},
 LL | |         _ => {}
 LL | |     }
    | |_____- rustdoc does not generate documentation for expressions
+   |
+   = help: use `//` for a plain comment
 
 error: unused doc comment
   --> $DIR/useless-comment.rs:20:9
@@ -48,6 +52,8 @@ LL |         /// c
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |         1 => {},
    |         ------- rustdoc does not generate documentation for match arms
+   |
+   = help: use `//` for a plain comment
 
 error: unused doc comment
   --> $DIR/useless-comment.rs:25:5
@@ -56,6 +62,8 @@ LL |     /// foo
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |     unsafe {}
    |     --------- rustdoc does not generate documentation for expressions
+   |
+   = help: use `//` for a plain comment
 
 error: unused doc comment
   --> $DIR/useless-comment.rs:28:5
@@ -65,6 +73,8 @@ LL |     #[doc = "foo"]
 LL |     #[doc = "bar"]
 LL |     3;
    |     - rustdoc does not generate documentation for expressions
+   |
+   = help: use `//` for a plain comment
 
 error: unused doc comment
   --> $DIR/useless-comment.rs:29:5
@@ -73,12 +83,16 @@ LL |     #[doc = "bar"]
    |     ^^^^^^^^^^^^^^
 LL |     3;
    |     - rustdoc does not generate documentation for expressions
+   |
+   = help: use `//` for a plain comment
 
 error: unused doc comment
   --> $DIR/useless-comment.rs:35:13
    |
 LL |     let x = /** comment */ 47;
    |             ^^^^^^^^^^^^^^ -- rustdoc does not generate documentation for expressions
+   |
+   = help: use `/* */` for a plain comment
 
 error: unused doc comment
   --> $DIR/useless-comment.rs:37:5
@@ -89,6 +103,8 @@ LL | /     {
 LL | |
 LL | |     }
    | |_____- rustdoc does not generate documentation for expressions
+   |
+   = help: use `//` for a plain comment
 
 error: aborting due to 10 previous errors
 
diff --git a/src/test/ui/wait-forked-but-failed-child.rs b/src/test/ui/wait-forked-but-failed-child.rs
index 26835907759..0eb0fe071f5 100644
--- a/src/test/ui/wait-forked-but-failed-child.rs
+++ b/src/test/ui/wait-forked-but-failed-child.rs
@@ -28,7 +28,7 @@ use std::process::Command;
 fn find_zombies() {
     let my_pid = unsafe { libc::getpid() };
 
-    // http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html
+    // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html
     let ps_cmd_output = Command::new("ps").args(&["-A", "-o", "pid,ppid,args"]).output().unwrap();
     let ps_output = String::from_utf8_lossy(&ps_cmd_output.stdout);
 
diff --git a/src/test/ui/write-fmt-errors.rs b/src/test/ui/write-fmt-errors.rs
index 7dd98564425..3fcaefaa63e 100644
--- a/src/test/ui/write-fmt-errors.rs
+++ b/src/test/ui/write-fmt-errors.rs
@@ -1,5 +1,7 @@
 // run-pass
 
+#![feature(io_error_uncategorized)]
+
 use std::fmt;
 use std::io::{self, Error, Write, sink};
 
@@ -13,7 +15,7 @@ impl fmt::Display for ErrorDisplay {
 
 struct ErrorWriter;
 
-const FORMAT_ERROR: io::ErrorKind = io::ErrorKind::Other;
+const FORMAT_ERROR: io::ErrorKind = io::ErrorKind::Uncategorized;
 const WRITER_ERROR: io::ErrorKind = io::ErrorKind::NotConnected;
 
 impl Write for ErrorWriter {
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 9233aa06c801801cff75df65df718d70905a235
+Subproject 3ebb5f15a940810f250b68821149387af583a79
diff --git a/src/tools/clippy/.github/workflows/clippy.yml b/src/tools/clippy/.github/workflows/clippy.yml
index 32103f59d8b..d856c55a41a 100644
--- a/src/tools/clippy/.github/workflows/clippy.yml
+++ b/src/tools/clippy/.github/workflows/clippy.yml
@@ -71,7 +71,7 @@ jobs:
       working-directory: clippy_workspace_tests
 
     - name: Test cargo-clippy --fix
-      run: ../target/debug/cargo-clippy clippy --fix -Zunstable-options
+      run: ../target/debug/cargo-clippy clippy --fix
       working-directory: clippy_workspace_tests
 
     - name: Test clippy-driver
diff --git a/src/tools/clippy/.github/workflows/clippy_bors.yml b/src/tools/clippy/.github/workflows/clippy_bors.yml
index f27fee87dc1..146b6fccd0c 100644
--- a/src/tools/clippy/.github/workflows/clippy_bors.yml
+++ b/src/tools/clippy/.github/workflows/clippy_bors.yml
@@ -90,11 +90,6 @@ jobs:
     - name: Checkout
       uses: actions/checkout@v2.3.3
 
-    # FIXME: should not be necessary once 1.24.2 is the default version on the windows runner
-    - name: Update rustup
-      run: rustup self update
-      if: runner.os == 'Windows'
-
     - name: Install toolchain
       run: rustup show active-toolchain
 
@@ -139,7 +134,7 @@ jobs:
       working-directory: clippy_workspace_tests
 
     - name: Test cargo-clippy --fix
-      run: ../target/debug/cargo-clippy clippy --fix -Zunstable-options
+      run: ../target/debug/cargo-clippy clippy --fix
       working-directory: clippy_workspace_tests
 
     - name: Test clippy-driver
diff --git a/src/tools/clippy/.github/workflows/remark.yml b/src/tools/clippy/.github/workflows/remark.yml
index 4f25a86b2e4..77efdec1e50 100644
--- a/src/tools/clippy/.github/workflows/remark.yml
+++ b/src/tools/clippy/.github/workflows/remark.yml
@@ -22,7 +22,7 @@ jobs:
       uses: actions/setup-node@v1.4.4
 
     - name: Install remark
-      run: npm install remark-cli remark-lint remark-lint-maximum-line-length remark-preset-lint-recommended
+      run: npm install remark-cli remark-lint remark-lint-maximum-line-length remark-preset-lint-recommended remark-gfm
 
     # Run
     - name: Check *.md files
diff --git a/src/tools/clippy/.remarkrc b/src/tools/clippy/.remarkrc
index 0ede7ac75cb..04b82b8cc58 100644
--- a/src/tools/clippy/.remarkrc
+++ b/src/tools/clippy/.remarkrc
@@ -1,6 +1,7 @@
 {
   "plugins": [
     "remark-preset-lint-recommended",
+    "remark-gfm",
     ["remark-lint-list-item-indent", false],
     ["remark-lint-no-literal-urls", false],
     ["remark-lint-no-shortcut-reference-link", false],
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 41af8e190dd..f3a80703238 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -6,11 +6,139 @@ document.
 
 ## Unreleased / In Rust Nightly
 
-[7c7683c...master](https://github.com/rust-lang/rust-clippy/compare/7c7683c...master)
+[3ae8faf...master](https://github.com/rust-lang/rust-clippy/compare/3ae8faf...master)
+
+## Rust 1.54
+
+Current beta, release 2021-07-29
+
+[7c7683c...3ae8faf](https://github.com/rust-lang/rust-clippy/compare/7c7683c...3ae8faf)
+
+### New Lints
+
+- [`ref_binding_to_reference`]
+  [#7105](https://github.com/rust-lang/rust-clippy/pull/7105)
+- [`needless_bitwise_bool`]
+  [#7133](https://github.com/rust-lang/rust-clippy/pull/7133)
+- [`unused_async`] [#7225](https://github.com/rust-lang/rust-clippy/pull/7225)
+- [`manual_str_repeat`]
+  [#7265](https://github.com/rust-lang/rust-clippy/pull/7265)
+- [`suspicious_splitn`]
+  [#7292](https://github.com/rust-lang/rust-clippy/pull/7292)
+
+### Moves and Deprecations
+
+- Deprecate `pub_enum_variant_names` and `wrong_pub_self_convention` in favor of
+  the new `avoid_breaking_exported_api` config option (see
+  [Enhancements](#1-54-enhancements))
+  [#7187](https://github.com/rust-lang/rust-clippy/pull/7187)
+- Move [`inconsistent_struct_constructor`] to `pedantic`
+  [#7193](https://github.com/rust-lang/rust-clippy/pull/7193)
+- Move [`needless_borrow`] to `style` (now warn-by-default)
+  [#7254](https://github.com/rust-lang/rust-clippy/pull/7254)
+- Move [`suspicious_operation_groupings`] to `nursery`
+  [#7266](https://github.com/rust-lang/rust-clippy/pull/7266)
+- Move [`semicolon_if_nothing_returned`] to `pedantic`
+  [#7268](https://github.com/rust-lang/rust-clippy/pull/7268)
+
+### Enhancements <a name="1-54-enhancements"></a>
+
+- [`while_let_on_iterator`]: Now also lints in nested loops
+  [#6966](https://github.com/rust-lang/rust-clippy/pull/6966)
+- [`single_char_pattern`]: Now also lints on `strip_prefix` and `strip_suffix`
+  [#7156](https://github.com/rust-lang/rust-clippy/pull/7156)
+- [`needless_collect`]: Now also lints on assignments with type annotations
+  [#7163](https://github.com/rust-lang/rust-clippy/pull/7163)
+- [`if_then_some_else_none`]: Now works with the MSRV config
+  [#7177](https://github.com/rust-lang/rust-clippy/pull/7177)
+- Add `avoid_breaking_exported_api` config option for the lints
+  [`enum_variant_names`], [`large_types_passed_by_value`],
+  [`trivially_copy_pass_by_ref`], [`unnecessary_wraps`],
+  [`upper_case_acronyms`], and [`wrong_self_convention`]. We recommend to set
+  this configuration option to `false` before a major release (1.0/2.0/...) to
+  clean up the API [#7187](https://github.com/rust-lang/rust-clippy/pull/7187)
+- [`needless_collect`]: Now lints on even more data structures
+  [#7188](https://github.com/rust-lang/rust-clippy/pull/7188)
+- [`missing_docs_in_private_items`]: No longer sees `#[<name> = "<value>"]` like
+  attributes as sufficient documentation
+  [#7281](https://github.com/rust-lang/rust-clippy/pull/7281)
+- [`needless_collect`], [`short_circuit_statement`], [`unnecessary_operation`]:
+  Now work as expected when used with `allow`
+  [#7282](https://github.com/rust-lang/rust-clippy/pull/7282)
+
+### False Positive Fixes
+
+- [`implicit_return`]: Now takes all diverging functions in account to avoid
+  false positives [#6951](https://github.com/rust-lang/rust-clippy/pull/6951)
+- [`while_let_on_iterator`]: No longer lints when the iterator is a struct field
+  and the struct is used in the loop
+  [#6966](https://github.com/rust-lang/rust-clippy/pull/6966)
+- [`multiple_inherent_impl`]: No longer lints with generic arguments
+  [#7089](https://github.com/rust-lang/rust-clippy/pull/7089)
+- [`comparison_chain`]: No longer lints in a `const` context
+  [#7118](https://github.com/rust-lang/rust-clippy/pull/7118)
+- [`while_immutable_condition`]: Fix false positive where mutation in the loop
+  variable wasn't picked up
+  [#7144](https://github.com/rust-lang/rust-clippy/pull/7144)
+- [`default_trait_access`]: No longer lints in macros
+  [#7150](https://github.com/rust-lang/rust-clippy/pull/7150)
+- [`needless_question_mark`]: No longer lints when the inner value is implicitly
+  dereferenced [#7165](https://github.com/rust-lang/rust-clippy/pull/7165)
+- [`unused_unit`]: No longer lints when multiple macro contexts are involved
+  [#7167](https://github.com/rust-lang/rust-clippy/pull/7167)
+- [`eval_order_dependence`]: Fix false positive in async context
+  [#7174](https://github.com/rust-lang/rust-clippy/pull/7174)
+- [`unnecessary_filter_map`]: No longer lints if the `filter_map` changes the
+  type [#7175](https://github.com/rust-lang/rust-clippy/pull/7175)
+- [`wrong_self_convention`]: No longer lints in trait implementations of
+  non-`Copy` types [#7182](https://github.com/rust-lang/rust-clippy/pull/7182)
+- [`suboptimal_flops`]: No longer lints on `powi(2)`
+  [#7201](https://github.com/rust-lang/rust-clippy/pull/7201)
+- [`wrong_self_convention`]: No longer lints if there is no implicit `self`
+  [#7215](https://github.com/rust-lang/rust-clippy/pull/7215)
+- [`option_if_let_else`]: No longer lints on `else if let` pattern
+  [#7216](https://github.com/rust-lang/rust-clippy/pull/7216)
+- [`use_self`], [`useless_conversion`]: Fix false positives when generic
+  arguments are involved
+  [#7223](https://github.com/rust-lang/rust-clippy/pull/7223)
+- [`manual_unwrap_or`]: Fix false positive with deref coercion
+  [#7233](https://github.com/rust-lang/rust-clippy/pull/7233)
+- [`similar_names`]: No longer lints on `wparam`/`lparam`
+  [#7255](https://github.com/rust-lang/rust-clippy/pull/7255)
+- [`redundant_closure`]: No longer lints on using the `vec![]` macro in a
+  closure [#7263](https://github.com/rust-lang/rust-clippy/pull/7263)
+
+### Suggestion Fixes/Improvements
+
+- [`implicit_return`]
+  [#6951](https://github.com/rust-lang/rust-clippy/pull/6951)
+    - Fix suggestion for async functions
+    - Improve suggestion with macros
+    - Suggest to change `break` to `return` when appropriate
+- [`while_let_on_iterator`]: Now suggests `&mut iter` when necessary
+  [#6966](https://github.com/rust-lang/rust-clippy/pull/6966)
+- [`match_single_binding`]: Improve suggestion when match scrutinee has side
+  effects [#7095](https://github.com/rust-lang/rust-clippy/pull/7095)
+- [`needless_borrow`]: Now suggests to also change usage sites as needed
+  [#7105](https://github.com/rust-lang/rust-clippy/pull/7105)
+- [`write_with_newline`]: Improve suggestion when only `\n` is written to the
+  buffer [#7183](https://github.com/rust-lang/rust-clippy/pull/7183)
+- [`from_iter_instead_of_collect`]: The suggestion is now auto applicable also
+  when a `<_ as Trait>::_` is involved
+  [#7264](https://github.com/rust-lang/rust-clippy/pull/7264)
+- [`not_unsafe_ptr_arg_deref`]: Improved error message
+  [#7294](https://github.com/rust-lang/rust-clippy/pull/7294)
+
+### ICE Fixes
+
+- Fix ICE when running Clippy on `libstd`
+  [#7140](https://github.com/rust-lang/rust-clippy/pull/7140)
+- [`implicit_return`]
+  [#7242](https://github.com/rust-lang/rust-clippy/pull/7242)
 
 ## Rust 1.53
 
-Current beta, release 2021-06-17
+Current stable, released 2021-06-17
 
 [6ed6f1e...7c7683c](https://github.com/rust-lang/rust-clippy/compare/6ed6f1e...7c7683c)
 
@@ -194,7 +322,7 @@ Current beta, release 2021-06-17
 
 ## Rust 1.52
 
-Current stable, released 2021-05-06
+Released 2021-05-06
 
 [3e41797...6ed6f1e](https://github.com/rust-lang/rust-clippy/compare/3e41797...6ed6f1e)
 
@@ -2295,6 +2423,7 @@ Released 2018-09-13
 <!-- begin autogenerated links to lint list -->
 [`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons
 [`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped
+[`append_instead_of_extend`]: https://rust-lang.github.io/rust-clippy/master/index.html#append_instead_of_extend
 [`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant
 [`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
 [`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
@@ -2358,6 +2487,8 @@ Released 2018-09-13
 [`derive_hash_xor_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
 [`derive_ord_xor_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_ord_xor_partial_ord
 [`disallowed_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_method
+[`disallowed_script_idents`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents
+[`disallowed_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_type
 [`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression
 [`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown
 [`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons
@@ -2527,6 +2658,7 @@ Released 2018-09-13
 [`misrefactored_assign_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#misrefactored_assign_op
 [`missing_const_for_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn
 [`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items
+[`missing_enforced_import_renames`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames
 [`missing_errors_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc
 [`missing_inline_in_public_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_inline_in_public_items
 [`missing_panics_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc
@@ -2574,6 +2706,7 @@ Released 2018-09-13
 [`non_octal_unix_permissions`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_octal_unix_permissions
 [`nonminimal_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool
 [`nonsensical_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonsensical_open_options
+[`nonstandard_macro_braces`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces
 [`not_unsafe_ptr_arg_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#not_unsafe_ptr_arg_deref
 [`ok_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#ok_expect
 [`op_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#op_ref
diff --git a/src/tools/clippy/CONTRIBUTING.md b/src/tools/clippy/CONTRIBUTING.md
index 7d7b7c81173..4273fda4e64 100644
--- a/src/tools/clippy/CONTRIBUTING.md
+++ b/src/tools/clippy/CONTRIBUTING.md
@@ -115,7 +115,7 @@ To work around this, you need to have a copy of the [rustc-repo][rustc_repo] ava
 `git clone https://github.com/rust-lang/rust/`.
 Then you can run a `cargo dev` command to automatically make Clippy use the rustc-repo via path-dependencies
 which `IntelliJ Rust` will be able to understand.
-Run `cargo dev ide_setup --repo-path <repo-path>` where `<repo-path>` is a path to the rustc repo
+Run `cargo dev setup intellij --repo-path <repo-path>` where `<repo-path>` is a path to the rustc repo
 you just cloned.
 The command will add path-dependencies pointing towards rustc-crates inside the rustc repo to
 Clippys `Cargo.toml`s and should allow `IntelliJ Rust` to understand most of the types that Clippy uses.
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index b003b15a11d..9b5d9b2adf3 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy"
-version = "0.1.54"
+version = "0.1.55"
 authors = ["The Rust Clippy Developers"]
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
diff --git a/src/tools/clippy/README.md b/src/tools/clippy/README.md
index bd322cc8070..e1c968273cd 100644
--- a/src/tools/clippy/README.md
+++ b/src/tools/clippy/README.md
@@ -10,16 +10,17 @@ A collection of lints to catch common mistakes and improve your [Rust](https://g
 Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html).
 You can choose how much Clippy is supposed to ~~annoy~~ help you by changing the lint level by category.
 
-| Category              | Description                                                             | Default level |
-| --------------------- | ----------------------------------------------------------------------- | ------------- |
-| `clippy::all`         | all lints that are on by default (correctness, style, complexity, perf) | **warn/deny** |
-| `clippy::correctness` | code that is outright wrong or very useless                             | **deny**      |
-| `clippy::style`       | code that should be written in a more idiomatic way                     | **warn**      |
-| `clippy::complexity`  | code that does something simple but in a complex way                    | **warn**      |
-| `clippy::perf`        | code that can be written to run faster                                  | **warn**      |
-| `clippy::pedantic`    | lints which are rather strict or might have false positives             | allow         |
-| `clippy::nursery`     | new lints that are still under development                              | allow         |
-| `clippy::cargo`       | lints for the cargo manifest                                            | allow         |
+| Category              | Description                                                                         | Default level |
+| --------------------- | ----------------------------------------------------------------------------------- | ------------- |
+| `clippy::all`         | all lints that are on by default (correctness, suspicious, style, complexity, perf) | **warn/deny** |
+| `clippy::correctness` | code that is outright wrong or useless                                              | **deny**      |
+| `clippy::suspicious`  | code that is most likely wrong or useless                                           | **warn**      |
+| `clippy::style`       | code that should be written in a more idiomatic way                                 | **warn**      |
+| `clippy::complexity`  | code that does something simple but in a complex way                                | **warn**      |
+| `clippy::perf`        | code that can be written to run faster                                              | **warn**      |
+| `clippy::pedantic`    | lints which are rather strict or might have false positives                         | allow         |
+| `clippy::nursery`     | new lints that are still under development                                          | allow         |
+| `clippy::cargo`       | lints for the cargo manifest                                                        | allow         |
 
 More to come, please [file an issue](https://github.com/rust-lang/rust-clippy/issues) if you have ideas!
 
@@ -75,11 +76,10 @@ cargo clippy
 
 #### Automatically applying Clippy suggestions
 
-Clippy can automatically apply some lint suggestions.
-Note that this is still experimental and only supported on the nightly channel:
+Clippy can automatically apply some lint suggestions, just like the compiler.
 
 ```terminal
-cargo clippy --fix -Z unstable-options
+cargo clippy --fix
 ```
 
 #### Workspaces
diff --git a/src/tools/clippy/clippy_dev/Cargo.toml b/src/tools/clippy/clippy_dev/Cargo.toml
index b1844e29b32..5c6c106e0e6 100644
--- a/src/tools/clippy/clippy_dev/Cargo.toml
+++ b/src/tools/clippy/clippy_dev/Cargo.toml
@@ -8,7 +8,7 @@ edition = "2018"
 bytecount = "0.6"
 clap = "2.33"
 itertools = "0.9"
-opener = "0.4"
+opener = "0.5"
 regex = "1"
 shell-escape = "0.1"
 walkdir = "2"
diff --git a/src/tools/clippy/clippy_dev/src/fmt.rs b/src/tools/clippy/clippy_dev/src/fmt.rs
index 1517cdc9419..c81eb40d52f 100644
--- a/src/tools/clippy/clippy_dev/src/fmt.rs
+++ b/src/tools/clippy/clippy_dev/src/fmt.rs
@@ -60,11 +60,7 @@ pub fn run(check: bool, verbose: bool) {
             let entry = entry?;
             let path = entry.path();
 
-            if path.extension() != Some("rs".as_ref())
-                || entry.file_name() == "ice-3891.rs"
-                // Avoid rustfmt bug rust-lang/rustfmt#1873
-                || cfg!(windows) && entry.file_name() == "implicit_hasher.rs"
-            {
+            if path.extension() != Some("rs".as_ref()) || entry.file_name() == "ice-3891.rs" {
                 continue;
             }
 
@@ -90,7 +86,7 @@ pub fn run(check: bool, verbose: bool) {
             },
             CliError::RaSetupActive => {
                 eprintln!(
-                    "error: a local rustc repo is enabled as path dependency via `cargo dev ide_setup`.
+                    "error: a local rustc repo is enabled as path dependency via `cargo dev setup intellij`.
 Not formatting because that would format the local repo as well!
 Please revert the changes to Cargo.tomls first."
                 );
diff --git a/src/tools/clippy/clippy_dev/src/ide_setup.rs b/src/tools/clippy/clippy_dev/src/ide_setup.rs
deleted file mode 100644
index defb1133e44..00000000000
--- a/src/tools/clippy/clippy_dev/src/ide_setup.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-use std::fs;
-use std::fs::File;
-use std::io::prelude::*;
-use std::path::{Path, PathBuf};
-
-// This module takes an absolute path to a rustc repo and alters the dependencies to point towards
-// the respective rustc subcrates instead of using extern crate xyz.
-// This allows rust analyzer to analyze rustc internals and show proper information inside clippy
-// code. See https://github.com/rust-analyzer/rust-analyzer/issues/3517 and https://github.com/rust-lang/rust-clippy/issues/5514 for details
-
-/// # Panics
-///
-/// Panics if `rustc_path` does not lead to a rustc repo or the files could not be read
-pub fn run(rustc_path: Option<&str>) {
-    // we can unwrap here because the arg is required by clap
-    let rustc_path = PathBuf::from(rustc_path.unwrap())
-        .canonicalize()
-        .expect("failed to get the absolute repo path");
-    assert!(rustc_path.is_dir(), "path is not a directory");
-    let rustc_source_basedir = rustc_path.join("compiler");
-    assert!(
-        rustc_source_basedir.is_dir(),
-        "are you sure the path leads to a rustc repo?"
-    );
-
-    let clippy_root_manifest = fs::read_to_string("Cargo.toml").expect("failed to read ./Cargo.toml");
-    let clippy_root_lib_rs = fs::read_to_string("src/driver.rs").expect("failed to read ./src/driver.rs");
-    inject_deps_into_manifest(
-        &rustc_source_basedir,
-        "Cargo.toml",
-        &clippy_root_manifest,
-        &clippy_root_lib_rs,
-    )
-    .expect("Failed to inject deps into ./Cargo.toml");
-
-    let clippy_lints_manifest =
-        fs::read_to_string("clippy_lints/Cargo.toml").expect("failed to read ./clippy_lints/Cargo.toml");
-    let clippy_lints_lib_rs =
-        fs::read_to_string("clippy_lints/src/lib.rs").expect("failed to read ./clippy_lints/src/lib.rs");
-    inject_deps_into_manifest(
-        &rustc_source_basedir,
-        "clippy_lints/Cargo.toml",
-        &clippy_lints_manifest,
-        &clippy_lints_lib_rs,
-    )
-    .expect("Failed to inject deps into ./clippy_lints/Cargo.toml");
-}
-
-fn inject_deps_into_manifest(
-    rustc_source_dir: &Path,
-    manifest_path: &str,
-    cargo_toml: &str,
-    lib_rs: &str,
-) -> std::io::Result<()> {
-    // do not inject deps if we have aleady done so
-    if cargo_toml.contains("[target.'cfg(NOT_A_PLATFORM)'.dependencies]") {
-        eprintln!(
-            "cargo dev ide_setup: warning: deps already found inside {}, doing nothing.",
-            manifest_path
-        );
-        return Ok(());
-    }
-
-    let extern_crates = lib_rs
-        .lines()
-        // get the deps
-        .filter(|line| line.starts_with("extern crate"))
-        // we have something like "extern crate foo;", we only care about the "foo"
-        //              ↓          ↓
-        // extern crate rustc_middle;
-        .map(|s| &s[13..(s.len() - 1)]);
-
-    let new_deps = extern_crates.map(|dep| {
-        // format the dependencies that are going to be put inside the Cargo.toml
-        format!(
-            "{dep} = {{ path = \"{source_path}/{dep}\" }}\n",
-            dep = dep,
-            source_path = rustc_source_dir.display()
-        )
-    });
-
-    // format a new [dependencies]-block with the new deps we need to inject
-    let mut all_deps = String::from("[target.'cfg(NOT_A_PLATFORM)'.dependencies]\n");
-    new_deps.for_each(|dep_line| {
-        all_deps.push_str(&dep_line);
-    });
-    all_deps.push_str("\n[dependencies]\n");
-
-    // replace "[dependencies]" with
-    // [dependencies]
-    // dep1 = { path = ... }
-    // dep2 = { path = ... }
-    // etc
-    let new_manifest = cargo_toml.replacen("[dependencies]\n", &all_deps, 1);
-
-    // println!("{}", new_manifest);
-    let mut file = File::create(manifest_path)?;
-    file.write_all(new_manifest.as_bytes())?;
-
-    println!("Dependency paths injected: {}", manifest_path);
-
-    Ok(())
-}
diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs
index 69f42aca8b6..72bdaf8d592 100644
--- a/src/tools/clippy/clippy_dev/src/lib.rs
+++ b/src/tools/clippy/clippy_dev/src/lib.rs
@@ -14,9 +14,9 @@ use walkdir::WalkDir;
 
 pub mod bless;
 pub mod fmt;
-pub mod ide_setup;
 pub mod new_lint;
 pub mod serve;
+pub mod setup;
 pub mod stderr_length_check;
 pub mod update_lints;
 
diff --git a/src/tools/clippy/clippy_dev/src/main.rs b/src/tools/clippy/clippy_dev/src/main.rs
index 7040c257c83..ff324ff6ee6 100644
--- a/src/tools/clippy/clippy_dev/src/main.rs
+++ b/src/tools/clippy/clippy_dev/src/main.rs
@@ -2,8 +2,8 @@
 // warn on lints, that are included in `rust-lang/rust`s bootstrap
 #![warn(rust_2018_idioms, unused_lifetimes)]
 
-use clap::{App, Arg, ArgMatches, SubCommand};
-use clippy_dev::{bless, fmt, ide_setup, new_lint, serve, stderr_length_check, update_lints};
+use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
+use clippy_dev::{bless, fmt, new_lint, serve, setup, stderr_length_check, update_lints};
 fn main() {
     let matches = get_clap_config();
 
@@ -36,7 +36,22 @@ fn main() {
         ("limit_stderr_length", _) => {
             stderr_length_check::check();
         },
-        ("ide_setup", Some(matches)) => ide_setup::run(matches.value_of("rustc-repo-path")),
+        ("setup", Some(sub_command)) => match sub_command.subcommand() {
+            ("intellij", Some(matches)) => setup::intellij::setup_rustc_src(
+                matches
+                    .value_of("rustc-repo-path")
+                    .expect("this field is mandatory and therefore always valid"),
+            ),
+            ("git-hook", Some(matches)) => setup::git_hook::install_hook(matches.is_present("force-override")),
+            ("vscode-tasks", Some(matches)) => setup::vscode::install_tasks(matches.is_present("force-override")),
+            _ => {},
+        },
+        ("remove", Some(sub_command)) => match sub_command.subcommand() {
+            ("git-hook", Some(_)) => setup::git_hook::remove_hook(),
+            ("intellij", Some(_)) => setup::intellij::remove_rustc_src(),
+            ("vscode-tasks", Some(_)) => setup::vscode::remove_tasks(),
+            _ => {},
+        },
         ("serve", Some(matches)) => {
             let port = matches.value_of("port").unwrap().parse().unwrap();
             let lint = matches.value_of("lint");
@@ -48,6 +63,7 @@ fn main() {
 
 fn get_clap_config<'a>() -> ArgMatches<'a> {
     App::new("Clippy developer tooling")
+        .setting(AppSettings::ArgRequiredElseHelp)
         .subcommand(
             SubCommand::with_name("bless")
                 .about("bless the test output changes")
@@ -123,6 +139,7 @@ fn get_clap_config<'a>() -> ArgMatches<'a> {
                         .possible_values(&[
                             "style",
                             "correctness",
+                            "suspicious",
                             "complexity",
                             "perf",
                             "pedantic",
@@ -140,16 +157,54 @@ fn get_clap_config<'a>() -> ArgMatches<'a> {
                 .about("Ensures that stderr files do not grow longer than a certain amount of lines."),
         )
         .subcommand(
-            SubCommand::with_name("ide_setup")
-                .about("Alter dependencies so Intellij Rust can find rustc internals")
-                .arg(
-                    Arg::with_name("rustc-repo-path")
-                        .long("repo-path")
-                        .short("r")
-                        .help("The path to a rustc repo that will be used for setting the dependencies")
-                        .takes_value(true)
-                        .value_name("path")
-                        .required(true),
+            SubCommand::with_name("setup")
+                .about("Support for setting up your personal development environment")
+                .setting(AppSettings::ArgRequiredElseHelp)
+                .subcommand(
+                    SubCommand::with_name("intellij")
+                        .about("Alter dependencies so Intellij Rust can find rustc internals")
+                        .arg(
+                            Arg::with_name("rustc-repo-path")
+                                .long("repo-path")
+                                .short("r")
+                                .help("The path to a rustc repo that will be used for setting the dependencies")
+                                .takes_value(true)
+                                .value_name("path")
+                                .required(true),
+                        ),
+                )
+                .subcommand(
+                    SubCommand::with_name("git-hook")
+                        .about("Add a pre-commit git hook that formats your code to make it look pretty")
+                        .arg(
+                            Arg::with_name("force-override")
+                                .long("force-override")
+                                .short("f")
+                                .help("Forces the override of an existing git pre-commit hook")
+                                .required(false),
+                        ),
+                )
+                .subcommand(
+                    SubCommand::with_name("vscode-tasks")
+                        .about("Add several tasks to vscode for formatting, validation and testing")
+                        .arg(
+                            Arg::with_name("force-override")
+                                .long("force-override")
+                                .short("f")
+                                .help("Forces the override of existing vscode tasks")
+                                .required(false),
+                        ),
+                ),
+        )
+        .subcommand(
+            SubCommand::with_name("remove")
+                .about("Support for undoing changes done by the setup command")
+                .setting(AppSettings::ArgRequiredElseHelp)
+                .subcommand(SubCommand::with_name("git-hook").about("Remove any existing pre-commit git hook"))
+                .subcommand(SubCommand::with_name("vscode-tasks").about("Remove any existing vscode tasks"))
+                .subcommand(
+                    SubCommand::with_name("intellij")
+                        .about("Removes rustc source paths added via `cargo dev setup intellij`"),
                 ),
         )
         .subcommand(
diff --git a/src/tools/clippy/clippy_dev/src/setup/git_hook.rs b/src/tools/clippy/clippy_dev/src/setup/git_hook.rs
new file mode 100644
index 00000000000..3fbb77d5923
--- /dev/null
+++ b/src/tools/clippy/clippy_dev/src/setup/git_hook.rs
@@ -0,0 +1,85 @@
+use std::fs;
+use std::path::Path;
+
+use super::verify_inside_clippy_dir;
+
+/// Rusts setup uses `git rev-parse --git-common-dir` to get the root directory of the repo.
+/// I've decided against this for the sake of simplicity and to make sure that it doesn't install
+/// the hook if `clippy_dev` would be used in the rust tree. The hook also references this tool
+/// for formatting and should therefor only be used in a normal clone of clippy
+const REPO_GIT_DIR: &str = ".git";
+const HOOK_SOURCE_FILE: &str = "util/etc/pre-commit.sh";
+const HOOK_TARGET_FILE: &str = ".git/hooks/pre-commit";
+
+pub fn install_hook(force_override: bool) {
+    if !check_precondition(force_override) {
+        return;
+    }
+
+    // So a little bit of a funny story. Git on unix requires the pre-commit file
+    // to have the `execute` permission to be set. The Rust functions for modifying
+    // these flags doesn't seem to work when executed with normal user permissions.
+    //
+    // However, there is a little hack that is also being used by Rust itself in their
+    // setup script. Git saves the `execute` flag when syncing files. This means
+    // that we can check in a file with execution permissions and the sync it to create
+    // a file with the flag set. We then copy this file here. The copy function will also
+    // include the `execute` permission.
+    match fs::copy(HOOK_SOURCE_FILE, HOOK_TARGET_FILE) {
+        Ok(_) => {
+            println!("info: the hook can be removed with `cargo dev remove git-hook`");
+            println!("git hook successfully installed");
+        },
+        Err(err) => eprintln!(
+            "error: unable to copy `{}` to `{}` ({})",
+            HOOK_SOURCE_FILE, HOOK_TARGET_FILE, err
+        ),
+    }
+}
+
+fn check_precondition(force_override: bool) -> bool {
+    if !verify_inside_clippy_dir() {
+        return false;
+    }
+
+    // Make sure that we can find the git repository
+    let git_path = Path::new(REPO_GIT_DIR);
+    if !git_path.exists() || !git_path.is_dir() {
+        eprintln!("error: clippy_dev was unable to find the `.git` directory");
+        return false;
+    }
+
+    // Make sure that we don't override an existing hook by accident
+    let path = Path::new(HOOK_TARGET_FILE);
+    if path.exists() {
+        if force_override {
+            return delete_git_hook_file(path);
+        }
+
+        eprintln!("error: there is already a pre-commit hook installed");
+        println!("info: use the `--force-override` flag to override the existing hook");
+        return false;
+    }
+
+    true
+}
+
+pub fn remove_hook() {
+    let path = Path::new(HOOK_TARGET_FILE);
+    if path.exists() {
+        if delete_git_hook_file(path) {
+            println!("git hook successfully removed");
+        }
+    } else {
+        println!("no pre-commit hook was found");
+    }
+}
+
+fn delete_git_hook_file(path: &Path) -> bool {
+    if let Err(err) = fs::remove_file(path) {
+        eprintln!("error: unable to delete existing pre-commit git hook ({})", err);
+        false
+    } else {
+        true
+    }
+}
diff --git a/src/tools/clippy/clippy_dev/src/setup/intellij.rs b/src/tools/clippy/clippy_dev/src/setup/intellij.rs
new file mode 100644
index 00000000000..bf741e6d121
--- /dev/null
+++ b/src/tools/clippy/clippy_dev/src/setup/intellij.rs
@@ -0,0 +1,223 @@
+use std::fs;
+use std::fs::File;
+use std::io::prelude::*;
+use std::path::{Path, PathBuf};
+
+// This module takes an absolute path to a rustc repo and alters the dependencies to point towards
+// the respective rustc subcrates instead of using extern crate xyz.
+// This allows IntelliJ to analyze rustc internals and show proper information inside Clippy
+// code. See https://github.com/rust-lang/rust-clippy/issues/5514 for details
+
+const RUSTC_PATH_SECTION: &str = "[target.'cfg(NOT_A_PLATFORM)'.dependencies]";
+const DEPENDENCIES_SECTION: &str = "[dependencies]";
+
+const CLIPPY_PROJECTS: &[ClippyProjectInfo] = &[
+    ClippyProjectInfo::new("root", "Cargo.toml", "src/driver.rs"),
+    ClippyProjectInfo::new("clippy_lints", "clippy_lints/Cargo.toml", "clippy_lints/src/lib.rs"),
+    ClippyProjectInfo::new("clippy_utils", "clippy_utils/Cargo.toml", "clippy_utils/src/lib.rs"),
+];
+
+/// Used to store clippy project information to later inject the dependency into.
+struct ClippyProjectInfo {
+    /// Only used to display information to the user
+    name: &'static str,
+    cargo_file: &'static str,
+    lib_rs_file: &'static str,
+}
+
+impl ClippyProjectInfo {
+    const fn new(name: &'static str, cargo_file: &'static str, lib_rs_file: &'static str) -> Self {
+        Self {
+            name,
+            cargo_file,
+            lib_rs_file,
+        }
+    }
+}
+
+pub fn setup_rustc_src(rustc_path: &str) {
+    let rustc_source_dir = match check_and_get_rustc_dir(rustc_path) {
+        Ok(path) => path,
+        Err(_) => return,
+    };
+
+    for project in CLIPPY_PROJECTS {
+        if inject_deps_into_project(&rustc_source_dir, project).is_err() {
+            return;
+        }
+    }
+
+    println!("info: the source paths can be removed again with `cargo dev remove intellij`");
+}
+
+fn check_and_get_rustc_dir(rustc_path: &str) -> Result<PathBuf, ()> {
+    let mut path = PathBuf::from(rustc_path);
+
+    if path.is_relative() {
+        match path.canonicalize() {
+            Ok(absolute_path) => {
+                println!("info: the rustc path was resolved to: `{}`", absolute_path.display());
+                path = absolute_path;
+            },
+            Err(err) => {
+                eprintln!("error: unable to get the absolute path of rustc ({})", err);
+                return Err(());
+            },
+        };
+    }
+
+    let path = path.join("compiler");
+    println!("info: looking for compiler sources at: {}", path.display());
+
+    if !path.exists() {
+        eprintln!("error: the given path does not exist");
+        return Err(());
+    }
+
+    if !path.is_dir() {
+        eprintln!("error: the given path is not a directory");
+        return Err(());
+    }
+
+    Ok(path)
+}
+
+fn inject_deps_into_project(rustc_source_dir: &Path, project: &ClippyProjectInfo) -> Result<(), ()> {
+    let cargo_content = read_project_file(project.cargo_file)?;
+    let lib_content = read_project_file(project.lib_rs_file)?;
+
+    if inject_deps_into_manifest(rustc_source_dir, project.cargo_file, &cargo_content, &lib_content).is_err() {
+        eprintln!(
+            "error: unable to inject dependencies into {} with the Cargo file {}",
+            project.name, project.cargo_file
+        );
+        Err(())
+    } else {
+        Ok(())
+    }
+}
+
+/// `clippy_dev` expects to be executed in the root directory of Clippy. This function
+/// loads the given file or returns an error. Having it in this extra function ensures
+/// that the error message looks nice.
+fn read_project_file(file_path: &str) -> Result<String, ()> {
+    let path = Path::new(file_path);
+    if !path.exists() {
+        eprintln!("error: unable to find the file `{}`", file_path);
+        return Err(());
+    }
+
+    match fs::read_to_string(path) {
+        Ok(content) => Ok(content),
+        Err(err) => {
+            eprintln!("error: the file `{}` could not be read ({})", file_path, err);
+            Err(())
+        },
+    }
+}
+
+fn inject_deps_into_manifest(
+    rustc_source_dir: &Path,
+    manifest_path: &str,
+    cargo_toml: &str,
+    lib_rs: &str,
+) -> std::io::Result<()> {
+    // do not inject deps if we have already done so
+    if cargo_toml.contains(RUSTC_PATH_SECTION) {
+        eprintln!(
+            "warn: dependencies are already setup inside {}, skipping file",
+            manifest_path
+        );
+        return Ok(());
+    }
+
+    let extern_crates = lib_rs
+        .lines()
+        // only take dependencies starting with `rustc_`
+        .filter(|line| line.starts_with("extern crate rustc_"))
+        // we have something like "extern crate foo;", we only care about the "foo"
+        // extern crate rustc_middle;
+        //              ^^^^^^^^^^^^
+        .map(|s| &s[13..(s.len() - 1)]);
+
+    let new_deps = extern_crates.map(|dep| {
+        // format the dependencies that are going to be put inside the Cargo.toml
+        format!(
+            "{dep} = {{ path = \"{source_path}/{dep}\" }}\n",
+            dep = dep,
+            source_path = rustc_source_dir.display()
+        )
+    });
+
+    // format a new [dependencies]-block with the new deps we need to inject
+    let mut all_deps = String::from("[target.'cfg(NOT_A_PLATFORM)'.dependencies]\n");
+    new_deps.for_each(|dep_line| {
+        all_deps.push_str(&dep_line);
+    });
+    all_deps.push_str("\n[dependencies]\n");
+
+    // replace "[dependencies]" with
+    // [dependencies]
+    // dep1 = { path = ... }
+    // dep2 = { path = ... }
+    // etc
+    let new_manifest = cargo_toml.replacen("[dependencies]\n", &all_deps, 1);
+
+    // println!("{}", new_manifest);
+    let mut file = File::create(manifest_path)?;
+    file.write_all(new_manifest.as_bytes())?;
+
+    println!("info: successfully setup dependencies inside {}", manifest_path);
+
+    Ok(())
+}
+
+pub fn remove_rustc_src() {
+    for project in CLIPPY_PROJECTS {
+        remove_rustc_src_from_project(project);
+    }
+}
+
+fn remove_rustc_src_from_project(project: &ClippyProjectInfo) -> bool {
+    let mut cargo_content = if let Ok(content) = read_project_file(project.cargo_file) {
+        content
+    } else {
+        return false;
+    };
+    let section_start = if let Some(section_start) = cargo_content.find(RUSTC_PATH_SECTION) {
+        section_start
+    } else {
+        println!(
+            "info: dependencies could not be found in `{}` for {}, skipping file",
+            project.cargo_file, project.name
+        );
+        return true;
+    };
+
+    let end_point = if let Some(end_point) = cargo_content.find(DEPENDENCIES_SECTION) {
+        end_point
+    } else {
+        eprintln!(
+            "error: the end of the rustc dependencies section could not be found in `{}`",
+            project.cargo_file
+        );
+        return false;
+    };
+
+    cargo_content.replace_range(section_start..end_point, "");
+
+    match File::create(project.cargo_file) {
+        Ok(mut file) => {
+            file.write_all(cargo_content.as_bytes()).unwrap();
+            println!("info: successfully removed dependencies inside {}", project.cargo_file);
+            true
+        },
+        Err(err) => {
+            eprintln!(
+                "error: unable to open file `{}` to remove rustc dependencies for {} ({})",
+                project.cargo_file, project.name, err
+            );
+            false
+        },
+    }
+}
diff --git a/src/tools/clippy/clippy_dev/src/setup/mod.rs b/src/tools/clippy/clippy_dev/src/setup/mod.rs
new file mode 100644
index 00000000000..a1e4dd103b8
--- /dev/null
+++ b/src/tools/clippy/clippy_dev/src/setup/mod.rs
@@ -0,0 +1,23 @@
+pub mod git_hook;
+pub mod intellij;
+pub mod vscode;
+
+use std::path::Path;
+
+const CLIPPY_DEV_DIR: &str = "clippy_dev";
+
+/// This function verifies that the tool is being executed in the clippy directory.
+/// This is useful to ensure that setups only modify Clippys resources. The verification
+/// is done by checking that `clippy_dev` is a sub directory of the current directory.
+///
+/// It will print an error message and return `false` if the directory could not be
+/// verified.
+fn verify_inside_clippy_dir() -> bool {
+    let path = Path::new(CLIPPY_DEV_DIR);
+    if path.exists() && path.is_dir() {
+        true
+    } else {
+        eprintln!("error: unable to verify that the working directory is clippys directory");
+        false
+    }
+}
diff --git a/src/tools/clippy/clippy_dev/src/setup/vscode.rs b/src/tools/clippy/clippy_dev/src/setup/vscode.rs
new file mode 100644
index 00000000000..d59001b2c66
--- /dev/null
+++ b/src/tools/clippy/clippy_dev/src/setup/vscode.rs
@@ -0,0 +1,104 @@
+use std::fs;
+use std::path::Path;
+
+use super::verify_inside_clippy_dir;
+
+const VSCODE_DIR: &str = ".vscode";
+const TASK_SOURCE_FILE: &str = "util/etc/vscode-tasks.json";
+const TASK_TARGET_FILE: &str = ".vscode/tasks.json";
+
+pub fn install_tasks(force_override: bool) {
+    if !check_install_precondition(force_override) {
+        return;
+    }
+
+    match fs::copy(TASK_SOURCE_FILE, TASK_TARGET_FILE) {
+        Ok(_) => {
+            println!("info: the task file can be removed with `cargo dev remove vscode-tasks`");
+            println!("vscode tasks successfully installed");
+        },
+        Err(err) => eprintln!(
+            "error: unable to copy `{}` to `{}` ({})",
+            TASK_SOURCE_FILE, TASK_TARGET_FILE, err
+        ),
+    }
+}
+
+fn check_install_precondition(force_override: bool) -> bool {
+    if !verify_inside_clippy_dir() {
+        return false;
+    }
+
+    let vs_dir_path = Path::new(VSCODE_DIR);
+    if vs_dir_path.exists() {
+        // verify the target will be valid
+        if !vs_dir_path.is_dir() {
+            eprintln!("error: the `.vscode` path exists but seems to be a file");
+            return false;
+        }
+
+        // make sure that we don't override any existing tasks by accident
+        let path = Path::new(TASK_TARGET_FILE);
+        if path.exists() {
+            if force_override {
+                return delete_vs_task_file(path);
+            }
+
+            eprintln!(
+                "error: there is already a `task.json` file inside the `{}` directory",
+                VSCODE_DIR
+            );
+            println!("info: use the `--force-override` flag to override the existing `task.json` file");
+            return false;
+        }
+    } else {
+        match fs::create_dir(vs_dir_path) {
+            Ok(_) => {
+                println!("info: created `{}` directory for clippy", VSCODE_DIR);
+            },
+            Err(err) => {
+                eprintln!(
+                    "error: the task target directory `{}` could not be created ({})",
+                    VSCODE_DIR, err
+                );
+            },
+        }
+    }
+
+    true
+}
+
+pub fn remove_tasks() {
+    let path = Path::new(TASK_TARGET_FILE);
+    if path.exists() {
+        if delete_vs_task_file(path) {
+            try_delete_vs_directory_if_empty();
+            println!("vscode tasks successfully removed");
+        }
+    } else {
+        println!("no vscode tasks were found");
+    }
+}
+
+fn delete_vs_task_file(path: &Path) -> bool {
+    if let Err(err) = fs::remove_file(path) {
+        eprintln!("error: unable to delete the existing `tasks.json` file ({})", err);
+        return false;
+    }
+
+    true
+}
+
+/// This function will try to delete the `.vscode` directory if it's empty.
+/// It may fail silently.
+fn try_delete_vs_directory_if_empty() {
+    let path = Path::new(VSCODE_DIR);
+    if path.read_dir().map_or(false, |mut iter| iter.next().is_none()) {
+        // The directory is empty. We just try to delete it but allow a silence
+        // fail as an empty `.vscode` directory is still valid
+        let _silence_result = fs::remove_dir(path);
+    } else {
+        // The directory is not empty or could not be read. Either way don't take
+        // any further actions
+    }
+}
diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs
index edf6c5f57a4..db467c26f15 100644
--- a/src/tools/clippy/clippy_dev/src/update_lints.rs
+++ b/src/tools/clippy/clippy_dev/src/update_lints.rs
@@ -92,7 +92,10 @@ pub fn run(update_mode: UpdateMode) {
         || {
             // clippy::all should only include the following lint groups:
             let all_group_lints = usable_lints.iter().filter(|l| {
-                l.group == "correctness" || l.group == "style" || l.group == "complexity" || l.group == "perf"
+                matches!(
+                    &*l.group,
+                    "correctness" | "suspicious" | "style" | "complexity" | "perf"
+                )
             });
 
             gen_lint_group_list(all_group_lints)
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index 48f2972ec58..42cf7547f51 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "clippy_lints"
 # begin automatic update
-version = "0.1.54"
+version = "0.1.55"
 # end automatic update
 authors = ["The Rust Clippy Developers"]
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
@@ -23,6 +23,7 @@ serde = { version = "1.0", features = ["derive"] }
 serde_json = { version = "1.0", optional = true }
 toml = "0.5.3"
 unicode-normalization = "0.1"
+unicode-script = { version = "0.5.3", default-features = false }
 semver = "0.11"
 rustc-semver = "1.1.0"
 # NOTE: cargo requires serde feat in its url dep
diff --git a/src/tools/clippy/clippy_lints/src/assign_ops.rs b/src/tools/clippy/clippy_lints/src/assign_ops.rs
index bc6eec0051a..a8c527fe2e3 100644
--- a/src/tools/clippy/clippy_lints/src/assign_ops.rs
+++ b/src/tools/clippy/clippy_lints/src/assign_ops.rs
@@ -55,7 +55,7 @@ declare_clippy_lint! {
     /// a += a + b;
     /// ```
     pub MISREFACTORED_ASSIGN_OP,
-    complexity,
+    suspicious,
     "having a variable on both sides of an assign op"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs
index 932cd58bf62..f272ed010a1 100644
--- a/src/tools/clippy/clippy_lints/src/attrs.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs.rs
@@ -173,7 +173,7 @@ declare_clippy_lint! {
     /// #![deny(clippy::as_conversions)]
     /// ```
     pub BLANKET_CLIPPY_RESTRICTION_LINTS,
-    style,
+    suspicious,
     "enabling the complete restriction group"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/blacklisted_name.rs b/src/tools/clippy/clippy_lints/src/blacklisted_name.rs
index b26ef33e056..8eb94f3c28e 100644
--- a/src/tools/clippy/clippy_lints/src/blacklisted_name.rs
+++ b/src/tools/clippy/clippy_lints/src/blacklisted_name.rs
@@ -1,6 +1,6 @@
-use clippy_utils::diagnostics::span_lint;
+use clippy_utils::{diagnostics::span_lint, is_test_module_or_function};
 use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::{Pat, PatKind};
+use rustc_hir::{Item, Pat, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 
@@ -25,18 +25,37 @@ declare_clippy_lint! {
 #[derive(Clone, Debug)]
 pub struct BlacklistedName {
     blacklist: FxHashSet<String>,
+    test_modules_deep: u32,
 }
 
 impl BlacklistedName {
     pub fn new(blacklist: FxHashSet<String>) -> Self {
-        Self { blacklist }
+        Self {
+            blacklist,
+            test_modules_deep: 0,
+        }
+    }
+
+    fn in_test_module(&self) -> bool {
+        self.test_modules_deep != 0
     }
 }
 
 impl_lint_pass!(BlacklistedName => [BLACKLISTED_NAME]);
 
 impl<'tcx> LateLintPass<'tcx> for BlacklistedName {
+    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
+        if is_test_module_or_function(cx.tcx, item) {
+            self.test_modules_deep = self.test_modules_deep.saturating_add(1);
+        }
+    }
+
     fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
+        // Check whether we are under the `test` attribute.
+        if self.in_test_module() {
+            return;
+        }
+
         if let PatKind::Binding(.., ident, _) = pat.kind {
             if self.blacklist.contains(&ident.name.to_string()) {
                 span_lint(
@@ -48,4 +67,10 @@ impl<'tcx> LateLintPass<'tcx> for BlacklistedName {
             }
         }
     }
+
+    fn check_item_post(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
+        if is_test_module_or_function(cx.tcx, item) {
+            self.test_modules_deep = self.test_modules_deep.saturating_sub(1);
+        }
+    }
 }
diff --git a/src/tools/clippy/clippy_lints/src/bytecount.rs b/src/tools/clippy/clippy_lints/src/bytecount.rs
index 877ae002d36..4f7ffdcdfb4 100644
--- a/src/tools/clippy/clippy_lints/src/bytecount.rs
+++ b/src/tools/clippy/clippy_lints/src/bytecount.rs
@@ -1,15 +1,15 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::match_type;
-use clippy_utils::{contains_name, get_pat_name, paths, single_segment_path};
+use clippy_utils::visitors::LocalUsedVisitor;
+use clippy_utils::{path_to_local_id, paths, peel_ref_operators, remove_blocks, strip_pat_refs};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, UnOp};
+use rustc_hir::{BinOpKind, Expr, ExprKind, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, UintTy};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::sym;
-use rustc_span::Symbol;
 
 declare_clippy_lint! {
     /// **What it does:** Checks for naive byte counts
@@ -38,42 +38,43 @@ declare_lint_pass!(ByteCount => [NAIVE_BYTECOUNT]);
 impl<'tcx> LateLintPass<'tcx> for ByteCount {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
         if_chain! {
-            if let ExprKind::MethodCall(count, _, count_args, _) = expr.kind;
+            if let ExprKind::MethodCall(count, _, [count_recv], _) = expr.kind;
             if count.ident.name == sym!(count);
-            if count_args.len() == 1;
-            if let ExprKind::MethodCall(filter, _, filter_args, _) = count_args[0].kind;
+            if let ExprKind::MethodCall(filter, _, [filter_recv, filter_arg], _) = count_recv.kind;
             if filter.ident.name == sym!(filter);
-            if filter_args.len() == 2;
-            if let ExprKind::Closure(_, _, body_id, _, _) = filter_args[1].kind;
+            if let ExprKind::Closure(_, _, body_id, _, _) = filter_arg.kind;
             let body = cx.tcx.hir().body(body_id);
-            if body.params.len() == 1;
-            if let Some(argname) = get_pat_name(body.params[0].pat);
+            if let [param] = body.params;
+            if let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind;
             if let ExprKind::Binary(ref op, l, r) = body.value.kind;
             if op.node == BinOpKind::Eq;
             if match_type(cx,
-                       cx.typeck_results().expr_ty(&filter_args[0]).peel_refs(),
+                       cx.typeck_results().expr_ty(filter_recv).peel_refs(),
                        &paths::SLICE_ITER);
+            let operand_is_arg = |expr| {
+                let expr = peel_ref_operators(cx, remove_blocks(expr));
+                path_to_local_id(expr, arg_id)
+            };
+            let needle = if operand_is_arg(l) {
+                r
+            } else if operand_is_arg(r) {
+                l
+            } else {
+                return;
+            };
+            if ty::Uint(UintTy::U8) == *cx.typeck_results().expr_ty(needle).peel_refs().kind();
+            if !LocalUsedVisitor::new(cx, arg_id).check_expr(needle);
             then {
-                let needle = match get_path_name(l) {
-                    Some(name) if check_arg(name, argname, r) => r,
-                    _ => match get_path_name(r) {
-                        Some(name) if check_arg(name, argname, l) => l,
-                        _ => { return; }
-                    }
-                };
-                if ty::Uint(UintTy::U8) != *cx.typeck_results().expr_ty(needle).peel_refs().kind() {
-                    return;
-                }
                 let haystack = if let ExprKind::MethodCall(path, _, args, _) =
-                        filter_args[0].kind {
+                        filter_recv.kind {
                     let p = path.ident.name;
                     if (p == sym::iter || p == sym!(iter_mut)) && args.len() == 1 {
                         &args[0]
                     } else {
-                        &filter_args[0]
+                        &filter_recv
                     }
                 } else {
-                    &filter_args[0]
+                    &filter_recv
                 };
                 let mut applicability = Applicability::MaybeIncorrect;
                 span_lint_and_sugg(
@@ -91,24 +92,3 @@ impl<'tcx> LateLintPass<'tcx> for ByteCount {
         };
     }
 }
-
-fn check_arg(name: Symbol, arg: Symbol, needle: &Expr<'_>) -> bool {
-    name == arg && !contains_name(name, needle)
-}
-
-fn get_path_name(expr: &Expr<'_>) -> Option<Symbol> {
-    match expr.kind {
-        ExprKind::Box(e) | ExprKind::AddrOf(BorrowKind::Ref, _, e) | ExprKind::Unary(UnOp::Deref, e) => {
-            get_path_name(e)
-        },
-        ExprKind::Block(b, _) => {
-            if b.stmts.is_empty() {
-                b.expr.as_ref().and_then(|p| get_path_name(p))
-            } else {
-                None
-            }
-        },
-        ExprKind::Path(ref qpath) => single_segment_path(qpath).map(|ps| ps.ident.name),
-        _ => None,
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/collapsible_match.rs b/src/tools/clippy/clippy_lints/src/collapsible_match.rs
index ab22578abd6..a6c3a5b0e83 100644
--- a/src/tools/clippy/clippy_lints/src/collapsible_match.rs
+++ b/src/tools/clippy/clippy_lints/src/collapsible_match.rs
@@ -1,11 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::visitors::LocalUsedVisitor;
-use clippy_utils::{is_lang_ctor, path_to_local, SpanlessEq};
+use clippy_utils::{is_lang_ctor, path_to_local, peel_ref_operators, SpanlessEq};
 use if_chain::if_chain;
 use rustc_hir::LangItem::OptionNone;
-use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind, StmtKind, UnOp};
+use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::TypeckResults;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::{MultiSpan, Span};
 
@@ -73,7 +72,7 @@ fn check_arm<'tcx>(arm: &Arm<'tcx>, wild_outer_arm: &Arm<'tcx>, cx: &LateContext
         if arms_inner.iter().all(|arm| arm.guard.is_none());
         // match expression must be a local binding
         // match <local> { .. }
-        if let Some(binding_id) = path_to_local(strip_ref_operators(expr_in, cx.typeck_results()));
+        if let Some(binding_id) = path_to_local(peel_ref_operators(cx, expr_in));
         // one of the branches must be "wild-like"
         if let Some(wild_inner_arm_idx) = arms_inner.iter().rposition(|arm_inner| arm_is_wild_like(cx, arm_inner));
         let (wild_inner_arm, non_wild_inner_arm) =
@@ -163,16 +162,3 @@ fn pat_contains_or(pat: &Pat<'_>) -> bool {
     });
     result
 }
-
-/// Removes `AddrOf` operators (`&`) or deref operators (`*`), but only if a reference type is
-/// dereferenced. An overloaded deref such as `Vec` to slice would not be removed.
-fn strip_ref_operators<'hir>(mut expr: &'hir Expr<'hir>, typeck_results: &TypeckResults<'_>) -> &'hir Expr<'hir> {
-    loop {
-        match expr.kind {
-            ExprKind::AddrOf(_, _, e) => expr = e,
-            ExprKind::Unary(UnOp::Deref, e) if typeck_results.expr_ty(e).is_ref() => expr = e,
-            _ => break,
-        }
-    }
-    expr
-}
diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs
index 7a53d390bb4..947479db8f5 100644
--- a/src/tools/clippy/clippy_lints/src/default.rs
+++ b/src/tools/clippy/clippy_lints/src/default.rs
@@ -7,7 +7,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::{Ident, Symbol};
@@ -122,7 +121,7 @@ impl LateLintPass<'_> for Default {
                 if let StmtKind::Local(local) = stmt.kind;
                 if let Some(expr) = local.init;
                 if !any_parent_is_automatically_derived(cx.tcx, expr.hir_id);
-                if !in_external_macro(cx.tcx.sess, expr.span);
+                if !in_macro(expr.span);
                 // only take bindings to identifiers
                 if let PatKind::Binding(_, binding_id, ident, _) = local.pat.kind;
                 // only when assigning `... = Default::default()`
diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
index 759f7d4062d..a125376bffa 100644
--- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
+++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
@@ -7,9 +7,10 @@ use rustc_hir::{
     intravisit::{walk_expr, walk_stmt, NestedVisitorMap, Visitor},
     Body, Expr, ExprKind, HirId, Lit, Stmt, StmtKind,
 };
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::{
     hir::map::Map,
+    lint::in_external_macro,
     ty::{self, FloatTy, IntTy, PolyFnSig, Ty},
 };
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -73,6 +74,7 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
     /// Check whether a passed literal has potential to cause fallback or not.
     fn check_lit(&self, lit: &Lit, lit_ty: Ty<'tcx>) {
         if_chain! {
+                if !in_external_macro(self.cx.sess(), lit.span);
                 if let Some(ty_bound) = self.ty_bounds.last();
                 if matches!(lit.node,
                             LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed));
diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
index 04f3d77464f..2933fbc9341 100644
--- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
@@ -149,7 +149,7 @@ declare_deprecated_lint! {
     /// enables the `enum_variant_names` lint for public items.
     /// ```
     pub PUB_ENUM_VARIANT_NAMES,
-    "set the `avoid_breaking_exported_api` config option to `false` to enable the `enum_variant_names` lint for public items"
+    "set the `avoid-breaking-exported-api` config option to `false` to enable the `enum_variant_names` lint for public items"
 }
 
 declare_deprecated_lint! {
@@ -158,5 +158,5 @@ declare_deprecated_lint! {
     /// **Deprecation reason:** The `avoid_breaking_exported_api` config option was added, which
     /// enables the `wrong_self_conversion` lint for public items.
     pub WRONG_PUB_SELF_CONVENTION,
-    "set the `avoid_breaking_exported_api` config option to `false` to enable the `wrong_self_convention` lint for public items"
+    "set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items"
 }
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 729941f345a..3ac20fd9849 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -410,11 +410,8 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
         }
 
         if let ExprKind::Block(block, _) = expr.kind {
-            match block.rules {
-                BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) => {
-                    self.has_unsafe = true;
-                },
-                _ => {},
+            if let BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) = block.rules {
+                self.has_unsafe = true;
             }
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_method.rs b/src/tools/clippy/clippy_lints/src/disallowed_method.rs
index ded0a0fff54..aa1a609afed 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_method.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_method.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint;
 use clippy_utils::fn_def_id;
 
 use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::Expr;
+use rustc_hir::{def::Res, def_id::DefId, Crate, Expr};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::Symbol;
@@ -13,21 +13,14 @@ declare_clippy_lint! {
     /// **Why is this bad?** Some methods are undesirable in certain contexts,
     /// and it's beneficial to lint for them as needed.
     ///
-    /// **Known problems:** Currently, you must write each function as a
-    /// fully-qualified path. This lint doesn't support aliases or reexported
-    /// names; be aware that many types in `std` are actually reexports.
-    ///
-    /// For example, if you want to disallow `Duration::as_secs`, your clippy.toml
-    /// configuration would look like
-    /// `disallowed-methods = ["core::time::Duration::as_secs"]` and not
-    /// `disallowed-methods = ["std::time::Duration::as_secs"]` as you might expect.
+    /// **Known problems:** None.
     ///
     /// **Example:**
     ///
     /// An example clippy.toml configuration:
     /// ```toml
     /// # clippy.toml
-    /// disallowed-methods = ["alloc::vec::Vec::leak", "std::time::Instant::now"]
+    /// disallowed-methods = ["std::vec::Vec::leak", "std::time::Instant::now"]
     /// ```
     ///
     /// ```rust,ignore
@@ -52,6 +45,7 @@ declare_clippy_lint! {
 #[derive(Clone, Debug)]
 pub struct DisallowedMethod {
     disallowed: FxHashSet<Vec<Symbol>>,
+    def_ids: FxHashSet<(DefId, Vec<Symbol>)>,
 }
 
 impl DisallowedMethod {
@@ -61,6 +55,7 @@ impl DisallowedMethod {
                 .iter()
                 .map(|s| s.split("::").map(|seg| Symbol::intern(seg)).collect::<Vec<_>>())
                 .collect(),
+            def_ids: FxHashSet::default(),
         }
     }
 }
@@ -68,10 +63,20 @@ impl DisallowedMethod {
 impl_lint_pass!(DisallowedMethod => [DISALLOWED_METHOD]);
 
 impl<'tcx> LateLintPass<'tcx> for DisallowedMethod {
+    fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
+        for path in &self.disallowed {
+            let segs = path.iter().map(ToString::to_string).collect::<Vec<_>>();
+            if let Res::Def(_, id) = clippy_utils::path_to_res(cx, &segs.iter().map(String::as_str).collect::<Vec<_>>())
+            {
+                self.def_ids.insert((id, path.clone()));
+            }
+        }
+    }
+
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if let Some(def_id) = fn_def_id(cx, expr) {
-            let func_path = cx.get_def_path(def_id);
-            if self.disallowed.contains(&func_path) {
+            if self.def_ids.iter().any(|(id, _)| def_id == *id) {
+                let func_path = cx.get_def_path(def_id);
                 let func_path_string = func_path
                     .into_iter()
                     .map(Symbol::to_ident_string)
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
new file mode 100644
index 00000000000..12c525634c5
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
@@ -0,0 +1,112 @@
+use clippy_utils::diagnostics::span_lint;
+use rustc_ast::ast;
+use rustc_data_structures::fx::FxHashSet;
+use rustc_lint::{EarlyContext, EarlyLintPass, Level};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use unicode_script::{Script, UnicodeScript};
+
+declare_clippy_lint! {
+    /// **What it does:** Checks for usage of unicode scripts other than those explicitly allowed
+    /// by the lint config.
+    ///
+    /// This lint doesn't take into account non-text scripts such as `Unknown` and `Linear_A`.
+    /// It also ignores the `Common` script type.
+    /// While configuring, be sure to use official script name [aliases] from
+    /// [the list of supported scripts][supported_scripts].
+    ///
+    /// See also: [`non_ascii_idents`].
+    ///
+    /// [aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases
+    /// [supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html
+    ///
+    /// **Why is this bad?** It may be not desired to have many different scripts for
+    /// identifiers in the codebase.
+    ///
+    /// Note that if you only want to allow plain English, you might want to use
+    /// built-in [`non_ascii_idents`] lint instead.
+    ///
+    /// [`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    /// ```rust
+    /// // Assuming that `clippy.toml` contains the following line:
+    /// // allowed-locales = ["Latin", "Cyrillic"]
+    /// let counter = 10; // OK, latin is allowed.
+    /// let счётчик = 10; // OK, cyrillic is allowed.
+    /// let zähler = 10; // OK, it's still latin.
+    /// let カウンタ = 10; // Will spawn the lint.
+    /// ```
+    pub DISALLOWED_SCRIPT_IDENTS,
+    restriction,
+    "usage of non-allowed Unicode scripts"
+}
+
+#[derive(Clone, Debug)]
+pub struct DisallowedScriptIdents {
+    whitelist: FxHashSet<Script>,
+}
+
+impl DisallowedScriptIdents {
+    pub fn new(whitelist: &[String]) -> Self {
+        let whitelist = whitelist
+            .iter()
+            .map(String::as_str)
+            .filter_map(Script::from_full_name)
+            .collect();
+        Self { whitelist }
+    }
+}
+
+impl_lint_pass!(DisallowedScriptIdents => [DISALLOWED_SCRIPT_IDENTS]);
+
+impl EarlyLintPass for DisallowedScriptIdents {
+    fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
+        // Implementation is heavily inspired by the implementation of [`non_ascii_idents`] lint:
+        // https://github.com/rust-lang/rust/blob/master/compiler/rustc_lint/src/non_ascii_idents.rs
+
+        let check_disallowed_script_idents = cx.builder.lint_level(DISALLOWED_SCRIPT_IDENTS).0 != Level::Allow;
+        if !check_disallowed_script_idents {
+            return;
+        }
+
+        let symbols = cx.sess.parse_sess.symbol_gallery.symbols.lock();
+        // Sort by `Span` so that error messages make sense with respect to the
+        // order of identifier locations in the code.
+        let mut symbols: Vec<_> = symbols.iter().collect();
+        symbols.sort_unstable_by_key(|k| k.1);
+
+        for (symbol, &span) in &symbols {
+            // Note: `symbol.as_str()` is an expensive operation, thus should not be called
+            // more than once for a single symbol.
+            let symbol_str = symbol.as_str();
+            if symbol_str.is_ascii() {
+                continue;
+            }
+
+            for c in symbol_str.chars() {
+                // We want to iterate through all the scripts associated with this character
+                // and check whether at least of one scripts is in the whitelist.
+                let forbidden_script = c
+                    .script_extension()
+                    .iter()
+                    .find(|script| !self.whitelist.contains(script));
+                if let Some(script) = forbidden_script {
+                    span_lint(
+                        cx,
+                        DISALLOWED_SCRIPT_IDENTS,
+                        span,
+                        &format!(
+                            "identifier `{}` has a Unicode script that is not allowed by configuration: {}",
+                            symbol_str,
+                            script.full_name()
+                        ),
+                    );
+                    // We don't want to spawn warning multiple times over a single identifier.
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_type.rs b/src/tools/clippy/clippy_lints/src/disallowed_type.rs
new file mode 100644
index 00000000000..e4a88c6324e
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/disallowed_type.rs
@@ -0,0 +1,126 @@
+use clippy_utils::diagnostics::span_lint;
+
+use rustc_data_structures::fx::FxHashSet;
+use rustc_hir::{
+    def::Res, def_id::DefId, Crate, Item, ItemKind, PolyTraitRef, TraitBoundModifier, Ty, TyKind, UseKind,
+};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::{Span, Symbol};
+
+declare_clippy_lint! {
+    /// **What it does:** Denies the configured types in clippy.toml.
+    ///
+    /// **Why is this bad?** Some types are undesirable in certain contexts.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// N.B. There is no way to ban primitive types.
+    ///
+    /// **Example:**
+    ///
+    /// An example clippy.toml configuration:
+    /// ```toml
+    /// # clippy.toml
+    /// disallowed-methods = ["std::collections::BTreeMap"]
+    /// ```
+    ///
+    /// ```rust,ignore
+    /// use std::collections::BTreeMap;
+    /// // or its use
+    /// let x = std::collections::BTreeMap::new();
+    /// ```
+    /// Use instead:
+    /// ```rust,ignore
+    /// // A similar type that is allowed by the config
+    /// use std::collections::HashMap;
+    /// ```
+    pub DISALLOWED_TYPE,
+    nursery,
+    "use of a disallowed type"
+}
+#[derive(Clone, Debug)]
+pub struct DisallowedType {
+    disallowed: FxHashSet<Vec<Symbol>>,
+    def_ids: FxHashSet<(DefId, Vec<Symbol>)>,
+}
+
+impl DisallowedType {
+    pub fn new(disallowed: &FxHashSet<String>) -> Self {
+        Self {
+            disallowed: disallowed
+                .iter()
+                .map(|s| s.split("::").map(|seg| Symbol::intern(seg)).collect::<Vec<_>>())
+                .collect(),
+            def_ids: FxHashSet::default(),
+        }
+    }
+}
+
+impl_lint_pass!(DisallowedType => [DISALLOWED_TYPE]);
+
+impl<'tcx> LateLintPass<'tcx> for DisallowedType {
+    fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
+        for path in &self.disallowed {
+            let segs = path.iter().map(ToString::to_string).collect::<Vec<_>>();
+            if let Res::Def(_, id) = clippy_utils::path_to_res(cx, &segs.iter().map(String::as_str).collect::<Vec<_>>())
+            {
+                self.def_ids.insert((id, path.clone()));
+            }
+        }
+    }
+
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
+        if_chain! {
+            if let ItemKind::Use(path, UseKind::Single) = &item.kind;
+            if let Res::Def(_, did) = path.res;
+            if let Some((_, name)) = self.def_ids.iter().find(|(id, _)| *id == did);
+            then {
+                emit(cx, name, item.span,);
+            }
+        }
+    }
+
+    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) {
+        if_chain! {
+            if let TyKind::Path(path) = &ty.kind;
+            if let Some(did) = cx.qpath_res(path, ty.hir_id).opt_def_id();
+            if let Some((_, name)) = self.def_ids.iter().find(|(id, _)| *id == did);
+            then {
+                emit(cx, name, path.span());
+            }
+        }
+    }
+
+    fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>, _: TraitBoundModifier) {
+        if_chain! {
+            if let Res::Def(_, did) = poly.trait_ref.path.res;
+            if let Some((_, name)) = self.def_ids.iter().find(|(id, _)| *id == did);
+            then {
+                emit(cx, name, poly.trait_ref.path.span);
+            }
+        }
+    }
+
+    // TODO: if non primitive const generics are a thing
+    // fn check_generic_arg(&mut self, cx: &LateContext<'tcx>, arg: &'tcx GenericArg<'tcx>) {
+    //     match arg {
+    //         GenericArg::Const(c) => {},
+    //     }
+    // }
+    // fn check_generic_param(&mut self, cx: &LateContext<'tcx>, param: &'tcx GenericParam<'tcx>) {
+    //     match param.kind {
+    //         GenericParamKind::Const { .. } => {},
+    //     }
+    // }
+}
+
+fn emit(cx: &LateContext<'_>, name: &[Symbol], span: Span) {
+    let name = name.iter().map(|s| s.to_ident_string()).collect::<Vec<_>>().join("::");
+    span_lint(
+        cx,
+        DISALLOWED_TYPE,
+        span,
+        &format!("`{}` is not allowed according to config", name),
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index e67ec4e06c5..4e164d33a05 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -1,4 +1,5 @@
-use clippy_utils::diagnostics::{span_lint, span_lint_and_note};
+use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_note};
+use clippy_utils::source::first_line_of_span;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use clippy_utils::{is_entrypoint_fn, is_expn_of, match_panic_def_id, method_chain_args, return_ty};
 use if_chain::if_chain;
@@ -37,7 +38,8 @@ declare_clippy_lint! {
     /// consider that.
     ///
     /// **Known problems:** Lots of bad docs won’t be fixed, what the lint checks
-    /// for is limited, and there are still false positives.
+    /// for is limited, and there are still false positives. HTML elements and their
+    /// content are not linted.
     ///
     /// In addition, when writing documentation comments, including `[]` brackets
     /// inside a link text would trip the parser. Therfore, documenting link with
@@ -469,11 +471,11 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
     spans: &[(usize, Span)],
 ) -> DocHeaders {
     // true if a safety header was found
-    use pulldown_cmark::CodeBlockKind;
     use pulldown_cmark::Event::{
         Code, End, FootnoteReference, HardBreak, Html, Rule, SoftBreak, Start, TaskListMarker, Text,
     };
-    use pulldown_cmark::Tag::{CodeBlock, Heading, Link};
+    use pulldown_cmark::Tag::{CodeBlock, Heading, Item, Link, Paragraph};
+    use pulldown_cmark::{CodeBlockKind, CowStr};
 
     let mut headers = DocHeaders {
         safety: false,
@@ -485,6 +487,9 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
     let mut in_heading = false;
     let mut is_rust = false;
     let mut edition = None;
+    let mut ticks_unbalanced = false;
+    let mut text_to_check: Vec<(CowStr<'_>, Span)> = Vec::new();
+    let mut paragraph_span = spans.get(0).expect("function isn't called if doc comment is empty").1;
     for (event, range) in events {
         match event {
             Start(CodeBlock(ref kind)) => {
@@ -510,13 +515,42 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
             },
             Start(Link(_, url, _)) => in_link = Some(url),
             End(Link(..)) => in_link = None,
-            Start(Heading(_)) => in_heading = true,
-            End(Heading(_)) => in_heading = false,
+            Start(Heading(_) | Paragraph | Item) => {
+                if let Start(Heading(_)) = event {
+                    in_heading = true;
+                }
+                ticks_unbalanced = false;
+                let (_, span) = get_current_span(spans, range.start);
+                paragraph_span = first_line_of_span(cx, span);
+            },
+            End(Heading(_) | Paragraph | Item) => {
+                if let End(Heading(_)) = event {
+                    in_heading = false;
+                }
+                if ticks_unbalanced {
+                    span_lint_and_help(
+                        cx,
+                        DOC_MARKDOWN,
+                        paragraph_span,
+                        "backticks are unbalanced",
+                        None,
+                        "a backtick may be missing a pair",
+                    );
+                } else {
+                    for (text, span) in text_to_check {
+                        check_text(cx, valid_idents, &text, span);
+                    }
+                }
+                text_to_check = Vec::new();
+            },
             Start(_tag) | End(_tag) => (), // We don't care about other tags
             Html(_html) => (),             // HTML is weird, just ignore it
             SoftBreak | HardBreak | TaskListMarker(_) | Code(_) | Rule => (),
             FootnoteReference(text) | Text(text) => {
-                if Some(&text) == in_link.as_ref() {
+                let (begin, span) = get_current_span(spans, range.start);
+                paragraph_span = paragraph_span.with_hi(span.hi());
+                ticks_unbalanced |= text.contains('`');
+                if Some(&text) == in_link.as_ref() || ticks_unbalanced {
                     // Probably a link of the form `<http://example.com>`
                     // Which are represented as a link to "http://example.com" with
                     // text "http://example.com" by pulldown-cmark
@@ -525,11 +559,6 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                 headers.safety |= in_heading && text.trim() == "Safety";
                 headers.errors |= in_heading && text.trim() == "Errors";
                 headers.panics |= in_heading && text.trim() == "Panics";
-                let index = match spans.binary_search_by(|c| c.0.cmp(&range.start)) {
-                    Ok(o) => o,
-                    Err(e) => e - 1,
-                };
-                let (begin, span) = spans[index];
                 if in_code {
                     if is_rust {
                         let edition = edition.unwrap_or_else(|| cx.tcx.sess.edition());
@@ -538,8 +567,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                 } else {
                     // Adjust for the beginning of the current `Event`
                     let span = span.with_lo(span.lo() + BytePos::from_usize(range.start - begin));
-
-                    check_text(cx, valid_idents, &text, span);
+                    text_to_check.push((text, span));
                 }
             },
         }
@@ -547,6 +575,14 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
     headers
 }
 
+fn get_current_span(spans: &[(usize, Span)], idx: usize) -> (usize, Span) {
+    let index = match spans.binary_search_by(|c| c.0.cmp(&idx)) {
+        Ok(o) => o,
+        Err(e) => e - 1,
+    };
+    spans[index]
+}
+
 fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
     fn has_needless_main(code: &str, edition: Edition) -> bool {
         rustc_driver::catch_fatal_errors(|| {
diff --git a/src/tools/clippy/clippy_lints/src/eval_order_dependence.rs b/src/tools/clippy/clippy_lints/src/eval_order_dependence.rs
index 5fdf5bc9e9d..03a8b40df55 100644
--- a/src/tools/clippy/clippy_lints/src/eval_order_dependence.rs
+++ b/src/tools/clippy/clippy_lints/src/eval_order_dependence.rs
@@ -38,7 +38,7 @@ declare_clippy_lint! {
     /// let a = tmp + x;
     /// ```
     pub EVAL_ORDER_DEPENDENCE,
-    complexity,
+    suspicious,
     "whether a variable read occurs before a write depends on sub-expression evaluation order"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs b/src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs
index b5ebe5f90ba..1e503cc795c 100644
--- a/src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs
+++ b/src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs
@@ -36,7 +36,7 @@ declare_clippy_lint! {
      /// }
      /// ```
     pub FLOAT_EQUALITY_WITHOUT_ABS,
-    correctness,
+    suspicious,
     "float equality check without `.abs()`"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/formatting.rs b/src/tools/clippy/clippy_lints/src/formatting.rs
index 3bd6a09d365..8aefb8d46f6 100644
--- a/src/tools/clippy/clippy_lints/src/formatting.rs
+++ b/src/tools/clippy/clippy_lints/src/formatting.rs
@@ -22,7 +22,7 @@ declare_clippy_lint! {
     /// a =- 42; // confusing, should it be `a -= 42` or `a = -42`?
     /// ```
     pub SUSPICIOUS_ASSIGNMENT_FORMATTING,
-    style,
+    suspicious,
     "suspicious formatting of `*=`, `-=` or `!=`"
 }
 
@@ -44,7 +44,7 @@ declare_clippy_lint! {
     /// }
     /// ```
     pub SUSPICIOUS_UNARY_OP_FORMATTING,
-    style,
+    suspicious,
     "suspicious formatting of unary `-` or `!` on the RHS of a BinOp"
 }
 
@@ -80,7 +80,7 @@ declare_clippy_lint! {
     /// }
     /// ```
     pub SUSPICIOUS_ELSE_FORMATTING,
-    style,
+    suspicious,
     "suspicious formatting of `else`"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/get_last_with_len.rs b/src/tools/clippy/clippy_lints/src/get_last_with_len.rs
index 3707e792177..8e45fdfecc4 100644
--- a/src/tools/clippy/clippy_lints/src/get_last_with_len.rs
+++ b/src/tools/clippy/clippy_lints/src/get_last_with_len.rs
@@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for GetLastWithLen {
 
             // LHS of subtraction is "x.len()"
             if let ExprKind::MethodCall(arg_lhs_path, _, lhs_args, _) = &lhs.kind;
-            if arg_lhs_path.ident.name == sym!(len);
+            if arg_lhs_path.ident.name == sym::len;
             if let Some(arg_lhs_struct) = lhs_args.get(0);
 
             // The two vectors referenced (x in x.get(...) and in x.len())
diff --git a/src/tools/clippy/clippy_lints/src/if_let_mutex.rs b/src/tools/clippy/clippy_lints/src/if_let_mutex.rs
index f661f7ede82..5403d76ea30 100644
--- a/src/tools/clippy/clippy_lints/src/if_let_mutex.rs
+++ b/src/tools/clippy/clippy_lints/src/if_let_mutex.rs
@@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for IfLetMutex {
     }
 }
 
-/// Checks if `Mutex::lock` is called in the `if let _ = expr.
+/// Checks if `Mutex::lock` is called in the `if let` expr.
 pub struct OppVisitor<'a, 'tcx> {
     mutex_lock_called: bool,
     found_mutex: Option<&'tcx Expr<'tcx>>,
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 583514b22f9..d69187f6746 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
         if_chain! {
-            if item.ident.as_str() == "len";
+            if item.ident.name == sym::len;
             if let ImplItemKind::Fn(sig, _) = &item.kind;
             if sig.decl.implicit_self.has_implicit_self();
             if cx.access_levels.is_exported(item.hir_id());
@@ -189,8 +189,8 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
 }
 
 fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items: &[TraitItemRef]) {
-    fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: &str) -> bool {
-        item.ident.name.as_str() == name
+    fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool {
+        item.ident.name == name
             && if let AssocItemKind::Fn { has_self } = item.kind {
                 has_self && { cx.tcx.fn_sig(item.id.def_id).inputs().skip_binder().len() == 1 }
             } else {
@@ -207,7 +207,9 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
         }
     }
 
-    if cx.access_levels.is_exported(visited_trait.hir_id()) && trait_items.iter().any(|i| is_named_self(cx, i, "len")) {
+    if cx.access_levels.is_exported(visited_trait.hir_id())
+        && trait_items.iter().any(|i| is_named_self(cx, i, sym::len))
+    {
         let mut current_and_super_traits = DefIdSet::default();
         fill_trait_set(visited_trait.def_id.to_def_id(), &mut current_and_super_traits, cx);
 
@@ -401,7 +403,7 @@ fn check_len(
             return;
         }
 
-        if method_name.as_str() == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) {
+        if method_name == sym::len && args.len() == 1 && has_is_empty(cx, &args[0]) {
             let mut applicability = Applicability::MachineApplicable;
             span_lint_and_sugg(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index e7dd3952b3a..e0325738466 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -60,9 +60,9 @@ use rustc_session::Session;
 /// 4. The `description` that contains a short explanation on what's wrong with code where the
 ///    lint is triggered.
 ///
-/// Currently the categories `style`, `correctness`, `complexity` and `perf` are enabled by default.
-/// As said in the README.md of this repository, if the lint level mapping changes, please update
-/// README.md.
+/// Currently the categories `style`, `correctness`, `suspicious`, `complexity` and `perf` are
+/// enabled by default. As said in the README.md of this repository, if the lint level mapping
+/// changes, please update README.md.
 ///
 /// # Example
 ///
@@ -106,6 +106,11 @@ macro_rules! declare_clippy_lint {
             $(#[$attr])* pub clippy::$name, Deny, $description, report_in_external_macro: true
         }
     };
+    { $(#[$attr:meta])* pub $name:tt, suspicious, $description:tt } => {
+        declare_tool_lint! {
+            $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
+        }
+    };
     { $(#[$attr:meta])* pub $name:tt, complexity, $description:tt } => {
         declare_tool_lint! {
             $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
@@ -187,6 +192,8 @@ mod default_numeric_fallback;
 mod dereference;
 mod derive;
 mod disallowed_method;
+mod disallowed_script_idents;
+mod disallowed_type;
 mod doc;
 mod double_comparison;
 mod double_parens;
@@ -254,7 +261,6 @@ mod manual_strip;
 mod manual_unwrap_or;
 mod map_clone;
 mod map_err_ignore;
-mod map_identity;
 mod map_unit_fn;
 mod match_on_vec_items;
 mod matches;
@@ -267,6 +273,7 @@ mod misc;
 mod misc_early;
 mod missing_const_for_fn;
 mod missing_doc;
+mod missing_enforced_import_rename;
 mod missing_inline;
 mod modulo_arithmetic;
 mod multiple_crate_versions;
@@ -293,6 +300,7 @@ mod no_effect;
 mod non_copy_const;
 mod non_expressive_names;
 mod non_octal_unix_permissions;
+mod nonstandard_macro_braces;
 mod open_options;
 mod option_env_unwrap;
 mod option_if_let_else;
@@ -483,11 +491,11 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     );
     store.register_removed(
         "clippy::pub_enum_variant_names",
-        "set the `avoid_breaking_exported_api` config option to `false` to enable the `enum_variant_names` lint for public items",
+        "set the `avoid-breaking-exported-api` config option to `false` to enable the `enum_variant_names` lint for public items",
     );
     store.register_removed(
         "clippy::wrong_pub_self_convention",
-        "set the `avoid_breaking_exported_api` config option to `false` to enable the `wrong_self_convention` lint for public items",
+        "set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items",
     );
     // end deprecated lints, do not remove this comment, it’s used in `update_lints`
 
@@ -583,6 +591,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         derive::EXPL_IMPL_CLONE_ON_COPY,
         derive::UNSAFE_DERIVE_DESERIALIZE,
         disallowed_method::DISALLOWED_METHOD,
+        disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS,
+        disallowed_type::DISALLOWED_TYPE,
         doc::DOC_MARKDOWN,
         doc::MISSING_ERRORS_DOC,
         doc::MISSING_PANICS_DOC,
@@ -705,7 +715,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         manual_unwrap_or::MANUAL_UNWRAP_OR,
         map_clone::MAP_CLONE,
         map_err_ignore::MAP_ERR_IGNORE,
-        map_identity::MAP_IDENTITY,
         map_unit_fn::OPTION_MAP_UNIT_FN,
         map_unit_fn::RESULT_MAP_UNIT_FN,
         match_on_vec_items::MATCH_ON_VEC_ITEMS,
@@ -730,6 +739,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         mem_replace::MEM_REPLACE_OPTION_WITH_NONE,
         mem_replace::MEM_REPLACE_WITH_DEFAULT,
         mem_replace::MEM_REPLACE_WITH_UNINIT,
+        methods::APPEND_INSTEAD_OF_EXTEND,
         methods::BIND_INSTEAD_OF_MAP,
         methods::BYTES_NTH,
         methods::CHARS_LAST_CMP,
@@ -765,6 +775,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         methods::MANUAL_STR_REPEAT,
         methods::MAP_COLLECT_RESULT_UNIT,
         methods::MAP_FLATTEN,
+        methods::MAP_IDENTITY,
         methods::MAP_UNWRAP_OR,
         methods::NEW_RET_NO_SELF,
         methods::OK_EXPECT,
@@ -810,6 +821,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         misc_early::ZERO_PREFIXED_LITERAL,
         missing_const_for_fn::MISSING_CONST_FOR_FN,
         missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS,
+        missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES,
         missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS,
         modulo_arithmetic::MODULO_ARITHMETIC,
         multiple_crate_versions::MULTIPLE_CRATE_VERSIONS,
@@ -843,6 +855,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         non_expressive_names::MANY_SINGLE_CHAR_NAMES,
         non_expressive_names::SIMILAR_NAMES,
         non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS,
+        nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES,
         open_options::NONSENSICAL_OPEN_OPTIONS,
         option_env_unwrap::OPTION_ENV_UNWRAP,
         option_if_let_else::OPTION_IF_LET_ELSE,
@@ -989,6 +1002,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(create_dir::CREATE_DIR),
         LintId::of(dbg_macro::DBG_MACRO),
         LintId::of(default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK),
+        LintId::of(disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS),
         LintId::of(else_if_without_else::ELSE_IF_WITHOUT_ELSE),
         LintId::of(exhaustive_items::EXHAUSTIVE_ENUMS),
         LintId::of(exhaustive_items::EXHAUSTIVE_STRUCTS),
@@ -1013,6 +1027,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(misc::FLOAT_CMP_CONST),
         LintId::of(misc_early::UNNEEDED_FIELD_PATTERN),
         LintId::of(missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS),
+        LintId::of(missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES),
         LintId::of(missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS),
         LintId::of(modulo_arithmetic::MODULO_ARITHMETIC),
         LintId::of(panic_in_result_fn::PANIC_IN_RESULT_FN),
@@ -1090,6 +1105,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(methods::CLONED_INSTEAD_OF_COPIED),
         LintId::of(methods::FILTER_MAP_NEXT),
         LintId::of(methods::FLAT_MAP_OPTION),
+        LintId::of(methods::FROM_ITER_INSTEAD_OF_COLLECT),
         LintId::of(methods::IMPLICIT_CLONE),
         LintId::of(methods::INEFFICIENT_TO_STRING),
         LintId::of(methods::MAP_FLATTEN),
@@ -1260,7 +1276,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(manual_strip::MANUAL_STRIP),
         LintId::of(manual_unwrap_or::MANUAL_UNWRAP_OR),
         LintId::of(map_clone::MAP_CLONE),
-        LintId::of(map_identity::MAP_IDENTITY),
         LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
         LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
         LintId::of(matches::INFALLIBLE_DESTRUCTURING_MATCH),
@@ -1276,6 +1291,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
         LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
         LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
+        LintId::of(methods::APPEND_INSTEAD_OF_EXTEND),
         LintId::of(methods::BIND_INSTEAD_OF_MAP),
         LintId::of(methods::BYTES_NTH),
         LintId::of(methods::CHARS_LAST_CMP),
@@ -1286,7 +1302,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(methods::FILTER_MAP_IDENTITY),
         LintId::of(methods::FILTER_NEXT),
         LintId::of(methods::FLAT_MAP_IDENTITY),
-        LintId::of(methods::FROM_ITER_INSTEAD_OF_COLLECT),
         LintId::of(methods::INSPECT_FOR_EACH),
         LintId::of(methods::INTO_ITER_ON_REF),
         LintId::of(methods::ITERATOR_STEP_BY_ZERO),
@@ -1301,6 +1316,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
         LintId::of(methods::MANUAL_STR_REPEAT),
         LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
+        LintId::of(methods::MAP_IDENTITY),
         LintId::of(methods::NEW_RET_NO_SELF),
         LintId::of(methods::OK_EXPECT),
         LintId::of(methods::OPTION_AS_REF_DEREF),
@@ -1359,6 +1375,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
         LintId::of(non_expressive_names::MANY_SINGLE_CHAR_NAMES),
         LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
+        LintId::of(nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES),
         LintId::of(open_options::NONSENSICAL_OPEN_OPTIONS),
         LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
         LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
@@ -1447,7 +1464,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_group(true, "clippy::style", Some("clippy_style"), vec![
         LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
         LintId::of(assign_ops::ASSIGN_OP_PATTERN),
-        LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
         LintId::of(blacklisted_name::BLACKLISTED_NAME),
         LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
         LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
@@ -1465,9 +1481,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(eq_op::OP_REF),
         LintId::of(eta_reduction::REDUNDANT_CLOSURE),
         LintId::of(float_literal::EXCESSIVE_PRECISION),
-        LintId::of(formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
-        LintId::of(formatting::SUSPICIOUS_ELSE_FORMATTING),
-        LintId::of(formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
         LintId::of(from_over_into::FROM_OVER_INTO),
         LintId::of(from_str_radix_10::FROM_STR_RADIX_10),
         LintId::of(functions::DOUBLE_MUST_USE),
@@ -1480,7 +1493,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(len_zero::LEN_ZERO),
         LintId::of(literal_representation::INCONSISTENT_DIGIT_GROUPING),
         LintId::of(literal_representation::UNUSUAL_BYTE_GROUPINGS),
-        LintId::of(loops::EMPTY_LOOP),
         LintId::of(loops::FOR_KV_MAP),
         LintId::of(loops::NEEDLESS_RANGE_LOOP),
         LintId::of(loops::SAME_ITEM_PUSH),
@@ -1501,7 +1513,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(methods::BYTES_NTH),
         LintId::of(methods::CHARS_LAST_CMP),
         LintId::of(methods::CHARS_NEXT_CMP),
-        LintId::of(methods::FROM_ITER_INSTEAD_OF_COLLECT),
         LintId::of(methods::INTO_ITER_ON_REF),
         LintId::of(methods::ITER_CLONED_COLLECT),
         LintId::of(methods::ITER_NEXT_SLICE),
@@ -1535,6 +1546,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
         LintId::of(non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
         LintId::of(non_expressive_names::MANY_SINGLE_CHAR_NAMES),
+        LintId::of(nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES),
         LintId::of(ptr::CMP_NULL),
         LintId::of(ptr::PTR_ARG),
         LintId::of(ptr_eq::PTR_EQ),
@@ -1560,7 +1572,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     ]);
 
     store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec![
-        LintId::of(assign_ops::MISREFACTORED_ASSIGN_OP),
         LintId::of(attrs::DEPRECATED_CFG_ATTR),
         LintId::of(booleans::NONMINIMAL_BOOL),
         LintId::of(casts::CHAR_LIT_AS_U8),
@@ -1570,7 +1581,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(double_parens::DOUBLE_PARENS),
         LintId::of(duration_subsec::DURATION_SUBSEC),
         LintId::of(eval_order_dependence::DIVERGING_SUB_EXPRESSION),
-        LintId::of(eval_order_dependence::EVAL_ORDER_DEPENDENCE),
         LintId::of(explicit_write::EXPLICIT_WRITE),
         LintId::of(format::USELESS_FORMAT),
         LintId::of(functions::TOO_MANY_ARGUMENTS),
@@ -1581,12 +1591,10 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(lifetimes::NEEDLESS_LIFETIMES),
         LintId::of(loops::EXPLICIT_COUNTER_LOOP),
         LintId::of(loops::MANUAL_FLATTEN),
-        LintId::of(loops::MUT_RANGE_BOUND),
         LintId::of(loops::SINGLE_ELEMENT_LOOP),
         LintId::of(loops::WHILE_LET_LOOP),
         LintId::of(manual_strip::MANUAL_STRIP),
         LintId::of(manual_unwrap_or::MANUAL_UNWRAP_OR),
-        LintId::of(map_identity::MAP_IDENTITY),
         LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
         LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
         LintId::of(matches::MATCH_AS_REF),
@@ -1601,11 +1609,11 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(methods::ITER_COUNT),
         LintId::of(methods::MANUAL_FILTER_MAP),
         LintId::of(methods::MANUAL_FIND_MAP),
+        LintId::of(methods::MAP_IDENTITY),
         LintId::of(methods::OPTION_AS_REF_DEREF),
         LintId::of(methods::OPTION_FILTER_MAP),
         LintId::of(methods::SEARCH_IS_SOME),
         LintId::of(methods::SKIP_WHILE_NEXT),
-        LintId::of(methods::SUSPICIOUS_MAP),
         LintId::of(methods::UNNECESSARY_FILTER_MAP),
         LintId::of(methods::USELESS_ASREF),
         LintId::of(misc::SHORT_CIRCUIT_STATEMENT),
@@ -1674,7 +1682,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
         LintId::of(eq_op::EQ_OP),
         LintId::of(erasing_op::ERASING_OP),
-        LintId::of(float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS),
         LintId::of(formatting::POSSIBLE_MISSING_COMMA),
         LintId::of(functions::NOT_UNSAFE_PTR_ARG_DEREF),
         LintId::of(if_let_mutex::IF_LET_MUTEX),
@@ -1684,7 +1691,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(inline_fn_without_body::INLINE_FN_WITHOUT_BODY),
         LintId::of(let_underscore::LET_UNDERSCORE_LOCK),
         LintId::of(literal_representation::MISTYPED_LITERAL_SUFFIXES),
-        LintId::of(loops::FOR_LOOPS_OVER_FALLIBLES),
         LintId::of(loops::ITER_NEXT_LOOP),
         LintId::of(loops::NEVER_LOOP),
         LintId::of(loops::WHILE_IMMUTABLE_CONDITION),
@@ -1699,7 +1705,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(misc::CMP_NAN),
         LintId::of(misc::FLOAT_CMP),
         LintId::of(misc::MODULO_ONE),
-        LintId::of(mut_key::MUTABLE_KEY_TYPE),
         LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
         LintId::of(open_options::NONSENSICAL_OPEN_OPTIONS),
         LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
@@ -1710,8 +1715,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(self_assignment::SELF_ASSIGNMENT),
         LintId::of(serde_api::SERDE_API_MISUSE),
         LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
-        LintId::of(suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
-        LintId::of(suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
         LintId::of(swap::ALMOST_SWAPPED),
         LintId::of(to_string_in_display::TO_STRING_IN_DISPLAY),
         LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
@@ -1728,6 +1731,23 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(vec_resize_to_zero::VEC_RESIZE_TO_ZERO),
     ]);
 
+    store.register_group(true, "clippy::suspicious", None, vec![
+        LintId::of(assign_ops::MISREFACTORED_ASSIGN_OP),
+        LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
+        LintId::of(eval_order_dependence::EVAL_ORDER_DEPENDENCE),
+        LintId::of(float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS),
+        LintId::of(formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
+        LintId::of(formatting::SUSPICIOUS_ELSE_FORMATTING),
+        LintId::of(formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
+        LintId::of(loops::EMPTY_LOOP),
+        LintId::of(loops::FOR_LOOPS_OVER_FALLIBLES),
+        LintId::of(loops::MUT_RANGE_BOUND),
+        LintId::of(methods::SUSPICIOUS_MAP),
+        LintId::of(mut_key::MUTABLE_KEY_TYPE),
+        LintId::of(suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
+        LintId::of(suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
+    ]);
+
     store.register_group(true, "clippy::perf", Some("clippy_perf"), vec![
         LintId::of(entry::MAP_ENTRY),
         LintId::of(escape::BOXED_LOCAL),
@@ -1735,6 +1755,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(large_enum_variant::LARGE_ENUM_VARIANT),
         LintId::of(loops::MANUAL_MEMCPY),
         LintId::of(loops::NEEDLESS_COLLECT),
+        LintId::of(methods::APPEND_INSTEAD_OF_EXTEND),
         LintId::of(methods::EXPECT_FUN_CALL),
         LintId::of(methods::ITER_NTH),
         LintId::of(methods::MANUAL_STR_REPEAT),
@@ -1761,6 +1782,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(attrs::EMPTY_LINE_AFTER_OUTER_ATTR),
         LintId::of(cognitive_complexity::COGNITIVE_COMPLEXITY),
         LintId::of(disallowed_method::DISALLOWED_METHOD),
+        LintId::of(disallowed_type::DISALLOWED_TYPE),
         LintId::of(fallible_impl_from::FALLIBLE_IMPL_FROM),
         LintId::of(floating_point_arithmetic::IMPRECISE_FLOPS),
         LintId::of(floating_point_arithmetic::SUBOPTIMAL_FLOPS),
@@ -2038,8 +2060,9 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_early_pass(move || box non_expressive_names::NonExpressiveNames {
         single_char_binding_names_threshold,
     });
+    let macro_matcher = conf.standard_macro_braces.iter().cloned().collect::<FxHashSet<_>>();
+    store.register_early_pass(move || box nonstandard_macro_braces::MacroBraces::new(&macro_matcher));
     store.register_late_pass(|| box macro_use::MacroUseImports::default());
-    store.register_late_pass(|| box map_identity::MapIdentity);
     store.register_late_pass(|| box pattern_type_mismatch::PatternTypeMismatch);
     store.register_late_pass(|| box stable_sort_primitive::StableSortPrimitive);
     store.register_late_pass(|| box repeat_once::RepeatOnce);
@@ -2066,7 +2089,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(move || box if_then_some_else_none::IfThenSomeElseNone::new(msrv));
     store.register_early_pass(|| box bool_assert_comparison::BoolAssertComparison);
     store.register_late_pass(|| box unused_async::UnusedAsync);
-
+    let disallowed_types = conf.disallowed_types.iter().cloned().collect::<FxHashSet<_>>();
+    store.register_late_pass(move || box disallowed_type::DisallowedType::new(&disallowed_types));
+    let import_renames = conf.enforced_import_renames.clone();
+    store.register_late_pass(move || box missing_enforced_import_rename::ImportRename::new(import_renames.clone()));
+    let scripts = conf.allowed_scripts.clone();
+    store.register_early_pass(move || box disallowed_script_idents::DisallowedScriptIdents::new(&scripts));
 }
 
 #[rustfmt::skip]
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
index c91fe88757e..a98e2dc1372 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
@@ -118,7 +118,7 @@ fn build_manual_memcpy_suggestion<'tcx>(
     let print_limit = |end: &Expr<'_>, end_str: &str, base: &Expr<'_>, sugg: MinifyingSugg<'static>| {
         if_chain! {
             if let ExprKind::MethodCall(method, _, len_args, _) = end.kind;
-            if method.ident.name == sym!(len);
+            if method.ident.name == sym::len;
             if len_args.len() == 1;
             if let Some(arg) = len_args.get(0);
             if path_to_local(arg) == path_to_local(base);
diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs
index a4bc3e6bd10..56a123b69c6 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs
@@ -199,7 +199,7 @@ declare_clippy_lint! {
     /// }
     /// ```
     pub FOR_LOOPS_OVER_FALLIBLES,
-    correctness,
+    suspicious,
     "for-looping over an `Option` or a `Result`, which is more clearly expressed as an `if let`"
 }
 
@@ -313,7 +313,7 @@ declare_clippy_lint! {
     /// loop {}
     /// ```
     pub EMPTY_LOOP,
-    style,
+    suspicious,
     "empty `loop {}`, which should block or sleep"
 }
 
@@ -401,7 +401,7 @@ declare_clippy_lint! {
     /// }
     /// ```
     pub MUT_RANGE_BOUND,
-    complexity,
+    suspicious,
     "for loop over a range where one of the bounds is a mutable variable"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_collect.rs b/src/tools/clippy/clippy_lints/src/loops/needless_collect.rs
index eb82c9c27c3..51d7def137e 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_collect.rs
@@ -7,10 +7,10 @@ use clippy_utils::{is_trait_method, path_to_local_id};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_block, walk_expr, NestedVisitorMap, Visitor};
-use rustc_hir::{Block, Expr, ExprKind, GenericArg, GenericArgs, HirId, Local, Pat, PatKind, QPath, StmtKind, Ty};
+use rustc_hir::{Block, Expr, ExprKind, HirId, PatKind, StmtKind};
 use rustc_lint::LateContext;
 use rustc_middle::hir::map::Map;
-use rustc_span::symbol::{sym, Ident};
+use rustc_span::sym;
 use rustc_span::{MultiSpan, Span};
 
 const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed";
@@ -24,10 +24,8 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont
         if let ExprKind::MethodCall(method, _, args, _) = expr.kind;
         if let ExprKind::MethodCall(chain_method, method0_span, _, _) = args[0].kind;
         if chain_method.ident.name == sym!(collect) && is_trait_method(cx, &args[0], sym::Iterator);
-        if let Some(generic_args) = chain_method.args;
-        if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0);
-        if let Some(ty) = cx.typeck_results().node_type_opt(ty.hir_id);
         then {
+            let ty = cx.typeck_results().expr_ty(&args[0]);
             let mut applicability = Applicability::MachineApplicable;
             let is_empty_sugg = "next().is_none()".to_string();
             let method_name = &*method.ident.name.as_str();
@@ -72,40 +70,25 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont
 }
 
 fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) {
-    fn get_hir_id<'tcx>(ty: Option<&Ty<'tcx>>, method_args: Option<&GenericArgs<'tcx>>) -> Option<HirId> {
-        if let Some(ty) = ty {
-            return Some(ty.hir_id);
-        }
-
-        if let Some(generic_args) = method_args {
-            if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0) {
-                return Some(ty.hir_id);
-            }
-        }
-
-        None
-    }
     if let ExprKind::Block(block, _) = expr.kind {
         for stmt in block.stmts {
             if_chain! {
-                if let StmtKind::Local(
-                    Local { pat: Pat { hir_id: pat_id, kind: PatKind::Binding(_, _, ident, .. ), .. },
-                    init: Some(init_expr), ty, .. }
-                ) = stmt.kind;
+                if let StmtKind::Local(local) = stmt.kind;
+                if let PatKind::Binding(_, id, ..) = local.pat.kind;
+                if let Some(init_expr) = local.init;
                 if let ExprKind::MethodCall(method_name, collect_span, &[ref iter_source], ..) = init_expr.kind;
                 if method_name.ident.name == sym!(collect) && is_trait_method(cx, init_expr, sym::Iterator);
-                if let Some(hir_id) = get_hir_id(*ty, method_name.args);
-                if let Some(ty) = cx.typeck_results().node_type_opt(hir_id);
+                let ty = cx.typeck_results().expr_ty(init_expr);
                 if is_type_diagnostic_item(cx, ty, sym::vec_type) ||
                     is_type_diagnostic_item(cx, ty, sym::vecdeque_type) ||
                     is_type_diagnostic_item(cx, ty, sym::BinaryHeap) ||
                     is_type_diagnostic_item(cx, ty, sym::LinkedList);
-                if let Some(iter_calls) = detect_iter_and_into_iters(block, *ident);
+                if let Some(iter_calls) = detect_iter_and_into_iters(block, id);
                 if let [iter_call] = &*iter_calls;
                 then {
                     let mut used_count_visitor = UsedCountVisitor {
                         cx,
-                        id: *pat_id,
+                        id,
                         count: 0,
                     };
                     walk_block(&mut used_count_visitor, block);
@@ -187,48 +170,40 @@ enum IterFunctionKind {
 struct IterFunctionVisitor {
     uses: Vec<IterFunction>,
     seen_other: bool,
-    target: Ident,
+    target: HirId,
 }
 impl<'tcx> Visitor<'tcx> for IterFunctionVisitor {
     fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
         // Check function calls on our collection
-        if_chain! {
-            if let ExprKind::MethodCall(method_name, _, args, _) = &expr.kind;
-            if let Some(Expr { kind: ExprKind::Path(QPath::Resolved(_, path)), .. }) = args.get(0);
-            if let &[name] = &path.segments;
-            if name.ident == self.target;
-            then {
-                let len = sym!(len);
-                let is_empty = sym!(is_empty);
-                let contains = sym!(contains);
-                match method_name.ident.name {
-                    sym::into_iter => self.uses.push(
-                        IterFunction { func: IterFunctionKind::IntoIter, span: expr.span }
-                    ),
-                    name if name == len => self.uses.push(
-                        IterFunction { func: IterFunctionKind::Len, span: expr.span }
-                    ),
-                    name if name == is_empty => self.uses.push(
-                        IterFunction { func: IterFunctionKind::IsEmpty, span: expr.span }
-                    ),
-                    name if name == contains => self.uses.push(
-                        IterFunction { func: IterFunctionKind::Contains(args[1].span), span: expr.span }
-                    ),
+        if let ExprKind::MethodCall(method_name, _, [recv, args @ ..], _) = &expr.kind {
+            if path_to_local_id(recv, self.target) {
+                match &*method_name.ident.name.as_str() {
+                    "into_iter" => self.uses.push(IterFunction {
+                        func: IterFunctionKind::IntoIter,
+                        span: expr.span,
+                    }),
+                    "len" => self.uses.push(IterFunction {
+                        func: IterFunctionKind::Len,
+                        span: expr.span,
+                    }),
+                    "is_empty" => self.uses.push(IterFunction {
+                        func: IterFunctionKind::IsEmpty,
+                        span: expr.span,
+                    }),
+                    "contains" => self.uses.push(IterFunction {
+                        func: IterFunctionKind::Contains(args[0].span),
+                        span: expr.span,
+                    }),
                     _ => self.seen_other = true,
                 }
-                return
+                return;
             }
         }
         // Check if the collection is used for anything else
-        if_chain! {
-            if let Expr { kind: ExprKind::Path(QPath::Resolved(_, path)), .. } = expr;
-            if let &[name] = &path.segments;
-            if name.ident == self.target;
-            then {
-                self.seen_other = true;
-            } else {
-                walk_expr(self, expr);
-            }
+        if path_to_local_id(expr, self.target) {
+            self.seen_other = true;
+        } else {
+            walk_expr(self, expr);
         }
     }
 
@@ -262,10 +237,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UsedCountVisitor<'a, 'tcx> {
 
 /// Detect the occurrences of calls to `iter` or `into_iter` for the
 /// given identifier
-fn detect_iter_and_into_iters<'tcx>(block: &'tcx Block<'tcx>, identifier: Ident) -> Option<Vec<IterFunction>> {
+fn detect_iter_and_into_iters<'tcx>(block: &'tcx Block<'tcx>, id: HirId) -> Option<Vec<IterFunction>> {
     let mut visitor = IterFunctionVisitor {
         uses: Vec::new(),
-        target: identifier,
+        target: id,
         seen_other: false,
     };
     visitor.visit_block(block);
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index 3065bcc3e6c..3810d0dcc05 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -192,7 +192,7 @@ fn is_len_call(expr: &Expr<'_>, var: Symbol) -> bool {
     if_chain! {
         if let ExprKind::MethodCall(method, _, len_args, _) = expr.kind;
         if len_args.len() == 1;
-        if method.ident.name == sym!(len);
+        if method.ident.name == sym::len;
         if let ExprKind::Path(QPath::Resolved(_, path)) = len_args[0].kind;
         if path.segments.len() == 1;
         if path.segments[0].ident.name == var;
diff --git a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
index 63560047578..d57588716a5 100644
--- a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
@@ -1,7 +1,9 @@
 use super::WHILE_LET_ON_ITERATOR;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{get_enclosing_loop, is_refutable, is_trait_method, match_def_path, paths, visitors::is_res_used};
+use clippy_utils::{
+    get_enclosing_loop_or_closure, is_refutable, is_trait_method, match_def_path, paths, visitors::is_res_used,
+};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_expr, ErasedMap, NestedVisitorMap, Visitor};
@@ -315,9 +317,10 @@ fn needs_mutable_borrow(cx: &LateContext<'tcx>, iter_expr: &IterExpr, loop_expr:
         }
     }
 
-    if let Some(e) = get_enclosing_loop(cx.tcx, loop_expr) {
-        // The iterator expression will be used on the next iteration unless it is declared within the outer
-        // loop.
+    if let Some(e) = get_enclosing_loop_or_closure(cx.tcx, loop_expr) {
+        // The iterator expression will be used on the next iteration (for loops), or on the next call (for
+        // closures) unless it is declared within the enclosing expression. TODO: Check for closures
+        // used where an `FnOnce` type is expected.
         let local_id = match iter_expr.path {
             Res::Local(id) => id,
             _ => return true,
diff --git a/src/tools/clippy/clippy_lints/src/manual_map.rs b/src/tools/clippy/clippy_lints/src/manual_map.rs
index 0b873534f2c..97e4a983f32 100644
--- a/src/tools/clippy/clippy_lints/src/manual_map.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_map.rs
@@ -3,19 +3,17 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
 use clippy_utils::ty::{is_type_diagnostic_item, peel_mid_ty_refs_is_mutable};
 use clippy_utils::{
-    can_move_expr_to_closure, in_constant, is_allowed, is_else_clause, is_lang_ctor, match_var, peel_hir_expr_refs,
+    can_move_expr_to_closure, in_constant, is_allowed, is_else_clause, is_lang_ctor, path_to_local_id,
+    peel_hir_expr_refs,
 };
 use rustc_ast::util::parser::PREC_POSTFIX;
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
-use rustc_hir::{Arm, BindingAnnotation, Block, Expr, ExprKind, MatchSource, Mutability, Pat, PatKind};
+use rustc_hir::{Arm, BindingAnnotation, Block, Expr, ExprKind, HirId, MatchSource, Mutability, Pat, PatKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::{
-    symbol::{sym, Ident},
-    SyntaxContext,
-};
+use rustc_span::{sym, SyntaxContext};
 
 declare_clippy_lint! {
     /// **What it does:** Checks for usages of `match` which could be implemented using `map`
@@ -141,13 +139,13 @@ impl LateLintPass<'_> for ManualMap {
                     scrutinee_str.into()
                 };
 
-            let body_str = if let PatKind::Binding(annotation, _, some_binding, None) = some_pat.kind {
-                match can_pass_as_func(cx, some_binding, some_expr) {
+            let body_str = if let PatKind::Binding(annotation, id, some_binding, None) = some_pat.kind {
+                match can_pass_as_func(cx, id, some_expr) {
                     Some(func) if func.span.ctxt() == some_expr.span.ctxt() => {
                         snippet_with_applicability(cx, func.span, "..", &mut app).into_owned()
                     },
                     _ => {
-                        if match_var(some_expr, some_binding.name)
+                        if path_to_local_id(some_expr, id)
                             && !is_allowed(cx, MATCH_AS_REF, expr.hir_id)
                             && binding_ref.is_some()
                         {
@@ -199,10 +197,10 @@ impl LateLintPass<'_> for ManualMap {
 
 // Checks whether the expression could be passed as a function, or whether a closure is needed.
 // Returns the function to be passed to `map` if it exists.
-fn can_pass_as_func(cx: &LateContext<'tcx>, binding: Ident, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
+fn can_pass_as_func(cx: &LateContext<'tcx>, binding: HirId, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
     match expr.kind {
         ExprKind::Call(func, [arg])
-            if match_var(arg, binding.name) && cx.typeck_results().expr_adjustments(arg).is_empty() =>
+            if path_to_local_id(arg, binding) && cx.typeck_results().expr_adjustments(arg).is_empty() =>
         {
             Some(func)
         },
diff --git a/src/tools/clippy/clippy_lints/src/map_identity.rs b/src/tools/clippy/clippy_lints/src/map_identity.rs
deleted file mode 100644
index 41cda23510e..00000000000
--- a/src/tools/clippy/clippy_lints/src/map_identity.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{is_adjusted, is_qpath_def_path, is_trait_method, match_var, paths, remove_blocks};
-use if_chain::if_chain;
-use rustc_errors::Applicability;
-use rustc_hir::{Body, Expr, ExprKind, Pat, PatKind, QPath, StmtKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
-
-declare_clippy_lint! {
-    /// **What it does:** Checks for instances of `map(f)` where `f` is the identity function.
-    ///
-    /// **Why is this bad?** It can be written more concisely without the call to `map`.
-    ///
-    /// **Known problems:** None.
-    ///
-    /// **Example:**
-    ///
-    /// ```rust
-    /// let x = [1, 2, 3];
-    /// let y: Vec<_> = x.iter().map(|x| x).map(|x| 2*x).collect();
-    /// ```
-    /// Use instead:
-    /// ```rust
-    /// let x = [1, 2, 3];
-    /// let y: Vec<_> = x.iter().map(|x| 2*x).collect();
-    /// ```
-    pub MAP_IDENTITY,
-    complexity,
-    "using iterator.map(|x| x)"
-}
-
-declare_lint_pass!(MapIdentity => [MAP_IDENTITY]);
-
-impl<'tcx> LateLintPass<'tcx> for MapIdentity {
-    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
-        if expr.span.from_expansion() {
-            return;
-        }
-
-        if_chain! {
-            if let Some([caller, func]) = get_map_argument(cx, expr);
-            if is_expr_identity_function(cx, func);
-            then {
-                span_lint_and_sugg(
-                    cx,
-                    MAP_IDENTITY,
-                    expr.span.trim_start(caller.span).unwrap(),
-                    "unnecessary map of the identity function",
-                    "remove the call to `map`",
-                    String::new(),
-                    Applicability::MachineApplicable
-                )
-            }
-        }
-    }
-}
-
-/// Returns the arguments passed into map() if the expression is a method call to
-/// map(). Otherwise, returns None.
-fn get_map_argument<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<&'a [Expr<'a>]> {
-    if_chain! {
-        if let ExprKind::MethodCall(method, _, args, _) = expr.kind;
-        if args.len() == 2 && method.ident.name == sym::map;
-        let caller_ty = cx.typeck_results().expr_ty(&args[0]);
-        if is_trait_method(cx, expr, sym::Iterator)
-            || is_type_diagnostic_item(cx, caller_ty, sym::result_type)
-            || is_type_diagnostic_item(cx, caller_ty, sym::option_type);
-        then {
-            Some(args)
-        } else {
-            None
-        }
-    }
-}
-
-/// Checks if an expression represents the identity function
-/// Only examines closures and `std::convert::identity`
-fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-    match expr.kind {
-        ExprKind::Closure(_, _, body_id, _, _) => is_body_identity_function(cx, cx.tcx.hir().body(body_id)),
-        ExprKind::Path(ref path) => is_qpath_def_path(cx, path, expr.hir_id, &paths::CONVERT_IDENTITY),
-        _ => false,
-    }
-}
-
-/// Checks if a function's body represents the identity function
-/// Looks for bodies of the form `|x| x`, `|x| return x`, `|x| { return x }` or `|x| {
-/// return x; }`
-fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
-    let params = func.params;
-    let body = remove_blocks(&func.value);
-
-    // if there's less/more than one parameter, then it is not the identity function
-    if params.len() != 1 {
-        return false;
-    }
-
-    match body.kind {
-        ExprKind::Path(QPath::Resolved(None, _)) => match_expr_param(cx, body, params[0].pat),
-        ExprKind::Ret(Some(ret_val)) => match_expr_param(cx, ret_val, params[0].pat),
-        ExprKind::Block(block, _) => {
-            if_chain! {
-                if block.stmts.len() == 1;
-                if let StmtKind::Semi(expr) | StmtKind::Expr(expr) = block.stmts[0].kind;
-                if let ExprKind::Ret(Some(ret_val)) = expr.kind;
-                then {
-                    match_expr_param(cx, ret_val, params[0].pat)
-                } else {
-                    false
-                }
-            }
-        },
-        _ => false,
-    }
-}
-
-/// Returns true iff an expression returns the same thing as a parameter's pattern
-fn match_expr_param(cx: &LateContext<'_>, expr: &Expr<'_>, pat: &Pat<'_>) -> bool {
-    if let PatKind::Binding(_, _, ident, _) = pat.kind {
-        match_var(expr, ident.name) && !(cx.typeck_results().hir_owner == expr.hir_id.owner && is_adjusted(cx, expr))
-    } else {
-        false
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/matches.rs b/src/tools/clippy/clippy_lints/src/matches.rs
index cd3e3b97928..f1e3492c4ec 100644
--- a/src/tools/clippy/clippy_lints/src/matches.rs
+++ b/src/tools/clippy/clippy_lints/src/matches.rs
@@ -992,9 +992,9 @@ impl CommonPrefixSearcher<'a> {
     }
 }
 
-fn is_doc_hidden(cx: &LateContext<'_>, variant_def: &VariantDef) -> bool {
+fn is_hidden(cx: &LateContext<'_>, variant_def: &VariantDef) -> bool {
     let attrs = cx.tcx.get_attrs(variant_def.def_id);
-    clippy_utils::attrs::is_doc_hidden(attrs)
+    clippy_utils::attrs::is_doc_hidden(attrs) || clippy_utils::attrs::is_unstable(attrs)
 }
 
 #[allow(clippy::too_many_lines)]
@@ -1033,7 +1033,8 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
 
     // Accumulate the variants which should be put in place of the wildcard because they're not
     // already covered.
-    let mut missing_variants: Vec<_> = adt_def.variants.iter().collect();
+    let has_hidden = adt_def.variants.iter().any(|x| is_hidden(cx, x));
+    let mut missing_variants: Vec<_> = adt_def.variants.iter().filter(|x| !is_hidden(cx, x)).collect();
 
     let mut path_prefix = CommonPrefixSearcher::None;
     for arm in arms {
@@ -1118,7 +1119,7 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
 
     match missing_variants.as_slice() {
         [] => (),
-        [x] if !adt_def.is_variant_list_non_exhaustive() && !is_doc_hidden(cx, x) => span_lint_and_sugg(
+        [x] if !adt_def.is_variant_list_non_exhaustive() && !has_hidden => span_lint_and_sugg(
             cx,
             MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
             wildcard_span,
@@ -1129,7 +1130,7 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
         ),
         variants => {
             let mut suggestions: Vec<_> = variants.iter().copied().map(format_suggestion).collect();
-            let message = if adt_def.is_variant_list_non_exhaustive() {
+            let message = if adt_def.is_variant_list_non_exhaustive() || has_hidden {
                 suggestions.push("_".into());
                 "wildcard matches known variants and will also match future added variants"
             } else {
@@ -2266,7 +2267,8 @@ fn lint_match_arms<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) {
                             ),
                         );
                     } else {
-                        diag.span_help(i.pat.span, &format!("consider refactoring into `{} | {}`", lhs, rhs));
+                        diag.span_help(i.pat.span, &format!("consider refactoring into `{} | {}`", lhs, rhs,))
+                            .help("...or consider changing the match arm bodies");
                     }
                 },
             );
diff --git a/src/tools/clippy/clippy_lints/src/methods/append_instead_of_extend.rs b/src/tools/clippy/clippy_lints/src/methods/append_instead_of_extend.rs
new file mode 100644
index 00000000000..e39a5a1efd1
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/append_instead_of_extend.rs
@@ -0,0 +1,41 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
+use if_chain::if_chain;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind, LangItem};
+use rustc_lint::LateContext;
+use rustc_span::symbol::sym;
+
+use super::APPEND_INSTEAD_OF_EXTEND;
+
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) {
+    let ty = cx.typeck_results().expr_ty(recv).peel_refs();
+    if_chain! {
+        if is_type_diagnostic_item(cx, ty, sym::vec_type);
+        //check source object
+        if let ExprKind::MethodCall(src_method, _, [drain_vec, drain_arg], _) = &arg.kind;
+        if src_method.ident.as_str() == "drain";
+        if let src_ty = cx.typeck_results().expr_ty(drain_vec).peel_refs();
+        if is_type_diagnostic_item(cx, src_ty, sym::vec_type);
+        //check drain range
+        if let src_ty_range = cx.typeck_results().expr_ty(drain_arg).peel_refs();
+        if is_type_lang_item(cx, src_ty_range, LangItem::RangeFull);
+        then {
+            let mut applicability = Applicability::MachineApplicable;
+            span_lint_and_sugg(
+                cx,
+                APPEND_INSTEAD_OF_EXTEND,
+                expr.span,
+                "use of `extend` instead of `append` for adding the full range of a second vector",
+                "try this",
+                format!(
+                    "{}.append(&mut {})",
+                    snippet_with_applicability(cx, recv.span, "..", &mut applicability),
+                    snippet_with_applicability(cx, drain_vec.span, "..", &mut applicability)
+                ),
+                applicability,
+            );
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs
index 403fe8d3546..d1b5e945dfd 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs
@@ -1,6 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{is_expr_path_def_path, is_trait_method, path_to_local_id, paths};
-use if_chain::if_chain;
+use clippy_utils::{is_expr_identity_function, is_trait_method};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
@@ -9,32 +8,15 @@ use rustc_span::{source_map::Span, sym};
 use super::FILTER_MAP_IDENTITY;
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_map_arg: &hir::Expr<'_>, filter_map_span: Span) {
-    if is_trait_method(cx, expr, sym::Iterator) {
-        let apply_lint = |message: &str| {
-            span_lint_and_sugg(
-                cx,
-                FILTER_MAP_IDENTITY,
-                filter_map_span.with_hi(expr.span.hi()),
-                message,
-                "try",
-                "flatten()".to_string(),
-                Applicability::MachineApplicable,
-            );
-        };
-
-        if_chain! {
-            if let hir::ExprKind::Closure(_, _, body_id, _, _) = filter_map_arg.kind;
-            let body = cx.tcx.hir().body(body_id);
-
-            if let hir::PatKind::Binding(_, binding_id, ..) = body.params[0].pat.kind;
-            if path_to_local_id(&body.value, binding_id);
-            then {
-                apply_lint("called `filter_map(|x| x)` on an `Iterator`");
-            }
-        }
-
-        if is_expr_path_def_path(cx, filter_map_arg, &paths::CONVERT_IDENTITY) {
-            apply_lint("called `filter_map(std::convert::identity)` on an `Iterator`");
-        }
+    if is_trait_method(cx, expr, sym::Iterator) && is_expr_identity_function(cx, filter_map_arg) {
+        span_lint_and_sugg(
+            cx,
+            FILTER_MAP_IDENTITY,
+            filter_map_span.with_hi(expr.span.hi()),
+            "use of `filter_map` with an identity function",
+            "try",
+            "flatten()".to_string(),
+            Applicability::MachineApplicable,
+        );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/flat_map_identity.rs b/src/tools/clippy/clippy_lints/src/methods/flat_map_identity.rs
index 25f8434cb94..6f911d79d0b 100644
--- a/src/tools/clippy/clippy_lints/src/methods/flat_map_identity.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/flat_map_identity.rs
@@ -1,6 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{is_expr_path_def_path, is_trait_method, paths};
-use if_chain::if_chain;
+use clippy_utils::{is_expr_identity_function, is_trait_method};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
@@ -15,36 +14,15 @@ pub(super) fn check<'tcx>(
     flat_map_arg: &'tcx hir::Expr<'_>,
     flat_map_span: Span,
 ) {
-    if is_trait_method(cx, expr, sym::Iterator) {
-        let apply_lint = |message: &str| {
-            span_lint_and_sugg(
-                cx,
-                FLAT_MAP_IDENTITY,
-                flat_map_span.with_hi(expr.span.hi()),
-                message,
-                "try",
-                "flatten()".to_string(),
-                Applicability::MachineApplicable,
-            );
-        };
-
-        if_chain! {
-            if let hir::ExprKind::Closure(_, _, body_id, _, _) = flat_map_arg.kind;
-            let body = cx.tcx.hir().body(body_id);
-
-            if let hir::PatKind::Binding(_, _, binding_ident, _) = body.params[0].pat.kind;
-            if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = body.value.kind;
-
-            if path.segments.len() == 1;
-            if path.segments[0].ident.name == binding_ident.name;
-
-            then {
-                apply_lint("called `flat_map(|x| x)` on an `Iterator`");
-            }
-        }
-
-        if is_expr_path_def_path(cx, flat_map_arg, &paths::CONVERT_IDENTITY) {
-            apply_lint("called `flat_map(std::convert::identity)` on an `Iterator`");
-        }
+    if is_trait_method(cx, expr, sym::Iterator) && is_expr_identity_function(cx, flat_map_arg) {
+        span_lint_and_sugg(
+            cx,
+            FLAT_MAP_IDENTITY,
+            flat_map_span.with_hi(expr.span.hi()),
+            "use of `flat_map` with an identity function",
+            "try",
+            "flatten()".to_string(),
+            Applicability::MachineApplicable,
+        );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_identity.rs b/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
new file mode 100644
index 00000000000..538a12566e3
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
@@ -0,0 +1,38 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::{is_expr_identity_function, is_trait_method};
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_lint::LateContext;
+use rustc_span::{source_map::Span, sym};
+
+use super::MAP_IDENTITY;
+
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    expr: &hir::Expr<'_>,
+    caller: &hir::Expr<'_>,
+    map_arg: &hir::Expr<'_>,
+    _map_span: Span,
+) {
+    let caller_ty = cx.typeck_results().expr_ty(caller);
+
+    if_chain! {
+        if is_trait_method(cx, expr, sym::Iterator)
+            || is_type_diagnostic_item(cx, caller_ty, sym::result_type)
+            || is_type_diagnostic_item(cx, caller_ty, sym::option_type);
+        if is_expr_identity_function(cx, map_arg);
+        if let Some(sugg_span) = expr.span.trim_start(caller.span);
+        then {
+            span_lint_and_sugg(
+                cx,
+                MAP_IDENTITY,
+                sugg_span,
+                "unnecessary map of the identity function",
+                "remove the call to `map`",
+                String::new(),
+                Applicability::MachineApplicable,
+            )
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index c8ae972f18c..283fcf281df 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -1,3 +1,4 @@
+mod append_instead_of_extend;
 mod bind_instead_of_map;
 mod bytes_nth;
 mod chars_cmp;
@@ -35,6 +36,7 @@ mod manual_saturating_arithmetic;
 mod manual_str_repeat;
 mod map_collect_result_unit;
 mod map_flatten;
+mod map_identity;
 mod map_unwrap_or;
 mod ok_expect;
 mod option_as_ref_deref;
@@ -1032,6 +1034,30 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
+    /// **What it does:** Checks for occurrences where one vector gets extended instead of append
+    ///
+    /// **Why is this bad?** Using `append` instead of `extend` is more concise and faster
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust
+    /// let mut a = vec![1, 2, 3];
+    /// let mut b = vec![4, 5, 6];
+    ///
+    /// // Bad
+    /// a.extend(b.drain(..));
+    ///
+    /// // Good
+    /// a.append(&mut b);
+    /// ```
+    pub APPEND_INSTEAD_OF_EXTEND,
+    perf,
+    "using vec.append(&mut vec) to move the full range of a vecor to another"
+}
+
+declare_clippy_lint! {
     /// **What it does:** Checks for the use of `.extend(s.chars())` where s is a
     /// `&str` or `String`.
     ///
@@ -1222,7 +1248,7 @@ declare_clippy_lint! {
     /// let _ = (0..3).map(|x| x + 2).count();
     /// ```
     pub SUSPICIOUS_MAP,
-    complexity,
+    suspicious,
     "suspicious usage of map"
 }
 
@@ -1504,7 +1530,7 @@ declare_clippy_lint! {
     /// assert_eq!(v, vec![5, 5, 5, 5, 5]);
     /// ```
     pub FROM_ITER_INSTEAD_OF_COLLECT,
-    style,
+    pedantic,
     "use `.collect()` instead of `::from_iter()`"
 }
 
@@ -1562,6 +1588,29 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
+    /// **What it does:** Checks for instances of `map(f)` where `f` is the identity function.
+    ///
+    /// **Why is this bad?** It can be written more concisely without the call to `map`.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust
+    /// let x = [1, 2, 3];
+    /// let y: Vec<_> = x.iter().map(|x| x).map(|x| 2*x).collect();
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// let x = [1, 2, 3];
+    /// let y: Vec<_> = x.iter().map(|x| 2*x).collect();
+    /// ```
+    pub MAP_IDENTITY,
+    complexity,
+    "using iterator.map(|x| x)"
+}
+
+declare_clippy_lint! {
     /// **What it does:** Checks for the use of `.bytes().nth()`.
     ///
     /// **Why is this bad?** `.as_bytes().get()` is more efficient and more
@@ -1728,6 +1777,7 @@ impl_lint_pass!(Methods => [
     FILTER_NEXT,
     SKIP_WHILE_NEXT,
     FILTER_MAP_IDENTITY,
+    MAP_IDENTITY,
     MANUAL_FILTER_MAP,
     MANUAL_FIND_MAP,
     OPTION_FILTER_MAP,
@@ -1760,7 +1810,8 @@ impl_lint_pass!(Methods => [
     INSPECT_FOR_EACH,
     IMPLICIT_CLONE,
     SUSPICIOUS_SPLITN,
-    MANUAL_STR_REPEAT
+    MANUAL_STR_REPEAT,
+    APPEND_INSTEAD_OF_EXTEND
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
@@ -1985,7 +2036,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
 fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Option<&RustcVersion>) {
     if let Some((name, [recv, args @ ..], span)) = method_call!(expr) {
         match (name, args) {
-            ("add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub", [recv, _]) => {
+            ("add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub", [_arg]) => {
                 zst_offset::check(cx, expr, recv);
             },
             ("and_then", [arg]) => {
@@ -2022,7 +2073,10 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
                 Some(("ok", [recv], _)) => ok_expect::check(cx, expr, recv),
                 _ => expect_used::check(cx, expr, recv),
             },
-            ("extend", [arg]) => string_extend_chars::check(cx, expr, recv, arg),
+            ("extend", [arg]) => {
+                string_extend_chars::check(cx, expr, recv, arg);
+                append_instead_of_extend::check(cx, expr, recv, arg);
+            },
             ("filter_map", [arg]) => {
                 unnecessary_filter_map::check(cx, expr, arg);
                 filter_map_identity::check(cx, expr, arg, span);
@@ -2058,6 +2112,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
                         _ => {},
                     }
                 }
+                map_identity::check(cx, expr, recv, m_arg, span);
             },
             ("map_or", [def, map]) => option_map_or_none::check(cx, expr, recv, def, map),
             ("next", []) => {
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
index 800172f4cf3..073c5570a88 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
@@ -87,7 +87,7 @@ pub(super) fn check<'tcx>(
         ];
 
         if let hir::ExprKind::MethodCall(path, _, args, _) = &arg.kind {
-            if path.ident.as_str() == "len" {
+            if path.ident.name == sym::len {
                 let ty = cx.typeck_results().expr_ty(&args[0]).peel_refs();
 
                 match ty.kind() {
diff --git a/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs b/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs
new file mode 100644
index 00000000000..59565350f72
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs
@@ -0,0 +1,102 @@
+use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet_opt};
+
+use rustc_data_structures::fx::FxHashMap;
+use rustc_errors::Applicability;
+use rustc_hir::{def::Res, def_id::DefId, Crate, Item, ItemKind, UseKind};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::Symbol;
+
+use crate::utils::conf::Rename;
+
+declare_clippy_lint! {
+    /// **What it does:** Checks for imports that do not rename the item as specified
+    /// in the `enforce-import-renames` config option.
+    ///
+    /// **Why is this bad?** Consistency is important, if a project has defined import
+    /// renames they should be followed. More practically, some item names are too
+    /// vague outside of their defining scope this can enforce a more meaningful naming.
+    ///
+    /// **Known problems:** None
+    ///
+    /// **Example:**
+    ///
+    /// An example clippy.toml configuration:
+    /// ```toml
+    /// # clippy.toml
+    /// enforced-import-renames = [ { path = "serde_json::Value", rename = "JsonValue" }]
+    /// ```
+    ///
+    /// ```rust,ignore
+    /// use serde_json::Value;
+    /// ```
+    /// Use instead:
+    /// ```rust,ignore
+    /// use serde_json::Value as JsonValue;
+    /// ```
+    pub MISSING_ENFORCED_IMPORT_RENAMES,
+    restriction,
+    "enforce import renames"
+}
+
+pub struct ImportRename {
+    conf_renames: Vec<Rename>,
+    renames: FxHashMap<DefId, Symbol>,
+}
+
+impl ImportRename {
+    pub fn new(conf_renames: Vec<Rename>) -> Self {
+        Self {
+            conf_renames,
+            renames: FxHashMap::default(),
+        }
+    }
+}
+
+impl_lint_pass!(ImportRename => [MISSING_ENFORCED_IMPORT_RENAMES]);
+
+impl LateLintPass<'_> for ImportRename {
+    fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
+        for Rename { path, rename } in &self.conf_renames {
+            if let Res::Def(_, id) = clippy_utils::path_to_res(cx, &path.split("::").collect::<Vec<_>>()) {
+                self.renames.insert(id, Symbol::intern(rename));
+            }
+        }
+    }
+
+    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
+        if_chain! {
+            if let ItemKind::Use(path, UseKind::Single) = &item.kind;
+            if let Res::Def(_, id) = path.res;
+            if let Some(name) = self.renames.get(&id);
+            // Remove semicolon since it is not present for nested imports
+            let span_without_semi = cx.sess().source_map().span_until_char(item.span, ';');
+            if let Some(snip) = snippet_opt(cx, span_without_semi);
+            if let Some(import) = match snip.split_once(" as ") {
+                None => Some(snip.as_str()),
+                Some((import, rename)) => {
+                    if rename.trim() == &*name.as_str() {
+                        None
+                    } else {
+                        Some(import.trim())
+                    }
+                },
+            };
+            then {
+                span_lint_and_sugg(
+                    cx,
+                    MISSING_ENFORCED_IMPORT_RENAMES,
+                    span_without_semi,
+                    "this import should be renamed",
+                    "try",
+                    format!(
+                        "{} as {}",
+                        import,
+                        name,
+                    ),
+                    Applicability::MachineApplicable,
+                );
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs
index 1786d5805d7..6c87136e5e1 100644
--- a/src/tools/clippy/clippy_lints/src/mut_key.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_key.rs
@@ -50,7 +50,7 @@ declare_clippy_lint! {
     /// }
     /// ```
     pub MUTABLE_KEY_TYPE,
-    correctness,
+    suspicious,
     "Check for mutable `Map`/`Set` key type"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index b2206a82208..910b0536092 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -167,7 +167,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
                         BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) => None,
                         BlockCheckMode::DefaultBlock => Some(vec![&**e]),
                         // in case of compiler-inserted signaling blocks
-                        _ => reduce_expression(cx, e),
+                        BlockCheckMode::UnsafeBlock(_) => reduce_expression(cx, e),
                     }
                 })
             } else {
diff --git a/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs b/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
new file mode 100644
index 00000000000..1adad5be6dd
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
@@ -0,0 +1,276 @@
+use std::{
+    fmt,
+    hash::{Hash, Hasher},
+};
+
+use clippy_utils::{diagnostics::span_lint_and_help, in_macro, is_direct_expn_of, source::snippet_opt};
+use if_chain::if_chain;
+use rustc_ast::ast;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::Span;
+use serde::{de, Deserialize};
+
+declare_clippy_lint! {
+    /// **What it does:** Checks that common macros are used with consistent bracing.
+    ///
+    /// **Why is this bad?** This is mostly a consistency lint although using () or []
+    /// doesn't give you a semicolon in item position, which can be unexpected.
+    ///
+    /// **Known problems:**
+    /// None
+    ///
+    /// **Example:**
+    ///
+    /// ```rust
+    /// vec!{1, 2, 3};
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// vec![1, 2, 3];
+    /// ```
+    pub NONSTANDARD_MACRO_BRACES,
+    style,
+    "check consistent use of braces in macro"
+}
+
+const BRACES: &[(&str, &str)] = &[("(", ")"), ("{", "}"), ("[", "]")];
+
+/// The (name, (open brace, close brace), source snippet)
+type MacroInfo<'a> = (&'a str, &'a (String, String), String);
+
+#[derive(Clone, Debug, Default)]
+pub struct MacroBraces {
+    macro_braces: FxHashMap<String, (String, String)>,
+    done: FxHashSet<Span>,
+}
+
+impl MacroBraces {
+    pub fn new(conf: &FxHashSet<MacroMatcher>) -> Self {
+        let macro_braces = macro_braces(conf.clone());
+        Self {
+            macro_braces,
+            done: FxHashSet::default(),
+        }
+    }
+}
+
+impl_lint_pass!(MacroBraces => [NONSTANDARD_MACRO_BRACES]);
+
+impl EarlyLintPass for MacroBraces {
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
+        if let Some((name, braces, snip)) = is_offending_macro(cx, item.span, self) {
+            let span = item.span.ctxt().outer_expn_data().call_site;
+            emit_help(cx, snip, braces, name, span);
+            self.done.insert(span);
+        }
+    }
+
+    fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &ast::Stmt) {
+        if let Some((name, braces, snip)) = is_offending_macro(cx, stmt.span, self) {
+            let span = stmt.span.ctxt().outer_expn_data().call_site;
+            emit_help(cx, snip, braces, name, span);
+            self.done.insert(span);
+        }
+    }
+
+    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
+        if let Some((name, braces, snip)) = is_offending_macro(cx, expr.span, self) {
+            let span = expr.span.ctxt().outer_expn_data().call_site;
+            emit_help(cx, snip, braces, name, span);
+            self.done.insert(span);
+        }
+    }
+
+    fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {
+        if let Some((name, braces, snip)) = is_offending_macro(cx, ty.span, self) {
+            let span = ty.span.ctxt().outer_expn_data().call_site;
+            emit_help(cx, snip, braces, name, span);
+            self.done.insert(span);
+        }
+    }
+}
+
+fn is_offending_macro<'a>(cx: &EarlyContext<'_>, span: Span, this: &'a MacroBraces) -> Option<MacroInfo<'a>> {
+    if_chain! {
+        if in_macro(span);
+        if let Some((name, braces)) = find_matching_macro(span, &this.macro_braces);
+        if let Some(snip) = snippet_opt(cx, span.ctxt().outer_expn_data().call_site);
+        let c = snip.replace(" ", ""); // make formatting consistent
+        if !c.starts_with(&format!("{}!{}", name, braces.0));
+        if !this.done.contains(&span.ctxt().outer_expn_data().call_site);
+        then {
+            Some((name, braces, snip))
+        } else {
+            None
+        }
+    }
+}
+
+fn emit_help(cx: &EarlyContext<'_>, snip: String, braces: &(String, String), name: &str, span: Span) {
+    let with_space = &format!("! {}", braces.0);
+    let without_space = &format!("!{}", braces.0);
+    let mut help = snip;
+    for b in BRACES.iter().filter(|b| b.0 != braces.0) {
+        help = help.replace(b.0, &braces.0).replace(b.1, &braces.1);
+        // Only `{` traditionally has space before the brace
+        if braces.0 != "{" && help.contains(with_space) {
+            help = help.replace(with_space, without_space);
+        } else if braces.0 == "{" && help.contains(without_space) {
+            help = help.replace(without_space, with_space);
+        }
+    }
+    span_lint_and_help(
+        cx,
+        NONSTANDARD_MACRO_BRACES,
+        span,
+        &format!("use of irregular braces for `{}!` macro", name),
+        Some(span),
+        &format!("consider writing `{}`", help),
+    );
+}
+
+fn find_matching_macro(
+    span: Span,
+    braces: &FxHashMap<String, (String, String)>,
+) -> Option<(&String, &(String, String))> {
+    braces
+        .iter()
+        .find(|(macro_name, _)| is_direct_expn_of(span, macro_name).is_some())
+}
+
+fn macro_braces(conf: FxHashSet<MacroMatcher>) -> FxHashMap<String, (String, String)> {
+    let mut braces = vec![
+        macro_matcher!(
+            name: "print",
+            braces: ("(", ")"),
+        ),
+        macro_matcher!(
+            name: "println",
+            braces: ("(", ")"),
+        ),
+        macro_matcher!(
+            name: "eprint",
+            braces: ("(", ")"),
+        ),
+        macro_matcher!(
+            name: "eprintln",
+            braces: ("(", ")"),
+        ),
+        macro_matcher!(
+            name: "write",
+            braces: ("(", ")"),
+        ),
+        macro_matcher!(
+            name: "writeln",
+            braces: ("(", ")"),
+        ),
+        macro_matcher!(
+            name: "format",
+            braces: ("(", ")"),
+        ),
+        macro_matcher!(
+            name: "format_args",
+            braces: ("(", ")"),
+        ),
+        macro_matcher!(
+            name: "vec",
+            braces: ("[", "]"),
+        ),
+    ]
+    .into_iter()
+    .collect::<FxHashMap<_, _>>();
+    // We want users items to override any existing items
+    for it in conf {
+        braces.insert(it.name, it.braces);
+    }
+    braces
+}
+
+macro_rules! macro_matcher {
+    (name: $name:expr, braces: ($open:expr, $close:expr) $(,)?) => {
+        ($name.to_owned(), ($open.to_owned(), $close.to_owned()))
+    };
+}
+pub(crate) use macro_matcher;
+
+#[derive(Clone, Debug)]
+pub struct MacroMatcher {
+    name: String,
+    braces: (String, String),
+}
+
+impl Hash for MacroMatcher {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.name.hash(state);
+    }
+}
+
+impl PartialEq for MacroMatcher {
+    fn eq(&self, other: &Self) -> bool {
+        self.name == other.name
+    }
+}
+impl Eq for MacroMatcher {}
+
+impl<'de> Deserialize<'de> for MacroMatcher {
+    fn deserialize<D>(deser: D) -> Result<Self, D::Error>
+    where
+        D: de::Deserializer<'de>,
+    {
+        #[derive(Deserialize)]
+        #[serde(field_identifier, rename_all = "lowercase")]
+        enum Field {
+            Name,
+            Brace,
+        }
+        struct MacVisitor;
+        impl<'de> de::Visitor<'de> for MacVisitor {
+            type Value = MacroMatcher;
+
+            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+                formatter.write_str("struct MacroMatcher")
+            }
+
+            fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
+            where
+                V: de::MapAccess<'de>,
+            {
+                let mut name = None;
+                let mut brace: Option<&str> = None;
+                while let Some(key) = map.next_key()? {
+                    match key {
+                        Field::Name => {
+                            if name.is_some() {
+                                return Err(de::Error::duplicate_field("name"));
+                            }
+                            name = Some(map.next_value()?);
+                        },
+                        Field::Brace => {
+                            if brace.is_some() {
+                                return Err(de::Error::duplicate_field("brace"));
+                            }
+                            brace = Some(map.next_value()?);
+                        },
+                    }
+                }
+                let name = name.ok_or_else(|| de::Error::missing_field("name"))?;
+                let brace = brace.ok_or_else(|| de::Error::missing_field("brace"))?;
+                Ok(MacroMatcher {
+                    name,
+                    braces: BRACES
+                        .iter()
+                        .find(|b| b.0 == brace)
+                        .map(|(o, c)| ((*o).to_owned(), (*c).to_owned()))
+                        .ok_or_else(|| {
+                            de::Error::custom(&format!("expected one of `(`, `{{`, `[` found `{}`", brace))
+                        })?,
+                })
+            }
+        }
+
+        const FIELDS: &[&str] = &["name", "brace"];
+        deser.deserialize_struct("MacroMatcher", FIELDS, MacVisitor)
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs
index ae5f0627fd6..b41c478c266 100644
--- a/src/tools/clippy/clippy_lints/src/ranges.rs
+++ b/src/tools/clippy/clippy_lints/src/ranges.rs
@@ -329,7 +329,7 @@ fn check_range_zip_with_len(cx: &LateContext<'_>, path: &PathSegment<'_>, args:
         if is_integer_const(cx, start, 0);
         // `.len()` call
         if let ExprKind::MethodCall(len_path, _, len_args, _) = end.kind;
-        if len_path.ident.name == sym!(len) && len_args.len() == 1;
+        if len_path.ident.name == sym::len && len_args.len() == 1;
         // `.iter()` and `.len()` called on same `Path`
         if let ExprKind::Path(QPath::Resolved(_, iter_path)) = iter_args[0].kind;
         if let ExprKind::Path(QPath::Resolved(_, len_path)) = len_args[0].kind;
diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
index 7dafce60d5e..119ec21520f 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
@@ -132,7 +132,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
                 }
             }
 
-            // `{ cloned = &arg; clone(move cloned); }` or `{ cloned = &arg; to_path_buf(cloned); }`
+            // `{ arg = &cloned; clone(move arg); }` or `{ arg = &cloned; to_path_buf(arg); }`
             let (cloned, cannot_move_out) = unwrap_or_continue!(find_stmt_assigns_to(cx, mir, arg, from_borrow, bb));
 
             let loc = mir::Location {
diff --git a/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs b/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs
index 16e4d73851f..da3e30af35c 100644
--- a/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs
+++ b/src/tools/clippy/clippy_lints/src/semicolon_if_nothing_returned.rs
@@ -1,3 +1,4 @@
+use crate::rustc_lint::LintContext;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_macro_callsite;
 use clippy_utils::{in_macro, sugg};
@@ -45,6 +46,7 @@ impl LateLintPass<'_> for SemicolonIfNothingReturned {
             if t_expr.is_unit();
             if let snippet = snippet_with_macro_callsite(cx, expr.span, "}");
             if !snippet.ends_with('}');
+            if cx.sess().source_map().is_multiline(block.span);
             then {
                 // filter out the desugared `for` loop
                 if let ExprKind::DropTemps(..) = &expr.kind {
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
index 512abde11a6..2203ab57b10 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
@@ -26,7 +26,7 @@ declare_clippy_lint! {
     /// }
     /// ```
     pub SUSPICIOUS_ARITHMETIC_IMPL,
-    correctness,
+    suspicious,
     "suspicious use of operators in impl of arithmetic trait"
 }
 
@@ -47,7 +47,7 @@ declare_clippy_lint! {
     /// }
     /// ```
     pub SUSPICIOUS_OP_ASSIGN_IMPL,
-    correctness,
+    suspicious,
     "suspicious use of operators in impl of OpAssign trait"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index 1b3c457b01a..07a4e294049 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -1,6 +1,6 @@
 #![allow(clippy::wildcard_imports, clippy::enum_glob_use)]
 
-use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_pat, eq_path, eq_maybe_qself};
+use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_maybe_qself, eq_pat, eq_path};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::{meets_msrv, msrvs, over};
 use rustc_ast::mut_visit::*;
@@ -277,7 +277,8 @@ fn transform_with_focus_on_idx(alternatives: &mut Vec<P<Pat>>, focus_idx: usize)
             ps1, start, alternatives,
             |k, ps1, idx| matches!(
                 k,
-                TupleStruct(qself2, path2, ps2) if eq_maybe_qself(qself1, qself2) && eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
+                TupleStruct(qself2, path2, ps2)
+                    if eq_maybe_qself(qself1, qself2) && eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
             ),
             |k| always_pat!(k, TupleStruct(_, _, ps) => ps),
         ),
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index 254b104bdef..906ac10f461 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -1,23 +1,22 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::same_type_and_consts;
 use clippy_utils::{in_macro, meets_msrv, msrvs};
 use if_chain::if_chain;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::{
     self as hir,
-    def::{self, DefKind},
+    def::{CtorOf, DefKind, Res},
     def_id::LocalDefId,
     intravisit::{walk_ty, NestedVisitorMap, Visitor},
-    Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Node, Path, PathSegment,
-    QPath, TyKind,
+    Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Path, QPath, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::map::Map;
-use rustc_middle::ty::{AssocKind, Ty};
+use rustc_middle::ty::AssocKind;
 use rustc_semver::RustcVersion;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::{BytePos, Span};
+use rustc_span::Span;
 use rustc_typeck::hir_ty_to_ty;
 
 declare_clippy_lint! {
@@ -75,10 +74,9 @@ impl UseSelf {
 #[derive(Debug)]
 enum StackItem {
     Check {
-        hir_id: HirId,
-        impl_trait_ref_def_id: Option<LocalDefId>,
-        types_to_skip: Vec<HirId>,
-        types_to_lint: Vec<HirId>,
+        impl_id: LocalDefId,
+        in_body: u32,
+        types_to_skip: FxHashSet<HirId>,
     },
     NoCheck,
 }
@@ -88,60 +86,41 @@ impl_lint_pass!(UseSelf => [USE_SELF]);
 const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element";
 
 impl<'tcx> LateLintPass<'tcx> for UseSelf {
-    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
+    fn check_item(&mut self, _cx: &LateContext<'_>, item: &Item<'_>) {
+        if !is_item_interesting(item) {
+            // This does two things:
+            //  1) Reduce needless churn on `self.stack`
+            //  2) Don't push `StackItem::NoCheck` when entering `ItemKind::OpaqueTy`,
+            //     in order to lint `foo() -> impl <..>`
+            return;
+        }
         // We push the self types of `impl`s on a stack here. Only the top type on the stack is
         // relevant for linting, since this is the self type of the `impl` we're currently in. To
         // avoid linting on nested items, we push `StackItem::NoCheck` on the stack to signal, that
         // we're in an `impl` or nested item, that we don't want to lint
-        //
-        // NB: If you push something on the stack in this method, remember to also pop it in the
-        // `check_item_post` method.
-        match &item.kind {
-            ItemKind::Impl(Impl {
-                self_ty: hir_self_ty,
-                of_trait,
-                ..
-            }) => {
-                let should_check = if let TyKind::Path(QPath::Resolved(_, item_path)) = hir_self_ty.kind {
-                    let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args;
-                    parameters.as_ref().map_or(true, |params| {
-                        !params.parenthesized && !params.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))
-                    })
-                } else {
-                    false
-                };
-                let impl_trait_ref_def_id = of_trait.as_ref().map(|_| cx.tcx.hir().local_def_id(item.hir_id()));
-                if should_check {
-                    self.stack.push(StackItem::Check {
-                        hir_id: hir_self_ty.hir_id,
-                        impl_trait_ref_def_id,
-                        types_to_lint: Vec::new(),
-                        types_to_skip: Vec::new(),
-                    });
-                } else {
-                    self.stack.push(StackItem::NoCheck);
+        let stack_item = if_chain! {
+            if let ItemKind::Impl(Impl { self_ty, .. }) = item.kind;
+            if let TyKind::Path(QPath::Resolved(_, item_path)) = self_ty.kind;
+            let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args;
+            if parameters.as_ref().map_or(true, |params| {
+                !params.parenthesized && !params.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))
+            });
+            then {
+                StackItem::Check {
+                    impl_id: item.def_id,
+                    in_body: 0,
+                    types_to_skip: std::iter::once(self_ty.hir_id).collect(),
                 }
-            },
-            ItemKind::Static(..)
-            | ItemKind::Const(..)
-            | ItemKind::Fn(..)
-            | ItemKind::Enum(..)
-            | ItemKind::Struct(..)
-            | ItemKind::Union(..)
-            | ItemKind::Trait(..) => {
-                self.stack.push(StackItem::NoCheck);
-            },
-            _ => (),
-        }
+            } else {
+                StackItem::NoCheck
+            }
+        };
+        self.stack.push(stack_item);
     }
 
     fn check_item_post(&mut self, _: &LateContext<'_>, item: &Item<'_>) {
-        use ItemKind::{Const, Enum, Fn, Impl, Static, Struct, Trait, Union};
-        match item.kind {
-            Impl { .. } | Static(..) | Const(..) | Fn(..) | Enum(..) | Struct(..) | Union(..) | Trait(..) => {
-                self.stack.pop();
-            },
-            _ => (),
+        if is_item_interesting(item) {
+            self.stack.pop();
         }
     }
 
@@ -151,11 +130,11 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
         if_chain! {
             if let ImplItemKind::Fn(FnSig { decl, .. }, ..) = impl_item.kind;
             if let Some(&mut StackItem::Check {
-                impl_trait_ref_def_id: Some(def_id),
+                impl_id,
                 ref mut types_to_skip,
                 ..
             }) = self.stack.last_mut();
-            if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(def_id);
+            if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(impl_id);
             then {
                 // `self_ty` is the semantic self type of `impl <trait> for <type>`. This cannot be
                 // `Self`.
@@ -203,142 +182,76 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
         }
     }
 
-    fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) {
+    fn check_body(&mut self, _: &LateContext<'_>, _: &hir::Body<'_>) {
         // `hir_ty_to_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies
         // we can use `cx.typeck_results.node_type(..)` to get the `ty::Ty` from a `hir::Ty`.
         // However the `node_type()` method can *only* be called in bodies.
-        //
-        // This method implementation determines which types should get linted in a `Body` and
-        // which shouldn't, with a visitor. We could directly lint in the visitor, but then we
-        // could only allow this lint on item scope. And we would have to check if those types are
-        // already dealt with in `check_ty` anyway.
-        if let Some(StackItem::Check {
-            hir_id,
-            types_to_lint,
-            types_to_skip,
-            ..
-        }) = self.stack.last_mut()
-        {
-            let self_ty = ty_from_hir_id(cx, *hir_id);
-
-            let mut visitor = LintTyCollector {
-                cx,
-                self_ty,
-                types_to_lint: vec![],
-                types_to_skip: vec![],
-            };
-            visitor.visit_expr(&body.value);
-            types_to_lint.extend(visitor.types_to_lint);
-            types_to_skip.extend(visitor.types_to_skip);
+        if let Some(&mut StackItem::Check { ref mut in_body, .. }) = self.stack.last_mut() {
+            *in_body = in_body.saturating_add(1);
         }
     }
 
-    fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) {
-        if in_macro(hir_ty.span)
-            || in_impl(cx, hir_ty)
-            || !meets_msrv(self.msrv.as_ref(), &msrvs::TYPE_ALIAS_ENUM_VARIANTS)
-        {
-            return;
+    fn check_body_post(&mut self, _: &LateContext<'_>, _: &hir::Body<'_>) {
+        if let Some(&mut StackItem::Check { ref mut in_body, .. }) = self.stack.last_mut() {
+            *in_body = in_body.saturating_sub(1);
         }
+    }
 
-        let lint_dependend_on_expr_kind = if let Some(StackItem::Check {
-            hir_id,
-            types_to_lint,
-            types_to_skip,
-            ..
-        }) = self.stack.last()
-        {
-            if types_to_skip.contains(&hir_ty.hir_id) {
-                false
-            } else if types_to_lint.contains(&hir_ty.hir_id) {
-                true
+    fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) {
+        if_chain! {
+            if !in_macro(hir_ty.span);
+            if meets_msrv(self.msrv.as_ref(), &msrvs::TYPE_ALIAS_ENUM_VARIANTS);
+            if let Some(&StackItem::Check {
+                impl_id,
+                in_body,
+                ref types_to_skip,
+            }) = self.stack.last();
+            if let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind;
+            if !matches!(path.res, Res::SelfTy(..) | Res::Def(DefKind::TyParam, _));
+            if !types_to_skip.contains(&hir_ty.hir_id);
+            let ty = if in_body > 0 {
+                cx.typeck_results().node_type(hir_ty.hir_id)
             } else {
-                let self_ty = ty_from_hir_id(cx, *hir_id);
-                should_lint_ty(hir_ty, hir_ty_to_ty(cx.tcx, hir_ty), self_ty)
-            }
-        } else {
-            false
-        };
-
-        if lint_dependend_on_expr_kind {
-            // FIXME: this span manipulation should not be necessary
-            // @flip1995 found an ast lowering issue in
-            // https://github.com/rust-lang/rust/blob/master/src/librustc_ast_lowering/path.rs#l142-l162
+                hir_ty_to_ty(cx.tcx, hir_ty)
+            };
+            if same_type_and_consts(ty, cx.tcx.type_of(impl_id));
             let hir = cx.tcx.hir();
             let id = hir.get_parent_node(hir_ty.hir_id);
-
-            if !hir.opt_span(id).map_or(false, in_macro) {
-                match hir.find(id) {
-                    Some(Node::Expr(Expr {
-                        kind: ExprKind::Path(QPath::TypeRelative(_, segment)),
-                        ..
-                    })) => span_lint_until_last_segment(cx, hir_ty.span, segment),
-                    _ => span_lint(cx, hir_ty.span),
-                }
+            if !hir.opt_span(id).map_or(false, in_macro);
+            then {
+                span_lint(cx, hir_ty.span);
             }
         }
     }
 
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
-        fn expr_ty_matches(cx: &LateContext<'_>, expr: &Expr<'_>, self_ty: Ty<'_>) -> bool {
-            let def_id = expr.hir_id.owner;
-            if cx.tcx.has_typeck_results(def_id) {
-                cx.tcx.typeck(def_id).expr_ty_opt(expr) == Some(self_ty)
-            } else {
-                false
-            }
-        }
-
-        if in_macro(expr.span) || !meets_msrv(self.msrv.as_ref(), &msrvs::TYPE_ALIAS_ENUM_VARIANTS) {
-            return;
+        if_chain! {
+            if !in_macro(expr.span);
+            if meets_msrv(self.msrv.as_ref(), &msrvs::TYPE_ALIAS_ENUM_VARIANTS);
+            if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last();
+            if cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id);
+            then {} else { return; }
         }
-
-        if let Some(StackItem::Check { hir_id, .. }) = self.stack.last() {
-            let self_ty = ty_from_hir_id(cx, *hir_id);
-
-            match &expr.kind {
-                ExprKind::Struct(QPath::Resolved(_, path), ..) => {
-                    if expr_ty_matches(cx, expr, self_ty) {
-                        match path.res {
-                            def::Res::SelfTy(..) => (),
-                            def::Res::Def(DefKind::Variant, _) => span_lint_on_path_until_last_segment(cx, path),
-                            _ => {
-                                span_lint(cx, path.span);
-                            },
-                        }
-                    }
-                },
-                // tuple struct instantiation (`Foo(arg)` or `Enum::Foo(arg)`)
-                ExprKind::Call(fun, _) => {
-                    if let Expr {
-                        kind: ExprKind::Path(ref qpath),
-                        ..
-                    } = fun
-                    {
-                        if expr_ty_matches(cx, expr, self_ty) {
-                            let res = cx.qpath_res(qpath, fun.hir_id);
-
-                            if let def::Res::Def(DefKind::Ctor(ctor_of, _), ..) = res {
-                                match ctor_of {
-                                    def::CtorOf::Variant => {
-                                        span_lint_on_qpath_resolved(cx, qpath, true);
-                                    },
-                                    def::CtorOf::Struct => {
-                                        span_lint_on_qpath_resolved(cx, qpath, false);
-                                    },
-                                }
-                            }
+        match expr.kind {
+            ExprKind::Struct(QPath::Resolved(_, path), ..) => match path.res {
+                Res::SelfTy(..) => (),
+                Res::Def(DefKind::Variant, _) => lint_path_to_variant(cx, path),
+                _ => span_lint(cx, path.span),
+            },
+            // tuple struct instantiation (`Foo(arg)` or `Enum::Foo(arg)`)
+            ExprKind::Call(fun, _) => {
+                if let ExprKind::Path(QPath::Resolved(_, path)) = fun.kind {
+                    if let Res::Def(DefKind::Ctor(ctor_of, _), ..) = path.res {
+                        match ctor_of {
+                            CtorOf::Variant => lint_path_to_variant(cx, path),
+                            CtorOf::Struct => span_lint(cx, path.span),
                         }
                     }
-                },
-                // unit enum variants (`Enum::A`)
-                ExprKind::Path(qpath) => {
-                    if expr_ty_matches(cx, expr, self_ty) {
-                        span_lint_on_qpath_resolved(cx, qpath, true);
-                    }
-                },
-                _ => (),
-            }
+                }
+            },
+            // unit enum variants (`Enum::A`)
+            ExprKind::Path(QPath::Resolved(_, path)) => lint_path_to_variant(cx, path),
+            _ => (),
         }
     }
 
@@ -364,35 +277,6 @@ impl<'tcx> Visitor<'tcx> for SkipTyCollector {
     }
 }
 
-struct LintTyCollector<'a, 'tcx> {
-    cx: &'a LateContext<'tcx>,
-    self_ty: Ty<'tcx>,
-    types_to_lint: Vec<HirId>,
-    types_to_skip: Vec<HirId>,
-}
-
-impl<'a, 'tcx> Visitor<'tcx> for LintTyCollector<'a, 'tcx> {
-    type Map = Map<'tcx>;
-
-    fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'_>) {
-        if_chain! {
-            if let Some(ty) = self.cx.typeck_results().node_type_opt(hir_ty.hir_id);
-            if should_lint_ty(hir_ty, ty, self.self_ty);
-            then {
-                self.types_to_lint.push(hir_ty.hir_id);
-            } else {
-                self.types_to_skip.push(hir_ty.hir_id);
-            }
-        }
-
-        walk_ty(self, hir_ty);
-    }
-
-    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
-        NestedVisitorMap::None
-    }
-}
-
 fn span_lint(cx: &LateContext<'_>, span: Span) {
     span_lint_and_sugg(
         cx,
@@ -405,66 +289,19 @@ fn span_lint(cx: &LateContext<'_>, span: Span) {
     );
 }
 
-#[allow(clippy::cast_possible_truncation)]
-fn span_lint_until_last_segment(cx: &LateContext<'_>, span: Span, segment: &PathSegment<'_>) {
-    let sp = span.with_hi(segment.ident.span.lo());
-    // remove the trailing ::
-    let span_without_last_segment = match snippet_opt(cx, sp) {
-        Some(snippet) => match snippet.rfind("::") {
-            Some(bidx) => sp.with_hi(sp.lo() + BytePos(bidx as u32)),
-            None => sp,
-        },
-        None => sp,
-    };
-    span_lint(cx, span_without_last_segment);
-}
-
-fn span_lint_on_path_until_last_segment(cx: &LateContext<'_>, path: &Path<'_>) {
-    if path.segments.len() > 1 {
-        span_lint_until_last_segment(cx, path.span, path.segments.last().unwrap());
-    }
-}
-
-fn span_lint_on_qpath_resolved(cx: &LateContext<'_>, qpath: &QPath<'_>, until_last_segment: bool) {
-    if let QPath::Resolved(_, path) = qpath {
-        if until_last_segment {
-            span_lint_on_path_until_last_segment(cx, path);
-        } else {
-            span_lint(cx, path.span);
-        }
-    }
-}
-
-fn ty_from_hir_id<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Ty<'tcx> {
-    if let Some(Node::Ty(hir_ty)) = cx.tcx.hir().find(hir_id) {
-        hir_ty_to_ty(cx.tcx, hir_ty)
-    } else {
-        unreachable!("This function should only be called with `HirId`s that are for sure `Node::Ty`")
-    }
-}
-
-fn in_impl(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'_>) -> bool {
-    let map = cx.tcx.hir();
-    let parent = map.get_parent_node(hir_ty.hir_id);
-    if_chain! {
-        if let Some(Node::Item(item)) = map.find(parent);
-        if let ItemKind::Impl { .. } = item.kind;
-        then {
-            true
-        } else {
-            false
-        }
+fn lint_path_to_variant(cx: &LateContext<'_>, path: &Path<'_>) {
+    if let [.., self_seg, _variant] = path.segments {
+        let span = path
+            .span
+            .with_hi(self_seg.args().span_ext().unwrap_or(self_seg.ident.span).hi());
+        span_lint(cx, span);
     }
 }
 
-fn should_lint_ty(hir_ty: &hir::Ty<'_>, ty: Ty<'_>, self_ty: Ty<'_>) -> bool {
-    if_chain! {
-        if same_type_and_consts(ty, self_ty);
-        if let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind;
-        then {
-            !matches!(path.res, def::Res::SelfTy(..))
-        } else {
-            false
-        }
-    }
+fn is_item_interesting(item: &Item<'_>) -> bool {
+    use rustc_hir::ItemKind::{Const, Enum, Fn, Impl, Static, Struct, Trait, Union};
+    matches!(
+        item.kind,
+        Impl { .. } | Static(..) | Const(..) | Fn(..) | Enum(..) | Struct(..) | Union(..) | Trait(..)
+    )
 }
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index 2be99fb761b..c97f7e1626e 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -104,7 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                     }
                 }
                 if_chain! {
-                    if match_trait_method(cx, e, &paths::TRY_INTO_TRAIT) && &*name.ident.as_str() == "try_into";
+                    if match_trait_method(cx, e, &paths::TRY_INTO_TRAIT) && name.ident.name == sym::try_into;
                     let a = cx.typeck_results().expr_ty(e);
                     let b = cx.typeck_results().expr_ty(&args[0]);
                     if is_type_diagnostic_item(cx, a, sym::result_type);
diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs
index 0e33ae740d9..44d3d456342 100644
--- a/src/tools/clippy/clippy_lints/src/utils/conf.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs
@@ -8,6 +8,13 @@ use std::error::Error;
 use std::path::{Path, PathBuf};
 use std::{env, fmt, fs, io};
 
+/// Holds information used by `MISSING_ENFORCED_IMPORT_RENAMES` lint.
+#[derive(Clone, Debug, Deserialize)]
+pub struct Rename {
+    pub path: String,
+    pub rename: String,
+}
+
 /// Conf with parse errors
 #[derive(Default)]
 pub struct TryConf {
@@ -24,6 +31,9 @@ impl TryConf {
     }
 }
 
+/// Note that the configuration parsing currently doesn't support documentation that will
+/// that spans over several lines. This will be possible with the new implementation
+/// See (rust-clippy#7172)
 macro_rules! define_Conf {
     ($(
         #[doc = $doc:literal]
@@ -149,7 +159,7 @@ define_Conf! {
         "WebGL",
         "TensorFlow",
         "TrueType",
-        "iOS", "macOS",
+        "iOS", "macOS", "FreeBSD",
         "TeX", "LaTeX", "BibTeX", "BibLaTeX",
         "MinGW",
         "CamelCase",
@@ -182,20 +192,28 @@ define_Conf! {
     (vec_box_size_threshold: u64 = 4096),
     /// Lint: TYPE_REPETITION_IN_BOUNDS. The maximum number of bounds a trait can have to be linted
     (max_trait_bounds: u64 = 3),
-    /// Lint: STRUCT_EXCESSIVE_BOOLS. The maximum number of bools a struct can have
+    /// Lint: STRUCT_EXCESSIVE_BOOLS. The maximum number of bool fields a struct can have
     (max_struct_bools: u64 = 3),
-    /// Lint: FN_PARAMS_EXCESSIVE_BOOLS. The maximum number of bools function parameters can have
+    /// Lint: FN_PARAMS_EXCESSIVE_BOOLS. The maximum number of bool parameters a function can have
     (max_fn_params_bools: u64 = 3),
     /// Lint: WILDCARD_IMPORTS. Whether to allow certain wildcard imports (prelude, super in tests).
     (warn_on_all_wildcard_imports: bool = false),
     /// Lint: DISALLOWED_METHOD. The list of disallowed methods, written as fully qualified paths.
     (disallowed_methods: Vec<String> = Vec::new()),
+    /// Lint: DISALLOWED_TYPE. The list of disallowed types, written as fully qualified paths.
+    (disallowed_types: Vec<String> = Vec::new()),
     /// Lint: UNREADABLE_LITERAL. Should the fraction of a decimal be linted to include separators.
     (unreadable_literal_lint_fractions: bool = true),
     /// Lint: UPPER_CASE_ACRONYMS. Enables verbose mode. Triggers if there is more than one uppercase char next to each other
     (upper_case_acronyms_aggressive: bool = false),
     /// Lint: _CARGO_COMMON_METADATA. For internal testing only, ignores the current `publish` settings in the Cargo manifest.
     (cargo_ignore_publish: bool = false),
+    /// Lint: NONSTANDARD_MACRO_BRACES. Enforce the named macros always use the braces specified. <br> A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If the macro is could be used with a full path two `MacroMatcher`s have to be added one with the full path `crate_name::macro_name` and one with just the macro name.
+    (standard_macro_braces: Vec<crate::nonstandard_macro_braces::MacroMatcher> = Vec::new()),
+    /// Lint: MISSING_ENFORCED_IMPORT_RENAMES. The list of imports to always rename, a fully qualified path followed by the rename.
+    (enforced_import_renames: Vec<crate::utils::conf::Rename> = Vec::new()),
+    /// Lint: RESTRICTED_SCRIPTS. The list of unicode scripts allowed to be used in the scope.
+    (allowed_scripts: Vec<String> = vec!["Latin".to_string()]),
 }
 
 /// Search for the configuration file.
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
index 46af03663b8..e877af09e28 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
@@ -9,6 +9,7 @@
 //! a simple mistake)
 
 use if_chain::if_chain;
+use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::{
     self as hir, def::DefKind, intravisit, intravisit::Visitor, ExprKind, Item, ItemKind, Mutability, QPath,
@@ -46,8 +47,9 @@ const DEPRECATED_LINT_GROUP_STR: &str = "deprecated";
 const DEPRECATED_LINT_LEVEL: &str = "none";
 /// This array holds Clippy's lint groups with their corresponding default lint level. The
 /// lint level for deprecated lints is set in `DEPRECATED_LINT_LEVEL`.
-const DEFAULT_LINT_LEVELS: [(&str, &str); 8] = [
+const DEFAULT_LINT_LEVELS: &[(&str, &str)] = &[
     ("correctness", "deny"),
+    ("suspicious", "warn"),
     ("restriction", "allow"),
     ("style", "warn"),
     ("pedantic", "allow"),
@@ -485,16 +487,32 @@ fn extract_attr_docs_or_lint(cx: &LateContext<'_>, item: &Item<'_>) -> Option<St
 ///
 /// Would result in `Hello world!\n=^.^=\n`
 fn extract_attr_docs(cx: &LateContext<'_>, item: &Item<'_>) -> Option<String> {
-    cx.tcx
-        .hir()
-        .attrs(item.hir_id())
-        .iter()
-        .filter_map(|x| x.doc_str().map(|sym| sym.as_str().to_string()))
-        .reduce(|mut acc, sym| {
-            acc.push_str(&sym);
-            acc.push('\n');
-            acc
-        })
+    let attrs = cx.tcx.hir().attrs(item.hir_id());
+    let mut lines = attrs.iter().filter_map(ast::Attribute::doc_str);
+    let mut docs = String::from(&*lines.next()?.as_str());
+    let mut in_code_block = false;
+    for line in lines {
+        docs.push('\n');
+        let line = line.as_str();
+        let line = &*line;
+        if let Some(info) = line.trim_start().strip_prefix("```") {
+            in_code_block = !in_code_block;
+            if in_code_block {
+                let lang = info
+                    .trim()
+                    .split(',')
+                    // remove rustdoc directives
+                    .find(|&s| !matches!(s, "" | "ignore" | "no_run" | "should_panic"))
+                    // if no language is present, fill in "rust"
+                    .unwrap_or("rust");
+                docs.push_str("```");
+                docs.push_str(lang);
+                continue;
+            }
+        }
+        docs.push_str(line);
+    }
+    Some(docs)
 }
 
 fn get_lint_group_and_level_or_lint(
diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
index 51c1117d206..520586b3a1f 100644
--- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::in_macro;
 use clippy_utils::source::{snippet, snippet_with_applicability};
+use clippy_utils::{in_macro, is_test_module_or_function};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{
@@ -106,7 +106,7 @@ impl_lint_pass!(WildcardImports => [ENUM_GLOB_USE, WILDCARD_IMPORTS]);
 
 impl LateLintPass<'_> for WildcardImports {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
-        if is_test_module_or_function(item) {
+        if is_test_module_or_function(cx.tcx, item) {
             self.test_modules_deep = self.test_modules_deep.saturating_add(1);
         }
         if item.vis.node.is_pub() || item.vis.node.is_pub_restricted() {
@@ -183,8 +183,8 @@ impl LateLintPass<'_> for WildcardImports {
         }
     }
 
-    fn check_item_post(&mut self, _: &LateContext<'_>, item: &Item<'_>) {
-        if is_test_module_or_function(item) {
+    fn check_item_post(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
+        if is_test_module_or_function(cx.tcx, item) {
             self.test_modules_deep = self.test_modules_deep.saturating_sub(1);
         }
     }
@@ -208,7 +208,3 @@ fn is_prelude_import(segments: &[PathSegment<'_>]) -> bool {
 fn is_super_only_import(segments: &[PathSegment<'_>]) -> bool {
     segments.len() == 1 && segments[0].ident.name == kw::Super
 }
-
-fn is_test_module_or_function(item: &Item<'_>) -> bool {
-    matches!(item.kind, ItemKind::Mod(..)) && item.ident.name.as_str().contains("test")
-}
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index 93ed3b18400..6ede9011208 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_utils"
-version = "0.1.54"
+version = "0.1.55"
 authors = ["The Rust Clippy Developers"]
 edition = "2018"
 publish = false
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 90c034bd02a..30c2260d15c 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -47,9 +47,14 @@ pub fn eq_pat(l: &Pat, r: &Pat) -> bool {
         | (Ref(l, Mutability::Mut), Ref(r, Mutability::Mut)) => eq_pat(l, r),
         (Tuple(l), Tuple(r)) | (Slice(l), Slice(r)) => over(l, r, |l, r| eq_pat(l, r)),
         (Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
-        (TupleStruct(lqself, lp, lfs), TupleStruct(rqself, rp, rfs)) => eq_maybe_qself(lqself, rqself) && eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r)),
+        (TupleStruct(lqself, lp, lfs), TupleStruct(rqself, rp, rfs)) => {
+            eq_maybe_qself(lqself, rqself) && eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r))
+        },
         (Struct(lqself, lp, lfs, lr), Struct(rqself, rp, rfs, rr)) => {
-            lr == rr && eq_maybe_qself(lqself, rqself) &&eq_path(lp, rp) && unordered_over(lfs, rfs, |lf, rf| eq_field_pat(lf, rf))
+            lr == rr
+                && eq_maybe_qself(lqself, rqself)
+                && eq_path(lp, rp)
+                && unordered_over(lfs, rfs, |lf, rf| eq_field_pat(lf, rf))
         },
         (Or(ls), Or(rs)) => unordered_over(ls, rs, |l, r| eq_pat(l, r)),
         (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
@@ -82,7 +87,7 @@ pub fn eq_maybe_qself(l: &Option<QSelf>, r: &Option<QSelf>) -> bool {
     match (l, r) {
         (Some(l), Some(r)) => eq_qself(l, r),
         (None, None) => true,
-        _ => false
+        _ => false,
     }
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index 0318c483959..c19b558cd8c 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -157,3 +157,8 @@ pub fn is_doc_hidden(attrs: &[ast::Attribute]) -> bool {
         .filter_map(ast::Attribute::meta_item_list)
         .any(|l| attr::list_contains_name(&l, sym::hidden))
 }
+
+/// Return true if the attributes contain `#[unstable]`
+pub fn is_unstable(attrs: &[ast::Attribute]) -> bool {
+    attrs.iter().any(|attr| attr.has_name(sym::unstable))
+}
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 0d7fdeeb920..15c27d1a996 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -1,6 +1,6 @@
 #![allow(clippy::float_cmp)]
 
-use crate::{clip, sext, unsext};
+use crate::{clip, is_direct_expn_of, sext, unsext};
 use if_chain::if_chain;
 use rustc_ast::ast::{self, LitFloatType, LitKind};
 use rustc_data_structures::sync::Lrc;
@@ -230,7 +230,13 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
         match e.kind {
             ExprKind::Path(ref qpath) => self.fetch_path(qpath, e.hir_id, self.typeck_results.expr_ty(e)),
             ExprKind::Block(block, _) => self.block(block),
-            ExprKind::Lit(ref lit) => Some(lit_to_constant(&lit.node, self.typeck_results.expr_ty_opt(e))),
+            ExprKind::Lit(ref lit) => {
+                if is_direct_expn_of(e.span, "cfg").is_some() {
+                    None
+                } else {
+                    Some(lit_to_constant(&lit.node, self.typeck_results.expr_ty_opt(e)))
+                }
+            },
             ExprKind::Array(vec) => self.multi(vec).map(Constant::Vec),
             ExprKind::Tup(tup) => self.multi(tup).map(Constant::Tuple),
             ExprKind::Repeat(value, _) => {
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 769836aaf18..217a1f4dded 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -72,7 +72,7 @@ use rustc_hir::LangItem::{ResultErr, ResultOk};
 use rustc_hir::{
     def, Arm, BindingAnnotation, Block, Body, Constness, Destination, Expr, ExprKind, FnDecl, GenericArgs, HirId, Impl,
     ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource, Node, Param, Pat, PatKind, Path,
-    PathSegment, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitRef, TyKind,
+    PathSegment, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitRef, TyKind, UnOp,
 };
 use rustc_lint::{LateContext, Level, Lint, LintContext};
 use rustc_middle::hir::exports::Export;
@@ -326,16 +326,6 @@ pub fn is_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol)
         .map_or(false, |did| is_diag_trait_item(cx, did, diag_item))
 }
 
-/// Checks if an expression references a variable of the given name.
-pub fn match_var(expr: &Expr<'_>, var: Symbol) -> bool {
-    if let ExprKind::Path(QPath::Resolved(None, path)) = expr.kind {
-        if let [p] = path.segments {
-            return p.ident.name == var;
-        }
-    }
-    false
-}
-
 pub fn last_path_segment<'tcx>(path: &QPath<'tcx>) -> &'tcx PathSegment<'tcx> {
     match *path {
         QPath::Resolved(_, path) => path.segments.last().expect("A path must have at least one segment"),
@@ -493,7 +483,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
         _ => return Res::Err,
     };
     let tcx = cx.tcx;
-    let crates = tcx.crates();
+    let crates = tcx.crates(());
     let krate = try_res!(crates.iter().find(|&&num| tcx.crate_name(num).as_str() == krate));
     let first = try_res!(item_child_by_name(tcx, krate.as_def_id(), first));
     let last = path
@@ -707,16 +697,6 @@ pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
     }
 }
 
-/// Gets the name of a `Pat`, if any.
-pub fn get_pat_name(pat: &Pat<'_>) -> Option<Symbol> {
-    match pat.kind {
-        PatKind::Binding(.., ref spname, _) => Some(spname.name),
-        PatKind::Path(ref qpath) => single_segment_path(qpath).map(|ps| ps.ident.name),
-        PatKind::Box(p) | PatKind::Ref(p, _) => get_pat_name(&*p),
-        _ => None,
-    }
-}
-
 pub struct ContainsName {
     pub name: Symbol,
     pub result: bool,
@@ -861,14 +841,16 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio
     })
 }
 
-/// Gets the loop enclosing the given expression, if any.
-pub fn get_enclosing_loop(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
+/// Gets the loop or closure enclosing the given expression, if any.
+pub fn get_enclosing_loop_or_closure(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
     let map = tcx.hir();
     for (_, node) in map.parent_iter(expr.hir_id) {
         match node {
             Node::Expr(
-                e @ Expr {
-                    kind: ExprKind::Loop(..),
+                e
+                @
+                Expr {
+                    kind: ExprKind::Loop(..) | ExprKind::Closure(..),
                     ..
                 },
             ) => return Some(e),
@@ -1399,6 +1381,55 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     did.map_or(false, |did| must_use_attr(cx.tcx.get_attrs(did)).is_some())
 }
 
+/// Checks if an expression represents the identity function
+/// Only examines closures and `std::convert::identity`
+pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    /// Checks if a function's body represents the identity function. Looks for bodies of the form:
+    /// * `|x| x`
+    /// * `|x| return x`
+    /// * `|x| { return x }`
+    /// * `|x| { return x; }`
+    fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
+        let id = if_chain! {
+            if let [param] = func.params;
+            if let PatKind::Binding(_, id, _, _) = param.pat.kind;
+            then {
+                id
+            } else {
+                return false;
+            }
+        };
+
+        let mut expr = &func.value;
+        loop {
+            match expr.kind {
+                #[rustfmt::skip]
+                ExprKind::Block(&Block { stmts: [], expr: Some(e), .. }, _, )
+                | ExprKind::Ret(Some(e)) => expr = e,
+                #[rustfmt::skip]
+                ExprKind::Block(&Block { stmts: [stmt], expr: None, .. }, _) => {
+                    if_chain! {
+                        if let StmtKind::Semi(e) | StmtKind::Expr(e) = stmt.kind;
+                        if let ExprKind::Ret(Some(ret_val)) = e.kind;
+                        then {
+                            expr = ret_val;
+                        } else {
+                            return false;
+                        }
+                    }
+                },
+                _ => return path_to_local_id(expr, id) && cx.typeck_results().expr_adjustments(expr).is_empty(),
+            }
+        }
+    }
+
+    match expr.kind {
+        ExprKind::Closure(_, _, body_id, _, _) => is_body_identity_function(cx, cx.tcx.hir().body(body_id)),
+        ExprKind::Path(ref path) => is_qpath_def_path(cx, path, expr.hir_id, &paths::CONVERT_IDENTITY),
+        _ => false,
+    }
+}
+
 /// Gets the node where an expression is either used, or it's type is unified with another branch.
 pub fn get_expr_use_or_unification_node(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<Node<'tcx>> {
     let map = tcx.hir();
@@ -1654,6 +1685,19 @@ pub fn peel_hir_expr_refs(expr: &'a Expr<'a>) -> (&'a Expr<'a>, usize) {
     (e, count)
 }
 
+/// Removes `AddrOf` operators (`&`) or deref operators (`*`), but only if a reference type is
+/// dereferenced. An overloaded deref such as `Vec` to slice would not be removed.
+pub fn peel_ref_operators<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>) -> &'hir Expr<'hir> {
+    loop {
+        match expr.kind {
+            ExprKind::AddrOf(_, _, e) => expr = e,
+            ExprKind::Unary(UnOp::Deref, e) if cx.typeck_results().expr_ty(e).is_ref() => expr = e,
+            _ => break,
+        }
+    }
+    expr
+}
+
 #[macro_export]
 macro_rules! unwrap_cargo_metadata {
     ($cx: ident, $lint: ident, $deps: expr) => {{
@@ -1683,3 +1727,15 @@ pub fn is_hir_ty_cfg_dependant(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
         }
     }
 }
+
+/// Checks whether item either has `test` attribute applied, or
+/// is a module with `test` in its name.
+pub fn is_test_module_or_function(tcx: TyCtxt<'_>, item: &Item<'_>) -> bool {
+    if let Some(def_id) = tcx.hir().opt_local_def_id(item.hir_id()) {
+        if tcx.has_attr(def_id.to_def_id(), sym::test) {
+            return true;
+        }
+    }
+
+    matches!(item.kind, ItemKind::Mod(..)) && item.ident.name.as_str().contains("test")
+}
diff --git a/src/tools/clippy/clippy_utils/src/ptr.rs b/src/tools/clippy/clippy_utils/src/ptr.rs
index 791688cd194..8adb6915952 100644
--- a/src/tools/clippy/clippy_utils/src/ptr.rs
+++ b/src/tools/clippy/clippy_utils/src/ptr.rs
@@ -1,10 +1,10 @@
 use crate::source::snippet;
-use crate::{get_pat_name, match_var};
+use crate::{path_to_local_id, strip_pat_refs};
 use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
-use rustc_hir::{Body, BodyId, Expr, ExprKind, Param};
+use rustc_hir::{Body, BodyId, Expr, ExprKind, HirId, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::hir::map::Map;
-use rustc_span::{Span, Symbol};
+use rustc_span::Span;
 use std::borrow::Cow;
 
 pub fn get_spans(
@@ -14,10 +14,11 @@ pub fn get_spans(
     replacements: &[(&'static str, &'static str)],
 ) -> Option<Vec<(Span, Cow<'static, str>)>> {
     if let Some(body) = opt_body_id.map(|id| cx.tcx.hir().body(id)) {
-        get_binding_name(&body.params[idx]).map_or_else(
-            || Some(vec![]),
-            |name| extract_clone_suggestions(cx, name, replacements, body),
-        )
+        if let PatKind::Binding(_, binding_id, _, _) = strip_pat_refs(body.params[idx].pat).kind {
+            extract_clone_suggestions(cx, binding_id, replacements, body)
+        } else {
+            Some(vec![])
+        }
     } else {
         Some(vec![])
     }
@@ -25,13 +26,13 @@ pub fn get_spans(
 
 fn extract_clone_suggestions<'tcx>(
     cx: &LateContext<'tcx>,
-    name: Symbol,
+    id: HirId,
     replace: &[(&'static str, &'static str)],
     body: &'tcx Body<'_>,
 ) -> Option<Vec<(Span, Cow<'static, str>)>> {
     let mut visitor = PtrCloneVisitor {
         cx,
-        name,
+        id,
         replace,
         spans: vec![],
         abort: false,
@@ -42,7 +43,7 @@ fn extract_clone_suggestions<'tcx>(
 
 struct PtrCloneVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
-    name: Symbol,
+    id: HirId,
     replace: &'a [(&'static str, &'static str)],
     spans: Vec<(Span, Cow<'static, str>)>,
     abort: bool,
@@ -55,16 +56,15 @@ impl<'a, 'tcx> Visitor<'tcx> for PtrCloneVisitor<'a, 'tcx> {
         if self.abort {
             return;
         }
-        if let ExprKind::MethodCall(seg, _, args, _) = expr.kind {
-            if args.len() == 1 && match_var(&args[0], self.name) {
+        if let ExprKind::MethodCall(seg, _, [recv], _) = expr.kind {
+            if path_to_local_id(recv, self.id) {
                 if seg.ident.name.as_str() == "capacity" {
                     self.abort = true;
                     return;
                 }
                 for &(fn_name, suffix) in self.replace {
                     if seg.ident.name.as_str() == fn_name {
-                        self.spans
-                            .push((expr.span, snippet(self.cx, args[0].span, "_") + suffix));
+                        self.spans.push((expr.span, snippet(self.cx, recv.span, "_") + suffix));
                         return;
                     }
                 }
@@ -77,7 +77,3 @@ impl<'a, 'tcx> Visitor<'tcx> for PtrCloneVisitor<'a, 'tcx> {
         NestedVisitorMap::None
     }
 }
-
-fn get_binding_name(arg: &Param<'_>) -> Option<Symbol> {
-    get_pat_name(arg.pat)
-}
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index a92d3be5d3c..2808fc35e2a 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -128,7 +128,9 @@ pub fn implements_trait<'tcx>(
         return false;
     }
     let ty_params = cx.tcx.mk_substs(ty_params.iter());
-    cx.tcx.type_implements_trait((trait_id, ty, ty_params, cx.param_env))
+    cx.tcx
+        .type_implements_trait((trait_id, ty, ty_params, cx.param_env))
+        .must_apply_modulo_regions()
 }
 
 /// Checks whether this type implements `Drop`.
diff --git a/src/tools/clippy/doc/basics.md b/src/tools/clippy/doc/basics.md
index ed3a2fff83f..e98354358af 100644
--- a/src/tools/clippy/doc/basics.md
+++ b/src/tools/clippy/doc/basics.md
@@ -90,8 +90,10 @@ cargo dev fmt
 cargo dev update_lints
 # create a new lint and register it
 cargo dev new_lint
+# automatically formatting all code before each commit
+cargo dev setup git-hook
 # (experimental) Setup Clippy to work with IntelliJ-Rust
-cargo dev ide_setup
+cargo dev setup intellij
 ```
 
 ## lintcheck
diff --git a/src/tools/clippy/doc/common_tools_writing_lints.md b/src/tools/clippy/doc/common_tools_writing_lints.md
index abac1227b4f..0a85f650011 100644
--- a/src/tools/clippy/doc/common_tools_writing_lints.md
+++ b/src/tools/clippy/doc/common_tools_writing_lints.md
@@ -6,7 +6,7 @@ You may need following tooltips to catch up with common operations.
   - [Retrieving the type of an expression](#retrieving-the-type-of-an-expression)
   - [Checking if an expression is calling a specific method](#checking-if-an-expr-is-calling-a-specific-method)
   - [Checking if a type implements a specific trait](#checking-if-a-type-implements-a-specific-trait)
-  - [Checking if a type defines a method](#checking-if-a-type-defines-a-method)
+  - [Checking if a type defines a specific method](#checking-if-a-type-defines-a-specific-method)
   - [Dealing with macros](#dealing-with-macros)
 
 Useful Rustc dev guide links:
diff --git a/src/tools/clippy/doc/release.md b/src/tools/clippy/doc/release.md
index e0af9bf0625..afe3033c288 100644
--- a/src/tools/clippy/doc/release.md
+++ b/src/tools/clippy/doc/release.md
@@ -101,6 +101,21 @@ After this, the release should be available on the Clippy [release page].
 
 [release page]: https://github.com/rust-lang/rust-clippy/releases
 
+## Update the `stable` branch
+
+At this step you should have already checked out the commit of the `rust-1.XX.0`
+tag. Updating the stable branch from here is as easy as:
+
+```bash
+# Assuming the current directory corresponds to the Clippy repository and the
+# commit of the just created rust-1.XX.0 tag is checked out.
+$ git push upstream rust-1.XX.0:stable  # `upstream` is the `rust-lang/rust-clippy` remote
+```
+
+_NOTE: Usually there are no stable backports for Clippy, so this update should
+be possible without force pushing or anything like this. If there should have
+happened a stable backport, make sure to re-merge those changes just as with the
+`beta` branch._
 
 ## Update `CHANGELOG.md`
 
diff --git a/src/tools/clippy/lintcheck/README.md b/src/tools/clippy/lintcheck/README.md
index a61070d8a80..8c169506e53 100644
--- a/src/tools/clippy/lintcheck/README.md
+++ b/src/tools/clippy/lintcheck/README.md
@@ -69,7 +69,7 @@ is checked.
 is explicitly specified in the options.
 
 ### Fix mode
-You can run `./lintcheck/target/debug/lintcheck --fix` which will run Clippy with `-Zunstable-options --fix` and
+You can run `./lintcheck/target/debug/lintcheck --fix` which will run Clippy with `--fix` and
 print a warning if Clippys suggestions fail to apply (if the resulting code does not build).  
 This lets us spot bad suggestions or false positives automatically in some cases.  
 
diff --git a/src/tools/clippy/lintcheck/src/main.rs b/src/tools/clippy/lintcheck/src/main.rs
index f6a75595c98..7d2f3173fb0 100644
--- a/src/tools/clippy/lintcheck/src/main.rs
+++ b/src/tools/clippy/lintcheck/src/main.rs
@@ -260,14 +260,7 @@ impl Crate {
         let shared_target_dir = clippy_project_root().join("target/lintcheck/shared_target_dir");
 
         let mut args = if fix {
-            vec![
-                "-Zunstable-options",
-                "--fix",
-                "-Zunstable-options",
-                "--allow-no-vcs",
-                "--",
-                "--cap-lints=warn",
-            ]
+            vec!["--fix", "--allow-no-vcs", "--", "--cap-lints=warn"]
         } else {
             vec!["--", "--message-format=json", "--", "--cap-lints=warn"]
         };
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index e3863c46288..2d3c65c1d39 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-06-03"
+channel = "nightly-2021-07-01"
 components = ["llvm-tools-preview", "rustc-dev", "rust-src"]
diff --git a/src/tools/clippy/src/main.rs b/src/tools/clippy/src/main.rs
index 7bb80b1196e..6bd4123ddeb 100644
--- a/src/tools/clippy/src/main.rs
+++ b/src/tools/clippy/src/main.rs
@@ -70,7 +70,6 @@ impl ClippyCmd {
         I: Iterator<Item = String>,
     {
         let mut cargo_subcommand = "check";
-        let mut unstable_options = false;
         let mut args = vec![];
 
         for arg in old_args.by_ref() {
@@ -80,18 +79,12 @@ impl ClippyCmd {
                     continue;
                 },
                 "--" => break,
-                // Cover -Zunstable-options and -Z unstable-options
-                s if s.ends_with("unstable-options") => unstable_options = true,
                 _ => {},
             }
 
             args.push(arg);
         }
 
-        if cargo_subcommand == "fix" && !unstable_options {
-            panic!("Usage of `--fix` requires `-Z unstable-options`");
-        }
-
         let mut clippy_args: Vec<String> = old_args.collect();
         if cargo_subcommand == "fix" && !clippy_args.iter().any(|arg| arg == "--no-deps") {
             clippy_args.push("--no-deps".into());
@@ -176,34 +169,23 @@ mod tests {
     use super::ClippyCmd;
 
     #[test]
-    #[should_panic]
-    fn fix_without_unstable() {
+    fn fix() {
         let args = "cargo clippy --fix".split_whitespace().map(ToString::to_string);
-        ClippyCmd::new(args);
-    }
-
-    #[test]
-    fn fix_unstable() {
-        let args = "cargo clippy --fix -Zunstable-options"
-            .split_whitespace()
-            .map(ToString::to_string);
         let cmd = ClippyCmd::new(args);
         assert_eq!("fix", cmd.cargo_subcommand);
-        assert!(cmd.args.iter().any(|arg| arg.ends_with("unstable-options")));
+        assert!(!cmd.args.iter().any(|arg| arg.ends_with("unstable-options")));
     }
 
     #[test]
     fn fix_implies_no_deps() {
-        let args = "cargo clippy --fix -Zunstable-options"
-            .split_whitespace()
-            .map(ToString::to_string);
+        let args = "cargo clippy --fix".split_whitespace().map(ToString::to_string);
         let cmd = ClippyCmd::new(args);
         assert!(cmd.clippy_args.iter().any(|arg| arg == "--no-deps"));
     }
 
     #[test]
     fn no_deps_not_duplicated_with_fix() {
-        let args = "cargo clippy --fix -Zunstable-options -- --no-deps"
+        let args = "cargo clippy --fix -- --no-deps"
             .split_whitespace()
             .map(ToString::to_string);
         let cmd = ClippyCmd::new(args);
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index 7d266a36bb6..caa19e39ccd 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -48,7 +48,24 @@ fn third_party_crates() -> String {
                     && name.rsplit('.').next().map(|ext| ext.eq_ignore_ascii_case("rlib")) == Some(true)
                 {
                     if let Some(old) = crates.insert(dep, path.clone()) {
-                        panic!("Found multiple rlibs for crate `{}`: `{:?}` and `{:?}", dep, old, path);
+                        // Check which action should be done in order to remove compiled deps.
+                        // If pre-installed version of compiler is used, `cargo clean` will do.
+                        // Otherwise (for bootstrapped compiler), the dependencies directory
+                        // must be removed manually.
+                        let suggested_action = if std::env::var_os("RUSTC_BOOTSTRAP").is_some() {
+                            "remove the stageN-tools directory"
+                        } else {
+                            "run `cargo clean`"
+                        };
+
+                        panic!(
+                            "\n---------------------------------------------------\n\n \
+                            Found multiple rlibs for crate `{}`: `{:?}` and `{:?}`.\n \
+                            Probably, you need to {} before running tests again.\n \
+                            \nFor details on that error see https://github.com/rust-lang/rust-clippy/issues/7343 \
+                            \n---------------------------------------------------\n",
+                            dep, old, path, suggested_action
+                        );
                     }
                     break;
                 }
diff --git a/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/clippy.toml b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/clippy.toml
new file mode 100644
index 00000000000..05ba822874d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/clippy.toml
@@ -0,0 +1,10 @@
+enforced-import-renames = [
+    { path = "std::option::Option", rename = "Maybe" },
+    { path = "std::process::Child", rename = "Kid" },
+    { path = "std::process::exit", rename = "goodbye" },
+    { path = "std::collections::BTreeMap", rename = "Map" },
+    { path = "std::clone", rename = "foo" },
+    { path = "std::thread::sleep", rename = "thread_sleep" },
+    { path = "std::any::type_name", rename = "ident" },
+    { path = "std::sync::Mutex", rename = "StdMutie" }
+]
diff --git a/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs
new file mode 100644
index 00000000000..f60058c8628
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs
@@ -0,0 +1,16 @@
+#![warn(clippy::missing_enforced_import_renames)]
+
+use std::alloc as colla;
+use std::option::Option as Maybe;
+use std::process::{exit as wrong_exit, Child as Kid};
+use std::thread::sleep;
+#[rustfmt::skip]
+use std::{
+    any::{type_name, Any},
+    clone,
+    sync :: Mutex,
+};
+
+fn main() {
+    use std::collections::BTreeMap as OopsWrongRename;
+}
diff --git a/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr
new file mode 100644
index 00000000000..45de8fdffef
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr
@@ -0,0 +1,40 @@
+error: this import should be renamed
+  --> $DIR/conf_missing_enforced_import_rename.rs:5:20
+   |
+LL | use std::process::{exit as wrong_exit, Child as Kid};
+   |                    ^^^^^^^^^^^^^^^^^^ help: try: `exit as goodbye`
+   |
+   = note: `-D clippy::missing-enforced-import-renames` implied by `-D warnings`
+
+error: this import should be renamed
+  --> $DIR/conf_missing_enforced_import_rename.rs:6:1
+   |
+LL | use std::thread::sleep;
+   | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `use std::thread::sleep as thread_sleep`
+
+error: this import should be renamed
+  --> $DIR/conf_missing_enforced_import_rename.rs:9:11
+   |
+LL |     any::{type_name, Any},
+   |           ^^^^^^^^^ help: try: `type_name as ident`
+
+error: this import should be renamed
+  --> $DIR/conf_missing_enforced_import_rename.rs:10:5
+   |
+LL |     clone,
+   |     ^^^^^ help: try: `clone as foo`
+
+error: this import should be renamed
+  --> $DIR/conf_missing_enforced_import_rename.rs:11:5
+   |
+LL |     sync :: Mutex,
+   |     ^^^^^^^^^^^^^ help: try: `sync :: Mutex as StdMutie`
+
+error: this import should be renamed
+  --> $DIR/conf_missing_enforced_import_rename.rs:15:5
+   |
+LL |     use std::collections::BTreeMap as OopsWrongRename;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `use std::collections::BTreeMap as Map`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/clippy.toml b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/clippy.toml
new file mode 100644
index 00000000000..bced8948a02
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/clippy.toml
@@ -0,0 +1,6 @@
+standard-macro-braces = [
+    { name = "quote", brace = "{" },
+    { name = "quote::quote", brace = "{" },
+    { name = "eprint", brace = "[" },
+    { name = "type_pos", brace = "[" },
+]
diff --git a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs
new file mode 100644
index 00000000000..4ae6864cbb0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs
@@ -0,0 +1,44 @@
+// #![warn(clippy::nonstandard_macro_braces)]
+
+extern crate quote;
+
+use quote::quote;
+
+#[rustfmt::skip]
+macro_rules! test {
+    () => {
+        vec!{0, 0, 0}
+    };
+}
+
+#[rustfmt::skip]
+macro_rules! test2 {
+    ($($arg:tt)*) => {
+        format_args!($($arg)*)
+    };
+}
+
+macro_rules! type_pos {
+    ($what:ty) => {
+        Vec<$what>
+    };
+}
+
+#[rustfmt::skip]
+fn main() {
+    let _ = vec! {1, 2, 3};
+    let _ = format!["ugh {} stop being such a good compiler", "hello"];
+    let _ = quote!(let x = 1;);
+    let _ = quote::quote!(match match match);
+    let _ = test!();
+    let _ = vec![1,2,3];
+
+    let _ = quote::quote! {true || false};
+    let _ = vec! [0 ,0 ,0];
+    let _ = format!("fds{}fds", 10);
+    let _ = test2!["{}{}{}", 1, 2, 3];
+
+    let _: type_pos!(usize) = vec![];
+
+    eprint!("test if user config overrides defaults");
+}
diff --git a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr
new file mode 100644
index 00000000000..7bcd1829524
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr
@@ -0,0 +1,94 @@
+error: use of irregular braces for `vec!` macro
+  --> $DIR/conf_nonstandard_macro_braces.rs:29:13
+   |
+LL |     let _ = vec! {1, 2, 3};
+   |             ^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::nonstandard-macro-braces` implied by `-D warnings`
+help: consider writing `vec![1, 2, 3]`
+  --> $DIR/conf_nonstandard_macro_braces.rs:29:13
+   |
+LL |     let _ = vec! {1, 2, 3};
+   |             ^^^^^^^^^^^^^^
+
+error: use of irregular braces for `format!` macro
+  --> $DIR/conf_nonstandard_macro_braces.rs:30:13
+   |
+LL |     let _ = format!["ugh {} stop being such a good compiler", "hello"];
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider writing `format!("ugh () stop being such a good compiler", "hello")`
+  --> $DIR/conf_nonstandard_macro_braces.rs:30:13
+   |
+LL |     let _ = format!["ugh {} stop being such a good compiler", "hello"];
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: use of irregular braces for `quote!` macro
+  --> $DIR/conf_nonstandard_macro_braces.rs:31:13
+   |
+LL |     let _ = quote!(let x = 1;);
+   |             ^^^^^^^^^^^^^^^^^^
+   |
+help: consider writing `quote! {let x = 1;}`
+  --> $DIR/conf_nonstandard_macro_braces.rs:31:13
+   |
+LL |     let _ = quote!(let x = 1;);
+   |             ^^^^^^^^^^^^^^^^^^
+
+error: use of irregular braces for `quote::quote!` macro
+  --> $DIR/conf_nonstandard_macro_braces.rs:32:13
+   |
+LL |     let _ = quote::quote!(match match match);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider writing `quote::quote! {match match match}`
+  --> $DIR/conf_nonstandard_macro_braces.rs:32:13
+   |
+LL |     let _ = quote::quote!(match match match);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: use of irregular braces for `vec!` macro
+  --> $DIR/conf_nonstandard_macro_braces.rs:10:9
+   |
+LL |         vec!{0, 0, 0}
+   |         ^^^^^^^^^^^^^
+...
+LL |     let _ = test!();
+   |             ------- in this macro invocation
+   |
+help: consider writing `vec![0, 0, 0]`
+  --> $DIR/conf_nonstandard_macro_braces.rs:10:9
+   |
+LL |         vec!{0, 0, 0}
+   |         ^^^^^^^^^^^^^
+...
+LL |     let _ = test!();
+   |             ------- in this macro invocation
+   = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: use of irregular braces for `type_pos!` macro
+  --> $DIR/conf_nonstandard_macro_braces.rs:41:12
+   |
+LL |     let _: type_pos!(usize) = vec![];
+   |            ^^^^^^^^^^^^^^^^
+   |
+help: consider writing `type_pos![usize]`
+  --> $DIR/conf_nonstandard_macro_braces.rs:41:12
+   |
+LL |     let _: type_pos!(usize) = vec![];
+   |            ^^^^^^^^^^^^^^^^
+
+error: use of irregular braces for `eprint!` macro
+  --> $DIR/conf_nonstandard_macro_braces.rs:43:5
+   |
+LL |     eprint!("test if user config overrides defaults");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider writing `eprint!["test if user config overrides defaults"];`
+  --> $DIR/conf_nonstandard_macro_braces.rs:43:5
+   |
+LL |     eprint!("test if user config overrides defaults");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/toml_disallowed_method/clippy.toml b/src/tools/clippy/tests/ui-toml/toml_disallowed_method/clippy.toml
index c0df3b6e8af..a3245da6825 100644
--- a/src/tools/clippy/tests/ui-toml/toml_disallowed_method/clippy.toml
+++ b/src/tools/clippy/tests/ui-toml/toml_disallowed_method/clippy.toml
@@ -1 +1,5 @@
-disallowed-methods = ["core::iter::traits::iterator::Iterator::sum", "regex::re_unicode::Regex::is_match", "regex::re_unicode::Regex::new"]
+disallowed-methods = [
+    "std::iter::Iterator::sum",
+    "regex::Regex::is_match",
+    "regex::Regex::new"
+]
diff --git a/src/tools/clippy/tests/ui-toml/toml_disallowed_type/clippy.toml b/src/tools/clippy/tests/ui-toml/toml_disallowed_type/clippy.toml
new file mode 100644
index 00000000000..2eff854c22c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/toml_disallowed_type/clippy.toml
@@ -0,0 +1,9 @@
+disallowed-types = [
+    "std::collections::HashMap",
+    "std::sync::atomic::AtomicU32",
+    "syn::TypePath",
+    "proc_macro2::Ident",
+    "std::thread::Thread",
+    "std::time::Instant",
+    "std::io::Read",
+]
diff --git a/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.rs b/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.rs
new file mode 100644
index 00000000000..567afb5aec1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.rs
@@ -0,0 +1,35 @@
+#![warn(clippy::disallowed_type)]
+
+extern crate quote;
+extern crate syn;
+
+use std::sync as foo;
+use std::sync::atomic::AtomicU32;
+use std::time::Instant as Sneaky;
+
+struct HashMap;
+
+fn bad_return_type() -> fn() -> Sneaky {
+    todo!()
+}
+
+fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {
+    todo!()
+}
+
+fn trait_obj(_: &dyn std::io::Read) {
+    todo!()
+}
+
+static BAD: foo::atomic::AtomicPtr<()> = foo::atomic::AtomicPtr::new(std::ptr::null_mut());
+
+#[allow(clippy::diverging_sub_expression)]
+fn main() {
+    let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new();
+    let _ = Sneaky::now();
+    let _ = foo::atomic::AtomicU32::new(0);
+    static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1);
+    let _: std::collections::BTreeMap<(), syn::TypePath> = Default::default();
+    let _ = syn::Ident::new("", todo!());
+    let _ = HashMap;
+}
diff --git a/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.stderr b/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.stderr
new file mode 100644
index 00000000000..4e6fd91fba1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/toml_disallowed_type/conf_disallowed_type.stderr
@@ -0,0 +1,88 @@
+error: `std::sync::atomic::AtomicU32` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:7:1
+   |
+LL | use std::sync::atomic::AtomicU32;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::disallowed-type` implied by `-D warnings`
+
+error: `std::time::Instant` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:8:1
+   |
+LL | use std::time::Instant as Sneaky;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `std::time::Instant` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:12:33
+   |
+LL | fn bad_return_type() -> fn() -> Sneaky {
+   |                                 ^^^^^^
+
+error: `std::time::Instant` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:16:28
+   |
+LL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {
+   |                            ^^^^^^
+
+error: `std::sync::atomic::AtomicU32` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:16:39
+   |
+LL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^
+
+error: `std::io::Read` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:20:22
+   |
+LL | fn trait_obj(_: &dyn std::io::Read) {
+   |                      ^^^^^^^^^^^^^
+
+error: `std::collections::HashMap` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:28:48
+   |
+LL |     let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new();
+   |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `std::collections::HashMap` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:28:12
+   |
+LL |     let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new();
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `std::time::Instant` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:29:13
+   |
+LL |     let _ = Sneaky::now();
+   |             ^^^^^^
+
+error: `std::sync::atomic::AtomicU32` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:30:13
+   |
+LL |     let _ = foo::atomic::AtomicU32::new(0);
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: `std::sync::atomic::AtomicU32` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:31:17
+   |
+LL |     static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1);
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `std::sync::atomic::AtomicU32` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:31:48
+   |
+LL |     static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1);
+   |                                                ^^^^^^^^^^^^^^^^^^^^^^
+
+error: `syn::TypePath` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:32:43
+   |
+LL |     let _: std::collections::BTreeMap<(), syn::TypePath> = Default::default();
+   |                                           ^^^^^^^^^^^^^
+
+error: `proc_macro2::Ident` is not allowed according to config
+  --> $DIR/conf_disallowed_type.rs:33:13
+   |
+LL |     let _ = syn::Ident::new("", todo!());
+   |             ^^^^^^^^^^
+
+error: aborting due to 14 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index a7be00426c4..e0029ebeb27 100644
--- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -1,4 +1,4 @@
-error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `third-party` at line 5 column 1
+error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `disallowed-types`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `standard-macro-braces`, `enforced-import-renames`, `allowed-scripts`, `third-party` at line 5 column 1
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/append_instead_of_extend.fixed b/src/tools/clippy/tests/ui/append_instead_of_extend.fixed
new file mode 100644
index 00000000000..283358333cd
--- /dev/null
+++ b/src/tools/clippy/tests/ui/append_instead_of_extend.fixed
@@ -0,0 +1,55 @@
+// run-rustfix
+#![warn(clippy::append_instead_of_extend)]
+use std::collections::BinaryHeap;
+fn main() {
+    //gets linted
+    let mut vec1 = vec![0u8; 1024];
+    let mut vec2: std::vec::Vec<u8> = Vec::new();
+
+    vec2.append(&mut vec1);
+
+    let mut vec3 = vec![0u8; 1024];
+    let mut vec4: std::vec::Vec<u8> = Vec::new();
+
+    vec4.append(&mut vec3);
+
+    let mut vec11: std::vec::Vec<u8> = Vec::new();
+
+    vec11.append(&mut return_vector());
+
+    //won't get linted it dosen't move the entire content of a vec into another
+    let mut test1 = vec![0u8, 10];
+    let mut test2: std::vec::Vec<u8> = Vec::new();
+
+    test2.extend(test1.drain(4..10));
+
+    let mut vec3 = vec![0u8; 104];
+    let mut vec7: std::vec::Vec<u8> = Vec::new();
+
+    vec3.append(&mut vec7);
+
+    let mut vec5 = vec![0u8; 1024];
+    let mut vec6: std::vec::Vec<u8> = Vec::new();
+
+    vec5.extend(vec6.drain(..4));
+
+    let mut vec9: std::vec::Vec<u8> = Vec::new();
+
+    return_vector().append(&mut vec9);
+
+    //won't get linted because it is not a vec
+
+    let mut heap = BinaryHeap::from(vec![1, 3]);
+    let mut heap2 = BinaryHeap::from(vec![]);
+    heap2.extend(heap.drain())
+}
+
+fn return_vector() -> Vec<u8> {
+    let mut new_vector = vec![];
+
+    for i in 1..10 {
+        new_vector.push(i)
+    }
+
+    new_vector
+}
diff --git a/src/tools/clippy/tests/ui/append_instead_of_extend.rs b/src/tools/clippy/tests/ui/append_instead_of_extend.rs
new file mode 100644
index 00000000000..abde5cdac5c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/append_instead_of_extend.rs
@@ -0,0 +1,55 @@
+// run-rustfix
+#![warn(clippy::append_instead_of_extend)]
+use std::collections::BinaryHeap;
+fn main() {
+    //gets linted
+    let mut vec1 = vec![0u8; 1024];
+    let mut vec2: std::vec::Vec<u8> = Vec::new();
+
+    vec2.extend(vec1.drain(..));
+
+    let mut vec3 = vec![0u8; 1024];
+    let mut vec4: std::vec::Vec<u8> = Vec::new();
+
+    vec4.extend(vec3.drain(..));
+
+    let mut vec11: std::vec::Vec<u8> = Vec::new();
+
+    vec11.extend(return_vector().drain(..));
+
+    //won't get linted it dosen't move the entire content of a vec into another
+    let mut test1 = vec![0u8, 10];
+    let mut test2: std::vec::Vec<u8> = Vec::new();
+
+    test2.extend(test1.drain(4..10));
+
+    let mut vec3 = vec![0u8; 104];
+    let mut vec7: std::vec::Vec<u8> = Vec::new();
+
+    vec3.append(&mut vec7);
+
+    let mut vec5 = vec![0u8; 1024];
+    let mut vec6: std::vec::Vec<u8> = Vec::new();
+
+    vec5.extend(vec6.drain(..4));
+
+    let mut vec9: std::vec::Vec<u8> = Vec::new();
+
+    return_vector().append(&mut vec9);
+
+    //won't get linted because it is not a vec
+
+    let mut heap = BinaryHeap::from(vec![1, 3]);
+    let mut heap2 = BinaryHeap::from(vec![]);
+    heap2.extend(heap.drain())
+}
+
+fn return_vector() -> Vec<u8> {
+    let mut new_vector = vec![];
+
+    for i in 1..10 {
+        new_vector.push(i)
+    }
+
+    new_vector
+}
diff --git a/src/tools/clippy/tests/ui/append_instead_of_extend.stderr b/src/tools/clippy/tests/ui/append_instead_of_extend.stderr
new file mode 100644
index 00000000000..9d309d981de
--- /dev/null
+++ b/src/tools/clippy/tests/ui/append_instead_of_extend.stderr
@@ -0,0 +1,22 @@
+error: use of `extend` instead of `append` for adding the full range of a second vector
+  --> $DIR/append_instead_of_extend.rs:9:5
+   |
+LL |     vec2.extend(vec1.drain(..));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec2.append(&mut vec1)`
+   |
+   = note: `-D clippy::append-instead-of-extend` implied by `-D warnings`
+
+error: use of `extend` instead of `append` for adding the full range of a second vector
+  --> $DIR/append_instead_of_extend.rs:14:5
+   |
+LL |     vec4.extend(vec3.drain(..));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec4.append(&mut vec3)`
+
+error: use of `extend` instead of `append` for adding the full range of a second vector
+  --> $DIR/append_instead_of_extend.rs:18:5
+   |
+LL |     vec11.extend(return_vector().drain(..));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec11.append(&mut return_vector())`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/assertions_on_constants.rs b/src/tools/clippy/tests/ui/assertions_on_constants.rs
index e989de65404..6617ca183a8 100644
--- a/src/tools/clippy/tests/ui/assertions_on_constants.rs
+++ b/src/tools/clippy/tests/ui/assertions_on_constants.rs
@@ -28,4 +28,7 @@ fn main() {
     debug_assert!(false); // #3948
     assert_const!(3);
     assert_const!(-1);
+
+    // Don't lint on this:
+    assert!(cfg!(feature = "hey") || cfg!(not(feature = "asdf")));
 }
diff --git a/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs b/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs
index d4470d3f407..170955e726c 100644
--- a/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs
@@ -106,3 +106,10 @@ macro_rules! field_reassign_with_default {
         }
     };
 }
+
+#[macro_export]
+macro_rules! default_numeric_fallback {
+    () => {
+        let x = 22;
+    };
+}
diff --git a/src/tools/clippy/tests/ui/auxiliary/non-exhaustive-enum.rs b/src/tools/clippy/tests/ui/auxiliary/non-exhaustive-enum.rs
new file mode 100644
index 00000000000..420232f9f8d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/auxiliary/non-exhaustive-enum.rs
@@ -0,0 +1,8 @@
+// Stripped down version of the ErrorKind enum of std
+#[non_exhaustive]
+pub enum ErrorKind {
+    NotFound,
+    PermissionDenied,
+    #[doc(hidden)]
+    Uncategorized,
+}
diff --git a/src/tools/clippy/tests/ui/blacklisted_name.rs b/src/tools/clippy/tests/ui/blacklisted_name.rs
index cb15bdd2f1b..57d7139fef5 100644
--- a/src/tools/clippy/tests/ui/blacklisted_name.rs
+++ b/src/tools/clippy/tests/ui/blacklisted_name.rs
@@ -43,3 +43,15 @@ fn issue_1647_ref_mut() {
     let ref mut baz = 0;
     if let Some(ref mut quux) = Some(42) {}
 }
+
+mod tests {
+    fn issue_7305() {
+        // `blackisted_name` lint should not be triggered inside of the test code.
+        let foo = 0;
+
+        // Check that even in nested functions warning is still not triggere.
+        fn nested() {
+            let foo = 0;
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3969.stderr b/src/tools/clippy/tests/ui/crashes/ice-3969.stderr
index fb4589a48ec..8b2c318acf8 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3969.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-3969.stderr
@@ -5,7 +5,7 @@ LL |     for<'a> Dst<A + 'a>: Sized,
    |                 ^^^^^^ help: use `dyn`: `dyn A + 'a`
    |
    = note: `-D bare-trait-objects` implied by `-D warnings`
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: trait objects without an explicit `dyn` are deprecated
@@ -14,7 +14,7 @@ error: trait objects without an explicit `dyn` are deprecated
 LL |     let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
    |                ^ help: use `dyn`: `dyn A`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: trait objects without an explicit `dyn` are deprecated
@@ -23,7 +23,7 @@ error: trait objects without an explicit `dyn` are deprecated
 LL |     let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
    |                                                         ^ help: use `dyn`: `dyn A`
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
 
 error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback.rs b/src/tools/clippy/tests/ui/default_numeric_fallback.rs
index 43468872db0..c0625fd1b75 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback.rs
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback.rs
@@ -1,3 +1,5 @@
+// aux-build:macro_rules.rs
+
 #![warn(clippy::default_numeric_fallback)]
 #![allow(unused)]
 #![allow(clippy::never_loop)]
@@ -5,6 +7,9 @@
 #![allow(clippy::unnecessary_operation)]
 #![allow(clippy::branches_sharing_code)]
 
+#[macro_use]
+extern crate macro_rules;
+
 mod basic_expr {
     fn test() {
         // Should lint unsuffixed literals typed `i32`.
@@ -133,4 +138,22 @@ mod method_calls {
     }
 }
 
+mod in_macro {
+    macro_rules! internal_macro {
+        () => {
+            let x = 22;
+        };
+    }
+
+    // Should lint in internal macro.
+    fn internal() {
+        internal_macro!();
+    }
+
+    // Should NOT lint in external macro.
+    fn external() {
+        default_numeric_fallback!();
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback.stderr b/src/tools/clippy/tests/ui/default_numeric_fallback.stderr
index d1c4c8203dd..5862cd936ac 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback.stderr
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback.stderr
@@ -1,5 +1,5 @@
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:11:17
+  --> $DIR/default_numeric_fallback.rs:16:17
    |
 LL |         let x = 22;
    |                 ^^ help: consider adding suffix: `22_i32`
@@ -7,142 +7,153 @@ LL |         let x = 22;
    = note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:12:18
+  --> $DIR/default_numeric_fallback.rs:17:18
    |
 LL |         let x = [1, 2, 3];
    |                  ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:12:21
+  --> $DIR/default_numeric_fallback.rs:17:21
    |
 LL |         let x = [1, 2, 3];
    |                     ^ help: consider adding suffix: `2_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:12:24
+  --> $DIR/default_numeric_fallback.rs:17:24
    |
 LL |         let x = [1, 2, 3];
    |                        ^ help: consider adding suffix: `3_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:13:28
+  --> $DIR/default_numeric_fallback.rs:18:28
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                            ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:13:31
+  --> $DIR/default_numeric_fallback.rs:18:31
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                               ^ help: consider adding suffix: `2_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:13:44
+  --> $DIR/default_numeric_fallback.rs:18:44
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                                            ^ help: consider adding suffix: `3_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:13:47
+  --> $DIR/default_numeric_fallback.rs:18:47
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                                               ^ help: consider adding suffix: `4_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:14:23
+  --> $DIR/default_numeric_fallback.rs:19:23
    |
 LL |         let x = match 1 {
    |                       ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:15:13
+  --> $DIR/default_numeric_fallback.rs:20:13
    |
 LL |             1 => 1,
    |             ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:15:18
+  --> $DIR/default_numeric_fallback.rs:20:18
    |
 LL |             1 => 1,
    |                  ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:16:18
+  --> $DIR/default_numeric_fallback.rs:21:18
    |
 LL |             _ => 2,
    |                  ^ help: consider adding suffix: `2_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:20:17
+  --> $DIR/default_numeric_fallback.rs:25:17
    |
 LL |         let x = 0.12;
    |                 ^^^^ help: consider adding suffix: `0.12_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:38:21
+  --> $DIR/default_numeric_fallback.rs:43:21
    |
 LL |             let y = 1;
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:46:21
+  --> $DIR/default_numeric_fallback.rs:51:21
    |
 LL |             let y = 1;
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:52:21
+  --> $DIR/default_numeric_fallback.rs:57:21
    |
 LL |             let y = 1;
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:64:9
+  --> $DIR/default_numeric_fallback.rs:69:9
    |
 LL |         1
    |         ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:70:27
+  --> $DIR/default_numeric_fallback.rs:75:27
    |
 LL |         let f = || -> _ { 1 };
    |                           ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:74:29
+  --> $DIR/default_numeric_fallback.rs:79:29
    |
 LL |         let f = || -> i32 { 1 };
    |                             ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:88:21
+  --> $DIR/default_numeric_fallback.rs:93:21
    |
 LL |         generic_arg(1);
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:91:32
+  --> $DIR/default_numeric_fallback.rs:96:32
    |
 LL |         let x: _ = generic_arg(1);
    |                                ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:109:28
+  --> $DIR/default_numeric_fallback.rs:114:28
    |
 LL |         GenericStruct { x: 1 };
    |                            ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:112:36
+  --> $DIR/default_numeric_fallback.rs:117:36
    |
 LL |         let _ = GenericStruct { x: 1 };
    |                                    ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:132:23
+  --> $DIR/default_numeric_fallback.rs:137:23
    |
 LL |         s.generic_arg(1);
    |                       ^ help: consider adding suffix: `1_i32`
 
-error: aborting due to 24 previous errors
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback.rs:144:21
+   |
+LL |             let x = 22;
+   |                     ^^ help: consider adding suffix: `22_i32`
+...
+LL |         internal_macro!();
+   |         ------------------ in this macro invocation
+   |
+   = note: this error originates in the macro `internal_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 25 previous errors
 
diff --git a/src/tools/clippy/tests/ui/deprecated.stderr b/src/tools/clippy/tests/ui/deprecated.stderr
index 03c9f438891..0af6b500115 100644
--- a/src/tools/clippy/tests/ui/deprecated.stderr
+++ b/src/tools/clippy/tests/ui/deprecated.stderr
@@ -84,13 +84,13 @@ error: lint `clippy::filter_map` has been removed: this lint has been replaced b
 LL | #[warn(clippy::filter_map)]
    |        ^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::pub_enum_variant_names` has been removed: set the `avoid_breaking_exported_api` config option to `false` to enable the `enum_variant_names` lint for public items
+error: lint `clippy::pub_enum_variant_names` has been removed: set the `avoid-breaking-exported-api` config option to `false` to enable the `enum_variant_names` lint for public items
   --> $DIR/deprecated.rs:15:8
    |
 LL | #[warn(clippy::pub_enum_variant_names)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::wrong_pub_self_convention` has been removed: set the `avoid_breaking_exported_api` config option to `false` to enable the `wrong_self_convention` lint for public items
+error: lint `clippy::wrong_pub_self_convention` has been removed: set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items
   --> $DIR/deprecated.rs:16:8
    |
 LL | #[warn(clippy::wrong_pub_self_convention)]
diff --git a/src/tools/clippy/tests/ui/disallowed_script_idents.rs b/src/tools/clippy/tests/ui/disallowed_script_idents.rs
new file mode 100644
index 00000000000..cfdda35971f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/disallowed_script_idents.rs
@@ -0,0 +1,10 @@
+#![deny(clippy::disallowed_script_idents)]
+#![allow(dead_code)]
+
+fn main() {
+    let counter = 10; // OK, latin is allowed.
+    let zähler = 10; // OK, it's still latin.
+
+    let счётчик = 10; // Cyrillic is not allowed by default.
+    let カウンタ = 10; // Same for japanese.
+}
diff --git a/src/tools/clippy/tests/ui/disallowed_script_idents.stderr b/src/tools/clippy/tests/ui/disallowed_script_idents.stderr
new file mode 100644
index 00000000000..cc84dc1d43c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/disallowed_script_idents.stderr
@@ -0,0 +1,20 @@
+error: identifier `счётчик` has a Unicode script that is not allowed by configuration: Cyrillic
+  --> $DIR/disallowed_script_idents.rs:8:9
+   |
+LL |     let счётчик = 10; // Cyrillic is not allowed by default.
+   |         ^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/disallowed_script_idents.rs:1:9
+   |
+LL | #![deny(clippy::disallowed_script_idents)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: identifier `カウンタ` has a Unicode script that is not allowed by configuration: Katakana
+  --> $DIR/disallowed_script_idents.rs:9:9
+   |
+LL |     let カウンタ = 10; // Same for japanese.
+   |         ^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/doc.rs b/src/tools/clippy/tests/ui/doc/doc.rs
index c946a047f1b..8afef6b23d4 100644
--- a/src/tools/clippy/tests/ui/doc.rs
+++ b/src/tools/clippy/tests/ui/doc/doc.rs
@@ -64,7 +64,7 @@ fn test_units() {
 /// WebGL
 /// TensorFlow
 /// TrueType
-/// iOS macOS
+/// iOS macOS FreeBSD
 /// TeX LaTeX BibTeX BibLaTeX
 /// MinGW
 /// CamelCase (see also #2395)
diff --git a/src/tools/clippy/tests/ui/doc.stderr b/src/tools/clippy/tests/ui/doc/doc.stderr
index 7eab8a85f09..7eab8a85f09 100644
--- a/src/tools/clippy/tests/ui/doc.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc.stderr
diff --git a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs
new file mode 100644
index 00000000000..78e87bc6906
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs
@@ -0,0 +1,36 @@
+//! This file tests for the `DOC_MARKDOWN` lint, specifically cases
+//! where ticks are unbalanced (see issue #6753).
+
+#![allow(dead_code)]
+#![warn(clippy::doc_markdown)]
+
+/// This is a doc comment with `unbalanced_tick marks and several words that
+/// should be `encompassed_by` tick marks because they `contain_underscores`.
+/// Because of the initial `unbalanced_tick` pair, the error message is
+/// very `confusing_and_misleading`.
+fn main() {}
+
+/// This paragraph has `unbalanced_tick marks and should stop_linting.
+///
+/// This paragraph is fine and should_be linted normally.
+///
+/// Double unbalanced backtick from ``here to here` should lint.
+///
+/// Double balanced back ticks ``start end`` is fine.
+fn multiple_paragraphs() {}
+
+/// ```
+/// // Unbalanced tick mark in code block shouldn't warn:
+/// `
+/// ```
+fn in_code_block() {}
+
+/// # `Fine`
+///
+/// ## not_fine
+///
+/// ### `unbalanced
+///
+/// - This `item has unbalanced tick marks
+/// - This item needs backticks_here
+fn other_markdown() {}
diff --git a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
new file mode 100644
index 00000000000..45ca34e2a8c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
@@ -0,0 +1,64 @@
+error: backticks are unbalanced
+  --> $DIR/unbalanced_ticks.rs:7:1
+   |
+LL | / /// This is a doc comment with `unbalanced_tick marks and several words that
+LL | | /// should be `encompassed_by` tick marks because they `contain_underscores`.
+LL | | /// Because of the initial `unbalanced_tick` pair, the error message is
+LL | | /// very `confusing_and_misleading`.
+   | |____________________________________^
+   |
+   = note: `-D clippy::doc-markdown` implied by `-D warnings`
+   = help: a backtick may be missing a pair
+
+error: backticks are unbalanced
+  --> $DIR/unbalanced_ticks.rs:13:1
+   |
+LL | /// This paragraph has `unbalanced_tick marks and should stop_linting.
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: a backtick may be missing a pair
+
+error: you should put `should_be` between ticks in the documentation
+  --> $DIR/unbalanced_ticks.rs:15:32
+   |
+LL | /// This paragraph is fine and should_be linted normally.
+   |                                ^^^^^^^^^
+
+error: backticks are unbalanced
+  --> $DIR/unbalanced_ticks.rs:17:1
+   |
+LL | /// Double unbalanced backtick from ``here to here` should lint.
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: a backtick may be missing a pair
+
+error: you should put `not_fine` between ticks in the documentation
+  --> $DIR/unbalanced_ticks.rs:30:8
+   |
+LL | /// ## not_fine
+   |        ^^^^^^^^
+
+error: backticks are unbalanced
+  --> $DIR/unbalanced_ticks.rs:32:1
+   |
+LL | /// ### `unbalanced
+   | ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: a backtick may be missing a pair
+
+error: backticks are unbalanced
+  --> $DIR/unbalanced_ticks.rs:34:1
+   |
+LL | /// - This `item has unbalanced tick marks
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: a backtick may be missing a pair
+
+error: you should put `backticks_here` between ticks in the documentation
+  --> $DIR/unbalanced_ticks.rs:35:23
+   |
+LL | /// - This item needs backticks_here
+   |                       ^^^^^^^^^^^^^^
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.rs b/src/tools/clippy/tests/ui/field_reassign_with_default.rs
index 1368c5d7984..787053fb000 100644
--- a/src/tools/clippy/tests/ui/field_reassign_with_default.rs
+++ b/src/tools/clippy/tests/ui/field_reassign_with_default.rs
@@ -29,6 +29,21 @@ struct C {
     i: Vec<i32>,
     j: i64,
 }
+
+#[derive(Default)]
+struct D {
+    a: Option<i32>,
+    b: Option<i32>,
+}
+
+macro_rules! m {
+    ($key:ident: $value:tt) => {{
+        let mut data = $crate::D::default();
+        data.$key = Some($value);
+        data
+    }};
+}
+
 /// Implements .next() that returns a different number each time.
 struct SideEffect(i32);
 
@@ -143,6 +158,11 @@ fn main() {
 
     let mut a: WrapperMulti<i32, i64> = Default::default();
     a.i = 42;
+
+    // Don't lint in macros
+    m! {
+        a: 42
+    };
 }
 
 mod m {
diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
index dd7c0360bb1..b56db08ec8a 100644
--- a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
+++ b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
@@ -1,108 +1,108 @@
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:48:5
+  --> $DIR/field_reassign_with_default.rs:63:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
    = note: `-D clippy::field-reassign-with-default` implied by `-D warnings`
 note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:47:5
+  --> $DIR/field_reassign_with_default.rs:62:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:88:5
+  --> $DIR/field_reassign_with_default.rs:103:5
    |
 LL |     a.j = 43;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { j: 43, i: 42 }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:87:5
+  --> $DIR/field_reassign_with_default.rs:102:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:93:5
+  --> $DIR/field_reassign_with_default.rs:108:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: 42, j: 44 }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:92:5
+  --> $DIR/field_reassign_with_default.rs:107:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:99:5
+  --> $DIR/field_reassign_with_default.rs:114:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:98:5
+  --> $DIR/field_reassign_with_default.rs:113:5
    |
 LL |     let mut a = A::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:109:5
+  --> $DIR/field_reassign_with_default.rs:124:5
    |
 LL |     a.i = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: Default::default(), ..Default::default() }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:108:5
+  --> $DIR/field_reassign_with_default.rs:123:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:113:5
+  --> $DIR/field_reassign_with_default.rs:128:5
    |
 LL |     a.i = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: Default::default(), j: 45 }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:112:5
+  --> $DIR/field_reassign_with_default.rs:127:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:135:5
+  --> $DIR/field_reassign_with_default.rs:150:5
    |
 LL |     a.i = vec![1];
    |     ^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `C { i: vec![1], ..Default::default() }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:134:5
+  --> $DIR/field_reassign_with_default.rs:149:5
    |
 LL |     let mut a: C = C::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:142:5
+  --> $DIR/field_reassign_with_default.rs:157:5
    |
 LL |     a.i = true;
    |     ^^^^^^^^^^^
    |
 note: consider initializing the variable with `Wrapper::<bool> { i: true }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:141:5
+  --> $DIR/field_reassign_with_default.rs:156:5
    |
 LL |     let mut a: Wrapper<bool> = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> $DIR/field_reassign_with_default.rs:145:5
+  --> $DIR/field_reassign_with_default.rs:160:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `WrapperMulti::<i32, i64> { i: 42, ..Default::default() }` and removing relevant reassignments
-  --> $DIR/field_reassign_with_default.rs:144:5
+  --> $DIR/field_reassign_with_default.rs:159:5
    |
 LL |     let mut a: WrapperMulti<i32, i64> = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/filter_map_identity.fixed b/src/tools/clippy/tests/ui/filter_map_identity.fixed
index 23ce28d8e9b..a5860aa49b3 100644
--- a/src/tools/clippy/tests/ui/filter_map_identity.fixed
+++ b/src/tools/clippy/tests/ui/filter_map_identity.fixed
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(unused_imports)]
+#![allow(unused_imports, clippy::needless_return)]
 #![warn(clippy::filter_map_identity)]
 
 fn main() {
@@ -13,4 +13,7 @@ fn main() {
     use std::convert::identity;
     let iterator = vec![Some(1), None, Some(2)].into_iter();
     let _ = iterator.flatten();
+
+    let iterator = vec![Some(1), None, Some(2)].into_iter();
+    let _ = iterator.flatten();
 }
diff --git a/src/tools/clippy/tests/ui/filter_map_identity.rs b/src/tools/clippy/tests/ui/filter_map_identity.rs
index e698df13eea..7e998b9cdf7 100644
--- a/src/tools/clippy/tests/ui/filter_map_identity.rs
+++ b/src/tools/clippy/tests/ui/filter_map_identity.rs
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(unused_imports)]
+#![allow(unused_imports, clippy::needless_return)]
 #![warn(clippy::filter_map_identity)]
 
 fn main() {
@@ -13,4 +13,7 @@ fn main() {
     use std::convert::identity;
     let iterator = vec![Some(1), None, Some(2)].into_iter();
     let _ = iterator.filter_map(identity);
+
+    let iterator = vec![Some(1), None, Some(2)].into_iter();
+    let _ = iterator.filter_map(|x| return x);
 }
diff --git a/src/tools/clippy/tests/ui/filter_map_identity.stderr b/src/tools/clippy/tests/ui/filter_map_identity.stderr
index 596a6320608..43c9fdca4fb 100644
--- a/src/tools/clippy/tests/ui/filter_map_identity.stderr
+++ b/src/tools/clippy/tests/ui/filter_map_identity.stderr
@@ -1,4 +1,4 @@
-error: called `filter_map(|x| x)` on an `Iterator`
+error: use of `filter_map` with an identity function
   --> $DIR/filter_map_identity.rs:8:22
    |
 LL |     let _ = iterator.filter_map(|x| x);
@@ -6,17 +6,23 @@ LL |     let _ = iterator.filter_map(|x| x);
    |
    = note: `-D clippy::filter-map-identity` implied by `-D warnings`
 
-error: called `filter_map(std::convert::identity)` on an `Iterator`
+error: use of `filter_map` with an identity function
   --> $DIR/filter_map_identity.rs:11:22
    |
 LL |     let _ = iterator.filter_map(std::convert::identity);
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
 
-error: called `filter_map(std::convert::identity)` on an `Iterator`
+error: use of `filter_map` with an identity function
   --> $DIR/filter_map_identity.rs:15:22
    |
 LL |     let _ = iterator.filter_map(identity);
    |                      ^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
 
-error: aborting due to 3 previous errors
+error: use of `filter_map` with an identity function
+  --> $DIR/filter_map_identity.rs:18:22
+   |
+LL |     let _ = iterator.filter_map(|x| return x);
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/flat_map_identity.fixed b/src/tools/clippy/tests/ui/flat_map_identity.fixed
index dfe3bd47e13..1f4b880ef5b 100644
--- a/src/tools/clippy/tests/ui/flat_map_identity.fixed
+++ b/src/tools/clippy/tests/ui/flat_map_identity.fixed
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(unused_imports)]
+#![allow(unused_imports, clippy::needless_return)]
 #![warn(clippy::flat_map_identity)]
 
 use std::convert;
@@ -11,4 +11,7 @@ fn main() {
 
     let iterator = [[0, 1], [2, 3], [4, 5]].iter();
     let _ = iterator.flatten();
+
+    let iterator = [[0, 1], [2, 3], [4, 5]].iter();
+    let _ = iterator.flatten();
 }
diff --git a/src/tools/clippy/tests/ui/flat_map_identity.rs b/src/tools/clippy/tests/ui/flat_map_identity.rs
index 393b9569255..de14a06d4e6 100644
--- a/src/tools/clippy/tests/ui/flat_map_identity.rs
+++ b/src/tools/clippy/tests/ui/flat_map_identity.rs
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(unused_imports)]
+#![allow(unused_imports, clippy::needless_return)]
 #![warn(clippy::flat_map_identity)]
 
 use std::convert;
@@ -11,4 +11,7 @@ fn main() {
 
     let iterator = [[0, 1], [2, 3], [4, 5]].iter();
     let _ = iterator.flat_map(convert::identity);
+
+    let iterator = [[0, 1], [2, 3], [4, 5]].iter();
+    let _ = iterator.flat_map(|x| return x);
 }
diff --git a/src/tools/clippy/tests/ui/flat_map_identity.stderr b/src/tools/clippy/tests/ui/flat_map_identity.stderr
index e4686ae5a54..e776c9fdf51 100644
--- a/src/tools/clippy/tests/ui/flat_map_identity.stderr
+++ b/src/tools/clippy/tests/ui/flat_map_identity.stderr
@@ -1,4 +1,4 @@
-error: called `flat_map(|x| x)` on an `Iterator`
+error: use of `flat_map` with an identity function
   --> $DIR/flat_map_identity.rs:10:22
    |
 LL |     let _ = iterator.flat_map(|x| x);
@@ -6,11 +6,17 @@ LL |     let _ = iterator.flat_map(|x| x);
    |
    = note: `-D clippy::flat-map-identity` implied by `-D warnings`
 
-error: called `flat_map(std::convert::identity)` on an `Iterator`
+error: use of `flat_map` with an identity function
   --> $DIR/flat_map_identity.rs:13:22
    |
 LL |     let _ = iterator.flat_map(convert::identity);
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
 
-error: aborting due to 2 previous errors
+error: use of `flat_map` with an identity function
+  --> $DIR/flat_map_identity.rs:16:22
+   |
+LL |     let _ = iterator.flat_map(|x| return x);
+   |                      ^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/match_same_arms.stderr b/src/tools/clippy/tests/ui/match_same_arms.stderr
index 0549886a1e8..e48451acfe8 100644
--- a/src/tools/clippy/tests/ui/match_same_arms.stderr
+++ b/src/tools/clippy/tests/ui/match_same_arms.stderr
@@ -32,6 +32,7 @@ help: consider refactoring into `(1, .., 3) | (.., 3)`
    |
 LL |         (1, .., 3) => 42,
    |         ^^^^^^^^^^
+   = help: ...or consider changing the match arm bodies
 
 error: this `match` has identical arm bodies
   --> $DIR/match_same_arms.rs:24:15
@@ -49,6 +50,7 @@ help: consider refactoring into `42 | 51`
    |
 LL |         42 => 1,
    |         ^^
+   = help: ...or consider changing the match arm bodies
 
 error: this `match` has identical arm bodies
   --> $DIR/match_same_arms.rs:26:15
@@ -66,6 +68,7 @@ help: consider refactoring into `41 | 52`
    |
 LL |         41 => 2,
    |         ^^
+   = help: ...or consider changing the match arm bodies
 
 error: this `match` has identical arm bodies
   --> $DIR/match_same_arms.rs:32:14
@@ -83,6 +86,7 @@ help: consider refactoring into `1 | 2`
    |
 LL |         1 => 2,
    |         ^
+   = help: ...or consider changing the match arm bodies
 
 error: this `match` has identical arm bodies
   --> $DIR/match_same_arms.rs:33:14
@@ -100,6 +104,7 @@ help: consider refactoring into `1 | 3`
    |
 LL |         1 => 2,
    |         ^
+   = help: ...or consider changing the match arm bodies
 
 error: this `match` has identical arm bodies
   --> $DIR/match_same_arms.rs:33:14
@@ -117,6 +122,7 @@ help: consider refactoring into `2 | 3`
    |
 LL |         2 => 2, //~ ERROR 2nd matched arms have same body
    |         ^
+   = help: ...or consider changing the match arm bodies
 
 error: this `match` has identical arm bodies
   --> $DIR/match_same_arms.rs:50:55
@@ -134,6 +140,7 @@ help: consider refactoring into `CommandInfo::BuiltIn { name, .. } | CommandInfo
    |
 LL |                 CommandInfo::BuiltIn { name, .. } => name.to_string(),
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ...or consider changing the match arm bodies
 
 error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/match_same_arms2.stderr b/src/tools/clippy/tests/ui/match_same_arms2.stderr
index 430021a0f7f..e1ed12f9370 100644
--- a/src/tools/clippy/tests/ui/match_same_arms2.stderr
+++ b/src/tools/clippy/tests/ui/match_same_arms2.stderr
@@ -53,6 +53,7 @@ help: consider refactoring into `42 | 51`
    |
 LL |         42 => foo(),
    |         ^^
+   = help: ...or consider changing the match arm bodies
 
 error: this `match` has identical arm bodies
   --> $DIR/match_same_arms2.rs:40:17
@@ -70,6 +71,7 @@ help: consider refactoring into `Some(_) | None`
    |
 LL |         Some(_) => 24,
    |         ^^^^^^^
+   = help: ...or consider changing the match arm bodies
 
 error: this `match` has identical arm bodies
   --> $DIR/match_same_arms2.rs:62:28
@@ -87,6 +89,7 @@ help: consider refactoring into `(Some(a), None) | (None, Some(a))`
    |
 LL |         (Some(a), None) => bar(a),
    |         ^^^^^^^^^^^^^^^
+   = help: ...or consider changing the match arm bodies
 
 error: this `match` has identical arm bodies
   --> $DIR/match_same_arms2.rs:68:26
@@ -104,6 +107,7 @@ help: consider refactoring into `(Some(a), ..) | (.., Some(a))`
    |
 LL |         (Some(a), ..) => bar(a),
    |         ^^^^^^^^^^^^^
+   = help: ...or consider changing the match arm bodies
 
 error: this `match` has identical arm bodies
   --> $DIR/match_same_arms2.rs:102:29
@@ -121,6 +125,7 @@ help: consider refactoring into `(Ok(x), Some(_)) | (Ok(_), Some(x))`
    |
 LL |         (Ok(x), Some(_)) => println!("ok {}", x),
    |         ^^^^^^^^^^^^^^^^
+   = help: ...or consider changing the match arm bodies
    = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: this `match` has identical arm bodies
@@ -139,6 +144,7 @@ help: consider refactoring into `Ok(3) | Ok(_)`
    |
 LL |         Ok(3) => println!("ok"),
    |         ^^^^^
+   = help: ...or consider changing the match arm bodies
    = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: this `match` has identical arm bodies
@@ -163,6 +169,7 @@ help: consider refactoring into `0 | 1`
    |
 LL |         0 => {
    |         ^
+   = help: ...or consider changing the match arm bodies
 
 error: match expression looks like `matches!` macro
   --> $DIR/match_same_arms2.rs:162:16
diff --git a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed
index 31b743f7a18..e675c183ea7 100644
--- a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed
+++ b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed
@@ -115,12 +115,19 @@ fn main() {
         pub enum Enum {
             A,
             B,
+            C,
             #[doc(hidden)]
             __Private,
         }
         match Enum::A {
             Enum::A => (),
             Enum::B => (),
+            Enum::C => (),
+            _ => (),
+        }
+        match Enum::A {
+            Enum::A => (),
+            Enum::B => (),
             _ => (),
         }
     }
diff --git a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs
index d19e6ab7eb2..38c3ffc00c7 100644
--- a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs
+++ b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs
@@ -115,12 +115,19 @@ fn main() {
         pub enum Enum {
             A,
             B,
+            C,
             #[doc(hidden)]
             __Private,
         }
         match Enum::A {
             Enum::A => (),
             Enum::B => (),
+            Enum::C => (),
+            _ => (),
+        }
+        match Enum::A {
+            Enum::A => (),
+            Enum::B => (),
             _ => (),
         }
     }
diff --git a/src/tools/clippy/tests/ui/mut_key.stderr b/src/tools/clippy/tests/ui/mut_key.stderr
index 8d6a259c7e3..a8460b06ca6 100644
--- a/src/tools/clippy/tests/ui/mut_key.stderr
+++ b/src/tools/clippy/tests/ui/mut_key.stderr
@@ -4,7 +4,7 @@ error: mutable key type
 LL | fn should_not_take_this_arg(m: &mut HashMap<Key, usize>, _n: usize) -> HashSet<Key> {
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[deny(clippy::mutable_key_type)]` on by default
+   = note: `-D clippy::mutable-key-type` implied by `-D warnings`
 
 error: mutable key type
   --> $DIR/mut_key.rs:27:72
diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs
index 0abe2cca267..79ba7402f1f 100644
--- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs
+++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.rs
@@ -17,6 +17,24 @@ fn basic101(x: i32) {
     y = x + 1
 }
 
+#[rustfmt::skip]
+fn closure_error() {
+    let _d = || {
+        hello()
+    };
+}
+
+#[rustfmt::skip]
+fn unsafe_checks_error() {
+    use std::mem::MaybeUninit;
+    use std::ptr;
+
+    let mut s = MaybeUninit::<String>::uninit();
+    let _d = || unsafe { 
+        ptr::drop_in_place(s.as_mut_ptr()) 
+    };
+}
+
 // this is fine
 fn print_sum(a: i32, b: i32) {
     println!("{}", a + b);
@@ -53,3 +71,29 @@ fn loop_test(x: i32) {
         println!("{}", ext);
     }
 }
+
+fn closure() {
+    let _d = || hello();
+}
+
+#[rustfmt::skip]
+fn closure_block() {
+    let _d = || { hello() };
+}
+
+unsafe fn some_unsafe_op() {}
+unsafe fn some_other_unsafe_fn() {}
+
+fn do_something() {
+    unsafe { some_unsafe_op() };
+
+    unsafe { some_other_unsafe_fn() };
+}
+
+fn unsafe_checks() {
+    use std::mem::MaybeUninit;
+    use std::ptr;
+
+    let mut s = MaybeUninit::<String>::uninit();
+    let _d = || unsafe { ptr::drop_in_place(s.as_mut_ptr()) };
+}
diff --git a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr
index b73f8967538..e88ebe2ad35 100644
--- a/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr
+++ b/src/tools/clippy/tests/ui/semicolon_if_nothing_returned.stderr
@@ -18,5 +18,17 @@ error: consider adding a `;` to the last statement for consistent formatting
 LL |     y = x + 1
    |     ^^^^^^^^^ help: add a `;` here: `y = x + 1;`
 
-error: aborting due to 3 previous errors
+error: consider adding a `;` to the last statement for consistent formatting
+  --> $DIR/semicolon_if_nothing_returned.rs:23:9
+   |
+LL |         hello()
+   |         ^^^^^^^ help: add a `;` here: `hello();`
+
+error: consider adding a `;` to the last statement for consistent formatting
+  --> $DIR/semicolon_if_nothing_returned.rs:34:9
+   |
+LL |         ptr::drop_in_place(s.as_mut_ptr()) 
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `ptr::drop_in_place(s.as_mut_ptr());`
+
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr b/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr
index 388fc740082..63fc9ecb79a 100644
--- a/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr
@@ -12,7 +12,7 @@ error: suspicious use of binary operator in `AddAssign` impl
 LL |         *self = *self - other;
    |                       ^
    |
-   = note: `#[deny(clippy::suspicious_op_assign_impl)]` on by default
+   = note: `-D clippy::suspicious-op-assign-impl` implied by `-D warnings`
 
 error: suspicious use of binary operator in `MulAssign` impl
   --> $DIR/suspicious_arithmetic_impl.rs:32:16
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed b/src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed
index 7fbce58a82f..bda0f2c47cd 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed
@@ -1,7 +1,7 @@
 // run-rustfix
 
 #![warn(clippy::unnecessary_cast)]
-#![allow(clippy::no_effect, clippy::unnecessary_operation)]
+#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::nonstandard_macro_braces)]
 
 fn main() {
     // casting integer literal to float is unnecessary
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs b/src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs
index a71363ea4d2..f7a4f2a5988 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs
@@ -1,7 +1,7 @@
 // run-rustfix
 
 #![warn(clippy::unnecessary_cast)]
-#![allow(clippy::no_effect, clippy::unnecessary_operation)]
+#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::nonstandard_macro_braces)]
 
 fn main() {
     // casting integer literal to float is unnecessary
diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed
index 631da6fe066..e2c28542efc 100644
--- a/src/tools/clippy/tests/ui/use_self.fixed
+++ b/src/tools/clippy/tests/ui/use_self.fixed
@@ -492,3 +492,26 @@ mod issue7206 {
         }
     }
 }
+
+mod self_is_ty_param {
+    trait Trait {
+        type Type;
+        type Hi;
+
+        fn test();
+    }
+
+    impl<I> Trait for I
+    where
+        I: Iterator,
+        I::Item: Trait, // changing this to Self would require <Self as Iterator>
+    {
+        type Type = I;
+        type Hi = I::Item;
+
+        fn test() {
+            let _: I::Item;
+            let _: I; // this could lint, but is questionable
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs
index 7a10d755faa..3cd99b9f5cd 100644
--- a/src/tools/clippy/tests/ui/use_self.rs
+++ b/src/tools/clippy/tests/ui/use_self.rs
@@ -279,7 +279,7 @@ mod generics {
     impl<T> Foo<T> {
         // `Self` is applicable here
         fn foo(value: T) -> Foo<T> {
-            Foo { value }
+            Foo::<T> { value }
         }
 
         // `Cannot` use `Self` as a return type as the generic types are different
@@ -492,3 +492,26 @@ mod issue7206 {
         }
     }
 }
+
+mod self_is_ty_param {
+    trait Trait {
+        type Type;
+        type Hi;
+
+        fn test();
+    }
+
+    impl<I> Trait for I
+    where
+        I: Iterator,
+        I::Item: Trait, // changing this to Self would require <Self as Iterator>
+    {
+        type Type = I;
+        type Hi = I::Item;
+
+        fn test() {
+            let _: I::Item;
+            let _: I; // this could lint, but is questionable
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/use_self.stderr b/src/tools/clippy/tests/ui/use_self.stderr
index cf6222c9b45..6ac26c9e5a9 100644
--- a/src/tools/clippy/tests/ui/use_self.stderr
+++ b/src/tools/clippy/tests/ui/use_self.stderr
@@ -153,8 +153,8 @@ LL |         fn foo(value: T) -> Foo<T> {
 error: unnecessary structure name repetition
   --> $DIR/use_self.rs:282:13
    |
-LL |             Foo { value }
-   |             ^^^ help: use the applicable keyword: `Self`
+LL |             Foo::<T> { value }
+   |             ^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
   --> $DIR/use_self.rs:454:13
diff --git a/src/tools/clippy/tests/ui/vec.fixed b/src/tools/clippy/tests/ui/vec.fixed
index da35f2e5c1b..318f9c2dceb 100644
--- a/src/tools/clippy/tests/ui/vec.fixed
+++ b/src/tools/clippy/tests/ui/vec.fixed
@@ -1,5 +1,5 @@
 // run-rustfix
-
+#![allow(clippy::nonstandard_macro_braces)]
 #![warn(clippy::useless_vec)]
 
 #[derive(Debug)]
diff --git a/src/tools/clippy/tests/ui/vec.rs b/src/tools/clippy/tests/ui/vec.rs
index e9ed83e5c5a..d7673ce3e64 100644
--- a/src/tools/clippy/tests/ui/vec.rs
+++ b/src/tools/clippy/tests/ui/vec.rs
@@ -1,5 +1,5 @@
 // run-rustfix
-
+#![allow(clippy::nonstandard_macro_braces)]
 #![warn(clippy::useless_vec)]
 
 #[derive(Debug)]
diff --git a/src/tools/clippy/tests/ui/while_let_on_iterator.fixed b/src/tools/clippy/tests/ui/while_let_on_iterator.fixed
index c3e2cf0c4a4..52e80ceee83 100644
--- a/src/tools/clippy/tests/ui/while_let_on_iterator.fixed
+++ b/src/tools/clippy/tests/ui/while_let_on_iterator.fixed
@@ -320,6 +320,20 @@ fn issue1924() {
     println!("iterator field {}", it.1);
 }
 
+fn issue7249() {
+    let mut it = 0..10;
+    let mut x = || {
+        // Needs &mut, the closure can be called multiple times
+        for x in &mut it {
+            if x % 2 == 0 {
+                break;
+            }
+        }
+    };
+    x();
+    x();
+}
+
 fn main() {
     let mut it = 0..20;
     for _ in it {
diff --git a/src/tools/clippy/tests/ui/while_let_on_iterator.rs b/src/tools/clippy/tests/ui/while_let_on_iterator.rs
index 1717006a449..5078a3c9028 100644
--- a/src/tools/clippy/tests/ui/while_let_on_iterator.rs
+++ b/src/tools/clippy/tests/ui/while_let_on_iterator.rs
@@ -320,6 +320,20 @@ fn issue1924() {
     println!("iterator field {}", it.1);
 }
 
+fn issue7249() {
+    let mut it = 0..10;
+    let mut x = || {
+        // Needs &mut, the closure can be called multiple times
+        while let Some(x) = it.next() {
+            if x % 2 == 0 {
+                break;
+            }
+        }
+    };
+    x();
+    x();
+}
+
 fn main() {
     let mut it = 0..20;
     while let Some(..) = it.next() {
diff --git a/src/tools/clippy/tests/ui/while_let_on_iterator.stderr b/src/tools/clippy/tests/ui/while_let_on_iterator.stderr
index eff559bef7e..cb0afeae15e 100644
--- a/src/tools/clippy/tests/ui/while_let_on_iterator.stderr
+++ b/src/tools/clippy/tests/ui/while_let_on_iterator.stderr
@@ -105,10 +105,16 @@ LL |     while let Some(n) = it.next() {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for n in &mut it`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:325:5
+  --> $DIR/while_let_on_iterator.rs:327:9
+   |
+LL |         while let Some(x) = it.next() {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in &mut it`
+
+error: this loop could be written as a `for` loop
+  --> $DIR/while_let_on_iterator.rs:339:5
    |
 LL |     while let Some(..) = it.next() {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it`
 
-error: aborting due to 18 previous errors
+error: aborting due to 19 previous errors
 
diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed
index 5ad27bb1450..3ee4ab48ac8 100644
--- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed
+++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+// aux-build:non-exhaustive-enum.rs
 
 #![deny(clippy::wildcard_enum_match_arm)]
 #![allow(
@@ -11,7 +12,9 @@
     clippy::diverging_sub_expression
 )]
 
-use std::io::ErrorKind;
+extern crate non_exhaustive_enum;
+
+use non_exhaustive_enum::ErrorKind;
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 enum Color {
@@ -77,29 +80,25 @@ fn main() {
     let error_kind = ErrorKind::NotFound;
     match error_kind {
         ErrorKind::NotFound => {},
-        ErrorKind::PermissionDenied | ErrorKind::ConnectionRefused | ErrorKind::ConnectionReset | ErrorKind::ConnectionAborted | ErrorKind::NotConnected | ErrorKind::AddrInUse | ErrorKind::AddrNotAvailable | ErrorKind::BrokenPipe | ErrorKind::AlreadyExists | ErrorKind::WouldBlock | ErrorKind::InvalidInput | ErrorKind::InvalidData | ErrorKind::TimedOut | ErrorKind::WriteZero | ErrorKind::Interrupted | ErrorKind::Other | ErrorKind::UnexpectedEof | ErrorKind::Unsupported | ErrorKind::OutOfMemory | _ => {},
+        ErrorKind::PermissionDenied | _ => {},
     }
     match error_kind {
         ErrorKind::NotFound => {},
         ErrorKind::PermissionDenied => {},
-        ErrorKind::ConnectionRefused => {},
-        ErrorKind::ConnectionReset => {},
-        ErrorKind::ConnectionAborted => {},
-        ErrorKind::NotConnected => {},
-        ErrorKind::AddrInUse => {},
-        ErrorKind::AddrNotAvailable => {},
-        ErrorKind::BrokenPipe => {},
-        ErrorKind::AlreadyExists => {},
-        ErrorKind::WouldBlock => {},
-        ErrorKind::InvalidInput => {},
-        ErrorKind::InvalidData => {},
-        ErrorKind::TimedOut => {},
-        ErrorKind::WriteZero => {},
-        ErrorKind::Interrupted => {},
-        ErrorKind::Other => {},
-        ErrorKind::UnexpectedEof => {},
-        ErrorKind::Unsupported => {},
-        ErrorKind::OutOfMemory => {},
         _ => {},
     }
+
+    {
+        #![allow(clippy::manual_non_exhaustive)]
+        pub enum Enum {
+            A,
+            B,
+            #[doc(hidden)]
+            __Private,
+        }
+        match Enum::A {
+            Enum::A => (),
+            Enum::B | _ => (),
+        }
+    }
 }
diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs
index adca0738bba..46886550453 100644
--- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs
+++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+// aux-build:non-exhaustive-enum.rs
 
 #![deny(clippy::wildcard_enum_match_arm)]
 #![allow(
@@ -11,7 +12,9 @@
     clippy::diverging_sub_expression
 )]
 
-use std::io::ErrorKind;
+extern crate non_exhaustive_enum;
+
+use non_exhaustive_enum::ErrorKind;
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 enum Color {
@@ -82,24 +85,20 @@ fn main() {
     match error_kind {
         ErrorKind::NotFound => {},
         ErrorKind::PermissionDenied => {},
-        ErrorKind::ConnectionRefused => {},
-        ErrorKind::ConnectionReset => {},
-        ErrorKind::ConnectionAborted => {},
-        ErrorKind::NotConnected => {},
-        ErrorKind::AddrInUse => {},
-        ErrorKind::AddrNotAvailable => {},
-        ErrorKind::BrokenPipe => {},
-        ErrorKind::AlreadyExists => {},
-        ErrorKind::WouldBlock => {},
-        ErrorKind::InvalidInput => {},
-        ErrorKind::InvalidData => {},
-        ErrorKind::TimedOut => {},
-        ErrorKind::WriteZero => {},
-        ErrorKind::Interrupted => {},
-        ErrorKind::Other => {},
-        ErrorKind::UnexpectedEof => {},
-        ErrorKind::Unsupported => {},
-        ErrorKind::OutOfMemory => {},
         _ => {},
     }
+
+    {
+        #![allow(clippy::manual_non_exhaustive)]
+        pub enum Enum {
+            A,
+            B,
+            #[doc(hidden)]
+            __Private,
+        }
+        match Enum::A {
+            Enum::A => (),
+            _ => (),
+        }
+    }
 }
diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr
index 73f6a4a80c9..d63f2090353 100644
--- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr
+++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.stderr
@@ -1,38 +1,44 @@
 error: wildcard match will also match any future added variants
-  --> $DIR/wildcard_enum_match_arm.rs:39:9
+  --> $DIR/wildcard_enum_match_arm.rs:42:9
    |
 LL |         _ => eprintln!("Not red"),
    |         ^ help: try this: `Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan`
    |
 note: the lint level is defined here
-  --> $DIR/wildcard_enum_match_arm.rs:3:9
+  --> $DIR/wildcard_enum_match_arm.rs:4:9
    |
 LL | #![deny(clippy::wildcard_enum_match_arm)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: wildcard match will also match any future added variants
-  --> $DIR/wildcard_enum_match_arm.rs:43:9
+  --> $DIR/wildcard_enum_match_arm.rs:46:9
    |
 LL |         _not_red => eprintln!("Not red"),
    |         ^^^^^^^^ help: try this: `_not_red @ Color::Green | _not_red @ Color::Blue | _not_red @ Color::Rgb(..) | _not_red @ Color::Cyan`
 
 error: wildcard match will also match any future added variants
-  --> $DIR/wildcard_enum_match_arm.rs:47:9
+  --> $DIR/wildcard_enum_match_arm.rs:50:9
    |
 LL |         not_red => format!("{:?}", not_red),
    |         ^^^^^^^ help: try this: `not_red @ Color::Green | not_red @ Color::Blue | not_red @ Color::Rgb(..) | not_red @ Color::Cyan`
 
 error: wildcard match will also match any future added variants
-  --> $DIR/wildcard_enum_match_arm.rs:63:9
+  --> $DIR/wildcard_enum_match_arm.rs:66:9
    |
 LL |         _ => "No red",
    |         ^ help: try this: `Color::Red | Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan`
 
 error: wildcard matches known variants and will also match future added variants
-  --> $DIR/wildcard_enum_match_arm.rs:80:9
+  --> $DIR/wildcard_enum_match_arm.rs:83:9
    |
 LL |         _ => {},
-   |         ^ help: try this: `ErrorKind::PermissionDenied | ErrorKind::ConnectionRefused | ErrorKind::ConnectionReset | ErrorKind::ConnectionAborted | ErrorKind::NotConnected | ErrorKind::AddrInUse | ErrorKind::AddrNotAvailable | ErrorKind::BrokenPipe | ErrorKind::AlreadyExists | ErrorKind::WouldBlock | ErrorKind::InvalidInput | ErrorKind::InvalidData | ErrorKind::TimedOut | ErrorKind::WriteZero | ErrorKind::Interrupted | ErrorKind::Other | ErrorKind::UnexpectedEof | ErrorKind::Unsupported | ErrorKind::OutOfMemory | _`
+   |         ^ help: try this: `ErrorKind::PermissionDenied | _`
 
-error: aborting due to 5 previous errors
+error: wildcard matches known variants and will also match future added variants
+  --> $DIR/wildcard_enum_match_arm.rs:101:13
+   |
+LL |             _ => (),
+   |             ^ help: try this: `Enum::B | _`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/zero_offset.rs b/src/tools/clippy/tests/ui/zero_offset.rs
index 2de904376ad..6c190a4c86c 100644
--- a/src/tools/clippy/tests/ui/zero_offset.rs
+++ b/src/tools/clippy/tests/ui/zero_offset.rs
@@ -1,12 +1,18 @@
 fn main() {
     unsafe {
-        let x = &() as *const ();
-        x.offset(0);
-        x.wrapping_add(0);
-        x.sub(0);
-        x.wrapping_sub(0);
+        let m = &mut () as *mut ();
+        m.offset(0);
+        m.wrapping_add(0);
+        m.sub(0);
+        m.wrapping_sub(0);
 
-        let y = &1 as *const u8;
-        y.offset(0);
+        let c = &() as *const ();
+        c.offset(0);
+        c.wrapping_add(0);
+        c.sub(0);
+        c.wrapping_sub(0);
+
+        let sized = &1 as *const i32;
+        sized.offset(0);
     }
 }
diff --git a/src/tools/clippy/tests/ui/zero_offset.stderr b/src/tools/clippy/tests/ui/zero_offset.stderr
index cfcd7de2b3d..b12c8e9a73c 100644
--- a/src/tools/clippy/tests/ui/zero_offset.stderr
+++ b/src/tools/clippy/tests/ui/zero_offset.stderr
@@ -1,9 +1,52 @@
-error[E0606]: casting `&i32` as `*const u8` is invalid
-  --> $DIR/zero_offset.rs:9:17
+error: offset calculation on zero-sized value
+  --> $DIR/zero_offset.rs:4:9
    |
-LL |         let y = &1 as *const u8;
-   |                 ^^^^^^^^^^^^^^^
+LL |         m.offset(0);
+   |         ^^^^^^^^^^^
+   |
+   = note: `#[deny(clippy::zst_offset)]` on by default
+
+error: offset calculation on zero-sized value
+  --> $DIR/zero_offset.rs:5:9
+   |
+LL |         m.wrapping_add(0);
+   |         ^^^^^^^^^^^^^^^^^
+
+error: offset calculation on zero-sized value
+  --> $DIR/zero_offset.rs:6:9
+   |
+LL |         m.sub(0);
+   |         ^^^^^^^^
+
+error: offset calculation on zero-sized value
+  --> $DIR/zero_offset.rs:7:9
+   |
+LL |         m.wrapping_sub(0);
+   |         ^^^^^^^^^^^^^^^^^
+
+error: offset calculation on zero-sized value
+  --> $DIR/zero_offset.rs:10:9
+   |
+LL |         c.offset(0);
+   |         ^^^^^^^^^^^
+
+error: offset calculation on zero-sized value
+  --> $DIR/zero_offset.rs:11:9
+   |
+LL |         c.wrapping_add(0);
+   |         ^^^^^^^^^^^^^^^^^
+
+error: offset calculation on zero-sized value
+  --> $DIR/zero_offset.rs:12:9
+   |
+LL |         c.sub(0);
+   |         ^^^^^^^^
+
+error: offset calculation on zero-sized value
+  --> $DIR/zero_offset.rs:13:9
+   |
+LL |         c.wrapping_sub(0);
+   |         ^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0606`.
diff --git a/src/tools/clippy/util/etc/pre-commit.sh b/src/tools/clippy/util/etc/pre-commit.sh
new file mode 100755
index 00000000000..528f8953b25
--- /dev/null
+++ b/src/tools/clippy/util/etc/pre-commit.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# hide output
+set -e
+
+# Update lints
+cargo dev update_lints
+git add clippy_lints/src/lib.rs
+
+# Formatting:
+#     Git will not automatically add the formatted code to the staged changes once
+#     fmt was executed. This collects all staged files rs files that are currently staged.
+#     They will later be added back.
+#
+#     This was proudly stolen and adjusted from here:
+#     https://medium.com/@harshitbangar/automatic-code-formatting-with-git-66c3c5c26798
+files=$( (git diff --cached --name-only --diff-filter=ACMR | grep -Ei "\.rs$") || true)
+if [ ! -z "${files}" ]; then
+    cargo dev fmt
+    git add $(echo "$files" | paste -s -d " " -)
+fi
diff --git a/src/tools/clippy/util/etc/vscode-tasks.json b/src/tools/clippy/util/etc/vscode-tasks.json
new file mode 100644
index 00000000000..a4bb26b9f90
--- /dev/null
+++ b/src/tools/clippy/util/etc/vscode-tasks.json
@@ -0,0 +1,57 @@
+{
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "label": "cargo check",
+            "type": "shell",
+            "command": "cargo check",
+            "problemMatcher": [],
+            "group": {
+                "kind": "build",
+                "isDefault": true,
+            },
+        },
+        {
+            "label": "cargo dev fmt",
+            "type": "shell",
+            "command": "cargo dev fmt",
+            "problemMatcher": [],
+            "group": "none",
+        },
+        {
+            "label": "cargo uitest",
+            "type": "shell",
+            "command": "cargo uitest",
+            "options": {
+                "env": {
+                    "RUST_BACKTRACE": "1",
+                    // This task will usually execute all UI tests inside `tests/ui` you can
+                    // optionally uncomment the line below and only run a specific test.
+                    //
+                    // See: https://github.com/rust-lang/rust-clippy/blob/master/doc/adding_lints.md#testing
+                    //
+                    // "TESTNAME": "<TODO>",
+                },
+            },
+            "problemMatcher": [],
+            "group": {
+                "kind": "test",
+                "isDefault": true,
+            }
+        },
+        {
+            "label": "cargo test",
+            "type": "shell",
+            "command": "cargo test",
+            "problemMatcher": [],
+            "group": "test",
+        },
+        {
+            "label": "cargo dev bless",
+            "type": "shell",
+            "command": "cargo dev bless",
+            "problemMatcher": [],
+            "group": "none",
+        },
+    ],
+}
diff --git a/src/tools/clippy/util/lintlib.py b/src/tools/clippy/util/lintlib.py
index 5707cf0ce0f..9cefb2dbb19 100644
--- a/src/tools/clippy/util/lintlib.py
+++ b/src/tools/clippy/util/lintlib.py
@@ -12,13 +12,14 @@ Config = collections.namedtuple('Config', 'name ty doc default')
 
 lintname_re = re.compile(r'''pub\s+([A-Z_][A-Z_0-9]*)''')
 group_re = re.compile(r'''\s*([a-z_][a-z_0-9]+)''')
-conf_re = re.compile(r'''define_Conf! {\n([^}]*)\n}''', re.MULTILINE)
+conf_re = re.compile(r'''define_Conf! {\n((?!\n})[\s\S])*\n}''', re.MULTILINE)
 confvar_re = re.compile(
     r'''/// Lint: ([\w,\s]+)\. (.*)\n\s*\(([^:]+):\s*([^\s=]+)\s*=\s*([^\.\)]+).*\),''', re.MULTILINE)
 comment_re = re.compile(r'''\s*/// ?(.*)''')
 
 lint_levels = {
     "correctness": 'Deny',
+    "suspicious": 'Warn',
     "style": 'Warn',
     "complexity": 'Warn',
     "perf": 'Warn',
@@ -91,7 +92,7 @@ def parse_configs(path):
         contents = fp.read()
 
     match = re.search(conf_re, contents)
-    confvars = re.findall(confvar_re, match.group(1))
+    confvars = re.findall(confvar_re, match.group(0))
 
     for (lints, doc, name, ty, default) in confvars:
         for lint in lints.split(','):
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 26c1710be74..68e28795347 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -27,8 +27,6 @@ enum ParsedNameDirective {
 /// the test.
 #[derive(Default)]
 pub struct EarlyProps {
-    pub ignore: bool,
-    pub should_fail: bool,
     pub aux: Vec<String>,
     pub aux_crate: Vec<(String, String)>,
     pub revisions: Vec<String>,
@@ -36,251 +34,22 @@ pub struct EarlyProps {
 
 impl EarlyProps {
     pub fn from_file(config: &Config, testfile: &Path) -> Self {
-        let file = File::open(testfile).unwrap();
+        let file = File::open(testfile).expect("open test file to parse earlyprops");
         Self::from_reader(config, testfile, file)
     }
 
     pub fn from_reader<R: Read>(config: &Config, testfile: &Path, rdr: R) -> Self {
         let mut props = EarlyProps::default();
-        let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
-        let rustc_has_sanitizer_support = env::var_os("RUSTC_SANITIZER_SUPPORT").is_some();
-        let has_asm_support = util::has_asm_support(&config.target);
-        let has_asan = util::ASAN_SUPPORTED_TARGETS.contains(&&*config.target);
-        let has_lsan = util::LSAN_SUPPORTED_TARGETS.contains(&&*config.target);
-        let has_msan = util::MSAN_SUPPORTED_TARGETS.contains(&&*config.target);
-        let has_tsan = util::TSAN_SUPPORTED_TARGETS.contains(&&*config.target);
-        let has_hwasan = util::HWASAN_SUPPORTED_TARGETS.contains(&&*config.target);
-        // for `-Z gcc-ld=lld`
-        let has_rust_lld = config
-            .compile_lib_path
-            .join("rustlib")
-            .join(&config.target)
-            .join("bin")
-            .join("gcc-ld")
-            .join(if config.host.contains("windows") { "ld.exe" } else { "ld" })
-            .exists();
-
-        iter_header(testfile, None, rdr, &mut |ln| {
-            // we should check if any only-<platform> exists and if it exists
-            // and does not matches the current platform, skip the test
-            if !props.ignore {
-                props.ignore = match config.parse_cfg_name_directive(ln, "ignore") {
-                    ParsedNameDirective::Match => true,
-                    ParsedNameDirective::NoMatch => props.ignore,
-                };
-
-                if config.has_cfg_prefix(ln, "only") {
-                    props.ignore = match config.parse_cfg_name_directive(ln, "only") {
-                        ParsedNameDirective::Match => props.ignore,
-                        ParsedNameDirective::NoMatch => true,
-                    };
-                }
-
-                if ignore_llvm(config, ln) {
-                    props.ignore = true;
-                }
-
-                if config.run_clang_based_tests_with.is_none()
-                    && config.parse_needs_matching_clang(ln)
-                {
-                    props.ignore = true;
-                }
-
-                if !has_asm_support && config.parse_name_directive(ln, "needs-asm-support") {
-                    props.ignore = true;
-                }
-
-                if !rustc_has_profiler_support && config.parse_needs_profiler_support(ln) {
-                    props.ignore = true;
-                }
-
-                if !config.run_enabled() && config.parse_name_directive(ln, "needs-run-enabled") {
-                    props.ignore = true;
-                }
-
-                if !rustc_has_sanitizer_support
-                    && config.parse_name_directive(ln, "needs-sanitizer-support")
-                {
-                    props.ignore = true;
-                }
-
-                if !has_asan && config.parse_name_directive(ln, "needs-sanitizer-address") {
-                    props.ignore = true;
-                }
-
-                if !has_lsan && config.parse_name_directive(ln, "needs-sanitizer-leak") {
-                    props.ignore = true;
-                }
-
-                if !has_msan && config.parse_name_directive(ln, "needs-sanitizer-memory") {
-                    props.ignore = true;
-                }
-
-                if !has_tsan && config.parse_name_directive(ln, "needs-sanitizer-thread") {
-                    props.ignore = true;
-                }
-
-                if !has_hwasan && config.parse_name_directive(ln, "needs-sanitizer-hwaddress") {
-                    props.ignore = true;
-                }
-
-                if config.target_panic == PanicStrategy::Abort
-                    && config.parse_name_directive(ln, "needs-unwind")
-                {
-                    props.ignore = true;
-                }
-
-                if config.target == "wasm32-unknown-unknown" && config.parse_check_run_results(ln) {
-                    props.ignore = true;
-                }
-
-                if config.debugger == Some(Debugger::Cdb) && ignore_cdb(config, ln) {
-                    props.ignore = true;
-                }
-
-                if config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln) {
-                    props.ignore = true;
-                }
-
-                if config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln) {
-                    props.ignore = true;
-                }
-
-                if !has_rust_lld && config.parse_name_directive(ln, "needs-rust-lld") {
-                    props.ignore = true;
-                }
-            }
-
+        iter_header(testfile, rdr, &mut |_, ln| {
             if let Some(s) = config.parse_aux_build(ln) {
                 props.aux.push(s);
             }
-
             if let Some(ac) = config.parse_aux_crate(ln) {
                 props.aux_crate.push(ac);
             }
-
             config.parse_and_update_revisions(ln, &mut props.revisions);
-
-            props.should_fail = props.should_fail || config.parse_name_directive(ln, "should-fail");
         });
-
         return props;
-
-        fn ignore_cdb(config: &Config, line: &str) -> bool {
-            if let Some(actual_version) = config.cdb_version {
-                if let Some(min_version) = line.strip_prefix("min-cdb-version:").map(str::trim) {
-                    let min_version = extract_cdb_version(min_version).unwrap_or_else(|| {
-                        panic!("couldn't parse version range: {:?}", min_version);
-                    });
-
-                    // Ignore if actual version is smaller than the minimum
-                    // required version
-                    return actual_version < min_version;
-                }
-            }
-            false
-        }
-
-        fn ignore_gdb(config: &Config, line: &str) -> bool {
-            if let Some(actual_version) = config.gdb_version {
-                if let Some(rest) = line.strip_prefix("min-gdb-version:").map(str::trim) {
-                    let (start_ver, end_ver) = extract_version_range(rest, extract_gdb_version)
-                        .unwrap_or_else(|| {
-                            panic!("couldn't parse version range: {:?}", rest);
-                        });
-
-                    if start_ver != end_ver {
-                        panic!("Expected single GDB version")
-                    }
-                    // Ignore if actual version is smaller than the minimum
-                    // required version
-                    return actual_version < start_ver;
-                } else if let Some(rest) = line.strip_prefix("ignore-gdb-version:").map(str::trim) {
-                    let (min_version, max_version) =
-                        extract_version_range(rest, extract_gdb_version).unwrap_or_else(|| {
-                            panic!("couldn't parse version range: {:?}", rest);
-                        });
-
-                    if max_version < min_version {
-                        panic!("Malformed GDB version range: max < min")
-                    }
-
-                    return actual_version >= min_version && actual_version <= max_version;
-                }
-            }
-            false
-        }
-
-        fn ignore_lldb(config: &Config, line: &str) -> bool {
-            if let Some(actual_version) = config.lldb_version {
-                if let Some(min_version) = line.strip_prefix("min-lldb-version:").map(str::trim) {
-                    let min_version = min_version.parse().unwrap_or_else(|e| {
-                        panic!(
-                            "Unexpected format of LLDB version string: {}\n{:?}",
-                            min_version, e
-                        );
-                    });
-                    // Ignore if actual version is smaller the minimum required
-                    // version
-                    actual_version < min_version
-                } else {
-                    line.starts_with("rust-lldb") && !config.lldb_native_rust
-                }
-            } else {
-                false
-            }
-        }
-
-        fn ignore_llvm(config: &Config, line: &str) -> bool {
-            if config.system_llvm && line.starts_with("no-system-llvm") {
-                return true;
-            }
-            if let Some(needed_components) =
-                config.parse_name_value_directive(line, "needs-llvm-components")
-            {
-                let components: HashSet<_> = config.llvm_components.split_whitespace().collect();
-                if let Some(missing_component) = needed_components
-                    .split_whitespace()
-                    .find(|needed_component| !components.contains(needed_component))
-                {
-                    if env::var_os("COMPILETEST_NEEDS_ALL_LLVM_COMPONENTS").is_some() {
-                        panic!("missing LLVM component: {}", missing_component);
-                    }
-                    return true;
-                }
-            }
-            if let Some(actual_version) = config.llvm_version {
-                if let Some(rest) = line.strip_prefix("min-llvm-version:").map(str::trim) {
-                    let min_version = extract_llvm_version(rest).unwrap();
-                    // Ignore if actual version is smaller the minimum required
-                    // version
-                    actual_version < min_version
-                } else if let Some(rest) =
-                    line.strip_prefix("min-system-llvm-version:").map(str::trim)
-                {
-                    let min_version = extract_llvm_version(rest).unwrap();
-                    // Ignore if using system LLVM and actual version
-                    // is smaller the minimum required version
-                    config.system_llvm && actual_version < min_version
-                } else if let Some(rest) = line.strip_prefix("ignore-llvm-version:").map(str::trim)
-                {
-                    // Syntax is: "ignore-llvm-version: <version1> [- <version2>]"
-                    let (v_min, v_max) = extract_version_range(rest, extract_llvm_version)
-                        .unwrap_or_else(|| {
-                            panic!("couldn't parse version range: {:?}", rest);
-                        });
-                    if v_max < v_min {
-                        panic!("Malformed LLVM version range: max < min")
-                    }
-                    // Ignore if version lies inside of range.
-                    actual_version >= v_min && actual_version <= v_max
-                } else {
-                    false
-                }
-            } else {
-                false
-            }
-        }
     }
 }
 
@@ -440,7 +209,11 @@ impl TestProps {
         if !testfile.is_dir() {
             let file = File::open(testfile).unwrap();
 
-            iter_header(testfile, cfg, file, &mut |ln| {
+            iter_header(testfile, file, &mut |revision, ln| {
+                if revision.is_some() && revision != cfg {
+                    return;
+                }
+
                 if let Some(ep) = config.parse_error_pattern(ln) {
                     self.error_patterns.push(ep);
                 }
@@ -672,12 +445,12 @@ impl TestProps {
     }
 }
 
-fn iter_header<R: Read>(testfile: &Path, cfg: Option<&str>, rdr: R, it: &mut dyn FnMut(&str)) {
+fn iter_header<R: Read>(testfile: &Path, rdr: R, it: &mut dyn FnMut(Option<&str>, &str)) {
     if testfile.is_dir() {
         return;
     }
 
-    let comment = if testfile.to_string_lossy().ends_with(".rs") { "//" } else { "#" };
+    let comment = if testfile.extension().map(|e| e == "rs") == Some(true) { "//" } else { "#" };
 
     let mut rdr = BufReader::new(rdr);
     let mut ln = String::new();
@@ -699,18 +472,12 @@ fn iter_header<R: Read>(testfile: &Path, cfg: Option<&str>, rdr: R, it: &mut dyn
             if let Some(close_brace) = ln.find(']') {
                 let open_brace = ln.find('[').unwrap();
                 let lncfg = &ln[open_brace + 1..close_brace];
-                let matches = match cfg {
-                    Some(s) => s == &lncfg[..],
-                    None => false,
-                };
-                if matches {
-                    it(ln[(close_brace + 1)..].trim_start());
-                }
+                it(Some(lncfg), ln[(close_brace + 1)..].trim_start());
             } else {
                 panic!("malformed condition directive: expected `{}[foo]`, found `{}`", comment, ln)
             }
         } else if ln.starts_with(comment) {
-            it(ln[comment.len()..].trim_start());
+            it(None, ln[comment.len()..].trim_start());
         }
     }
 }
@@ -1026,11 +793,12 @@ pub fn extract_llvm_version(version: &str) -> Option<u32> {
     Some(version)
 }
 
-// Takes a directive of the form "<version1> [- <version2>]",
-// returns the numeric representation of <version1> and <version2> as
-// tuple: (<version1> as u32, <version2> as u32)
-// If the <version2> part is omitted, the second component of the tuple
-// is the same as <version1>.
+/// Takes a directive of the form "<version1> [- <version2>]",
+/// returns the numeric representation of <version1> and <version2> as
+/// tuple: (<version1> as u32, <version2> as u32)
+///
+/// If the <version2> part is omitted, the second component of the tuple
+/// is the same as <version1>.
 fn extract_version_range<F>(line: &str, parse: F) -> Option<(u32, u32)>
 where
     F: Fn(&str) -> Option<u32>,
@@ -1056,3 +824,197 @@ where
 
     Some((min, max))
 }
+
+pub fn make_test_description<R: Read>(
+    config: &Config,
+    name: test::TestName,
+    path: &Path,
+    src: R,
+    cfg: Option<&str>,
+) -> test::TestDesc {
+    let mut ignore = false;
+    let mut should_fail = false;
+
+    let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
+    let rustc_has_sanitizer_support = env::var_os("RUSTC_SANITIZER_SUPPORT").is_some();
+    let has_asm_support = util::has_asm_support(&config.target);
+    let has_asan = util::ASAN_SUPPORTED_TARGETS.contains(&&*config.target);
+    let has_lsan = util::LSAN_SUPPORTED_TARGETS.contains(&&*config.target);
+    let has_msan = util::MSAN_SUPPORTED_TARGETS.contains(&&*config.target);
+    let has_tsan = util::TSAN_SUPPORTED_TARGETS.contains(&&*config.target);
+    let has_hwasan = util::HWASAN_SUPPORTED_TARGETS.contains(&&*config.target);
+    // for `-Z gcc-ld=lld`
+    let has_rust_lld = config
+        .compile_lib_path
+        .join("rustlib")
+        .join(&config.target)
+        .join("bin")
+        .join("gcc-ld")
+        .join(if config.host.contains("windows") { "ld.exe" } else { "ld" })
+        .exists();
+    iter_header(path, src, &mut |revision, ln| {
+        if revision.is_some() && revision != cfg {
+            return;
+        }
+        ignore = match config.parse_cfg_name_directive(ln, "ignore") {
+            ParsedNameDirective::Match => true,
+            ParsedNameDirective::NoMatch => ignore,
+        };
+        if config.has_cfg_prefix(ln, "only") {
+            ignore = match config.parse_cfg_name_directive(ln, "only") {
+                ParsedNameDirective::Match => ignore,
+                ParsedNameDirective::NoMatch => true,
+            };
+        }
+        ignore |= ignore_llvm(config, ln);
+        ignore |=
+            config.run_clang_based_tests_with.is_none() && config.parse_needs_matching_clang(ln);
+        ignore |= !has_asm_support && config.parse_name_directive(ln, "needs-asm-support");
+        ignore |= !rustc_has_profiler_support && config.parse_needs_profiler_support(ln);
+        ignore |= !config.run_enabled() && config.parse_name_directive(ln, "needs-run-enabled");
+        ignore |= !rustc_has_sanitizer_support
+            && config.parse_name_directive(ln, "needs-sanitizer-support");
+        ignore |= !has_asan && config.parse_name_directive(ln, "needs-sanitizer-address");
+        ignore |= !has_lsan && config.parse_name_directive(ln, "needs-sanitizer-leak");
+        ignore |= !has_msan && config.parse_name_directive(ln, "needs-sanitizer-memory");
+        ignore |= !has_tsan && config.parse_name_directive(ln, "needs-sanitizer-thread");
+        ignore |= !has_hwasan && config.parse_name_directive(ln, "needs-sanitizer-hwaddress");
+        ignore |= config.target_panic == PanicStrategy::Abort
+            && config.parse_name_directive(ln, "needs-unwind");
+        ignore |= config.target == "wasm32-unknown-unknown" && config.parse_check_run_results(ln);
+        ignore |= config.debugger == Some(Debugger::Cdb) && ignore_cdb(config, ln);
+        ignore |= config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln);
+        ignore |= config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln);
+        ignore |= !has_rust_lld && config.parse_name_directive(ln, "needs-rust-lld");
+        should_fail |= config.parse_name_directive(ln, "should-fail");
+    });
+
+    // The `should-fail` annotation doesn't apply to pretty tests,
+    // since we run the pretty printer across all tests by default.
+    // If desired, we could add a `should-fail-pretty` annotation.
+    let should_panic = match config.mode {
+        crate::common::Pretty => test::ShouldPanic::No,
+        _ if should_fail => test::ShouldPanic::Yes,
+        _ => test::ShouldPanic::No,
+    };
+
+    test::TestDesc {
+        name,
+        ignore,
+        should_panic,
+        allow_fail: false,
+        compile_fail: false,
+        no_run: false,
+        test_type: test::TestType::Unknown,
+    }
+}
+
+fn ignore_cdb(config: &Config, line: &str) -> bool {
+    if let Some(actual_version) = config.cdb_version {
+        if let Some(min_version) = line.strip_prefix("min-cdb-version:").map(str::trim) {
+            let min_version = extract_cdb_version(min_version).unwrap_or_else(|| {
+                panic!("couldn't parse version range: {:?}", min_version);
+            });
+
+            // Ignore if actual version is smaller than the minimum
+            // required version
+            return actual_version < min_version;
+        }
+    }
+    false
+}
+
+fn ignore_gdb(config: &Config, line: &str) -> bool {
+    if let Some(actual_version) = config.gdb_version {
+        if let Some(rest) = line.strip_prefix("min-gdb-version:").map(str::trim) {
+            let (start_ver, end_ver) = extract_version_range(rest, extract_gdb_version)
+                .unwrap_or_else(|| {
+                    panic!("couldn't parse version range: {:?}", rest);
+                });
+
+            if start_ver != end_ver {
+                panic!("Expected single GDB version")
+            }
+            // Ignore if actual version is smaller than the minimum
+            // required version
+            return actual_version < start_ver;
+        } else if let Some(rest) = line.strip_prefix("ignore-gdb-version:").map(str::trim) {
+            let (min_version, max_version) = extract_version_range(rest, extract_gdb_version)
+                .unwrap_or_else(|| {
+                    panic!("couldn't parse version range: {:?}", rest);
+                });
+
+            if max_version < min_version {
+                panic!("Malformed GDB version range: max < min")
+            }
+
+            return actual_version >= min_version && actual_version <= max_version;
+        }
+    }
+    false
+}
+
+fn ignore_lldb(config: &Config, line: &str) -> bool {
+    if let Some(actual_version) = config.lldb_version {
+        if let Some(min_version) = line.strip_prefix("min-lldb-version:").map(str::trim) {
+            let min_version = min_version.parse().unwrap_or_else(|e| {
+                panic!("Unexpected format of LLDB version string: {}\n{:?}", min_version, e);
+            });
+            // Ignore if actual version is smaller the minimum required
+            // version
+            actual_version < min_version
+        } else {
+            line.starts_with("rust-lldb") && !config.lldb_native_rust
+        }
+    } else {
+        false
+    }
+}
+
+fn ignore_llvm(config: &Config, line: &str) -> bool {
+    if config.system_llvm && line.starts_with("no-system-llvm") {
+        return true;
+    }
+    if let Some(needed_components) =
+        config.parse_name_value_directive(line, "needs-llvm-components")
+    {
+        let components: HashSet<_> = config.llvm_components.split_whitespace().collect();
+        if let Some(missing_component) = needed_components
+            .split_whitespace()
+            .find(|needed_component| !components.contains(needed_component))
+        {
+            if env::var_os("COMPILETEST_NEEDS_ALL_LLVM_COMPONENTS").is_some() {
+                panic!("missing LLVM component: {}", missing_component);
+            }
+            return true;
+        }
+    }
+    if let Some(actual_version) = config.llvm_version {
+        if let Some(rest) = line.strip_prefix("min-llvm-version:").map(str::trim) {
+            let min_version = extract_llvm_version(rest).unwrap();
+            // Ignore if actual version is smaller the minimum required
+            // version
+            actual_version < min_version
+        } else if let Some(rest) = line.strip_prefix("min-system-llvm-version:").map(str::trim) {
+            let min_version = extract_llvm_version(rest).unwrap();
+            // Ignore if using system LLVM and actual version
+            // is smaller the minimum required version
+            config.system_llvm && actual_version < min_version
+        } else if let Some(rest) = line.strip_prefix("ignore-llvm-version:").map(str::trim) {
+            // Syntax is: "ignore-llvm-version: <version1> [- <version2>]"
+            let (v_min, v_max) =
+                extract_version_range(rest, extract_llvm_version).unwrap_or_else(|| {
+                    panic!("couldn't parse version range: {:?}", rest);
+                });
+            if v_max < v_min {
+                panic!("Malformed LLVM version range: max < min")
+            }
+            // Ignore if version lies inside of range.
+            actual_version >= v_min && actual_version <= v_max
+        } else {
+            false
+        }
+    } else {
+        false
+    }
+}
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index 2c607b6a50e..2485dbadab5 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -1,7 +1,7 @@
 use std::path::Path;
 
 use crate::common::{Config, Debugger};
-use crate::header::{parse_normalization_string, EarlyProps};
+use crate::header::{make_test_description, parse_normalization_string, EarlyProps};
 
 #[test]
 fn test_parse_normalization_string() {
@@ -66,6 +66,13 @@ fn parse_rs(config: &Config, contents: &str) -> EarlyProps {
     EarlyProps::from_reader(config, Path::new("a.rs"), bytes)
 }
 
+fn check_ignore(config: &Config, contents: &str) -> bool {
+    let tn = test::DynTestName(String::new());
+    let p = Path::new("a.rs");
+    let d = make_test_description(&config, tn, p, std::io::Cursor::new(contents), None);
+    d.ignore
+}
+
 fn parse_makefile(config: &Config, contents: &str) -> EarlyProps {
     let bytes = contents.as_bytes();
     EarlyProps::from_reader(config, Path::new("Makefile"), bytes)
@@ -74,9 +81,13 @@ fn parse_makefile(config: &Config, contents: &str) -> EarlyProps {
 #[test]
 fn should_fail() {
     let config = config();
+    let tn = test::DynTestName(String::new());
+    let p = Path::new("a.rs");
 
-    assert!(!parse_rs(&config, "").should_fail);
-    assert!(parse_rs(&config, "// should-fail").should_fail);
+    let d = make_test_description(&config, tn.clone(), p, std::io::Cursor::new(""), None);
+    assert_eq!(d.should_panic, test::ShouldPanic::No);
+    let d = make_test_description(&config, tn, p, std::io::Cursor::new("// should-fail"), None);
+    assert_eq!(d.should_panic, test::ShouldPanic::Yes);
 }
 
 #[test]
@@ -112,10 +123,10 @@ fn no_system_llvm() {
     let mut config = config();
 
     config.system_llvm = false;
-    assert!(!parse_rs(&config, "// no-system-llvm").ignore);
+    assert!(!check_ignore(&config, "// no-system-llvm"));
 
     config.system_llvm = true;
-    assert!(parse_rs(&config, "// no-system-llvm").ignore);
+    assert!(check_ignore(&config, "// no-system-llvm"));
 }
 
 #[test]
@@ -123,16 +134,16 @@ fn llvm_version() {
     let mut config = config();
 
     config.llvm_version = Some(80102);
-    assert!(parse_rs(&config, "// min-llvm-version: 9.0").ignore);
+    assert!(check_ignore(&config, "// min-llvm-version: 9.0"));
 
     config.llvm_version = Some(90001);
-    assert!(parse_rs(&config, "// min-llvm-version: 9.2").ignore);
+    assert!(check_ignore(&config, "// min-llvm-version: 9.2"));
 
     config.llvm_version = Some(90301);
-    assert!(!parse_rs(&config, "// min-llvm-version: 9.2").ignore);
+    assert!(!check_ignore(&config, "// min-llvm-version: 9.2"));
 
     config.llvm_version = Some(100000);
-    assert!(!parse_rs(&config, "// min-llvm-version: 9.0").ignore);
+    assert!(!check_ignore(&config, "// min-llvm-version: 9.0"));
 }
 
 #[test]
@@ -140,16 +151,16 @@ fn ignore_target() {
     let mut config = config();
     config.target = "x86_64-unknown-linux-gnu".to_owned();
 
-    assert!(parse_rs(&config, "// ignore-x86_64-unknown-linux-gnu").ignore);
-    assert!(parse_rs(&config, "// ignore-x86_64").ignore);
-    assert!(parse_rs(&config, "// ignore-linux").ignore);
-    assert!(parse_rs(&config, "// ignore-gnu").ignore);
-    assert!(parse_rs(&config, "// ignore-64bit").ignore);
+    assert!(check_ignore(&config, "// ignore-x86_64-unknown-linux-gnu"));
+    assert!(check_ignore(&config, "// ignore-x86_64"));
+    assert!(check_ignore(&config, "// ignore-linux"));
+    assert!(check_ignore(&config, "// ignore-gnu"));
+    assert!(check_ignore(&config, "// ignore-64bit"));
 
-    assert!(!parse_rs(&config, "// ignore-i686").ignore);
-    assert!(!parse_rs(&config, "// ignore-windows").ignore);
-    assert!(!parse_rs(&config, "// ignore-msvc").ignore);
-    assert!(!parse_rs(&config, "// ignore-32bit").ignore);
+    assert!(!check_ignore(&config, "// ignore-i686"));
+    assert!(!check_ignore(&config, "// ignore-windows"));
+    assert!(!check_ignore(&config, "// ignore-msvc"));
+    assert!(!check_ignore(&config, "// ignore-32bit"));
 }
 
 #[test]
@@ -157,16 +168,16 @@ fn only_target() {
     let mut config = config();
     config.target = "x86_64-pc-windows-gnu".to_owned();
 
-    assert!(parse_rs(&config, "// only-i686").ignore);
-    assert!(parse_rs(&config, "// only-linux").ignore);
-    assert!(parse_rs(&config, "// only-msvc").ignore);
-    assert!(parse_rs(&config, "// only-32bit").ignore);
+    assert!(check_ignore(&config, "// only-i686"));
+    assert!(check_ignore(&config, "// only-linux"));
+    assert!(check_ignore(&config, "// only-msvc"));
+    assert!(check_ignore(&config, "// only-32bit"));
 
-    assert!(!parse_rs(&config, "// only-x86_64-pc-windows-gnu").ignore);
-    assert!(!parse_rs(&config, "// only-x86_64").ignore);
-    assert!(!parse_rs(&config, "// only-windows").ignore);
-    assert!(!parse_rs(&config, "// only-gnu").ignore);
-    assert!(!parse_rs(&config, "// only-64bit").ignore);
+    assert!(!check_ignore(&config, "// only-x86_64-pc-windows-gnu"));
+    assert!(!check_ignore(&config, "// only-x86_64"));
+    assert!(!check_ignore(&config, "// only-windows"));
+    assert!(!check_ignore(&config, "// only-gnu"));
+    assert!(!check_ignore(&config, "// only-64bit"));
 }
 
 #[test]
@@ -174,8 +185,8 @@ fn stage() {
     let mut config = config();
     config.stage_id = "stage1".to_owned();
 
-    assert!(parse_rs(&config, "// ignore-stage1").ignore);
-    assert!(!parse_rs(&config, "// ignore-stage2").ignore);
+    assert!(check_ignore(&config, "// ignore-stage1"));
+    assert!(!check_ignore(&config, "// ignore-stage2"));
 }
 
 #[test]
@@ -183,26 +194,26 @@ fn cross_compile() {
     let mut config = config();
     config.host = "x86_64-apple-darwin".to_owned();
     config.target = "wasm32-unknown-unknown".to_owned();
-    assert!(parse_rs(&config, "// ignore-cross-compile").ignore);
+    assert!(check_ignore(&config, "// ignore-cross-compile"));
 
     config.target = config.host.clone();
-    assert!(!parse_rs(&config, "// ignore-cross-compile").ignore);
+    assert!(!check_ignore(&config, "// ignore-cross-compile"));
 }
 
 #[test]
 fn debugger() {
     let mut config = config();
     config.debugger = None;
-    assert!(!parse_rs(&config, "// ignore-cdb").ignore);
+    assert!(!check_ignore(&config, "// ignore-cdb"));
 
     config.debugger = Some(Debugger::Cdb);
-    assert!(parse_rs(&config, "// ignore-cdb").ignore);
+    assert!(check_ignore(&config, "// ignore-cdb"));
 
     config.debugger = Some(Debugger::Gdb);
-    assert!(parse_rs(&config, "// ignore-gdb").ignore);
+    assert!(check_ignore(&config, "// ignore-gdb"));
 
     config.debugger = Some(Debugger::Lldb);
-    assert!(parse_rs(&config, "// ignore-lldb").ignore);
+    assert!(check_ignore(&config, "// ignore-lldb"));
 }
 
 #[test]
@@ -211,17 +222,17 @@ fn sanitizers() {
 
     // Target that supports all sanitizers:
     config.target = "x86_64-unknown-linux-gnu".to_owned();
-    assert!(!parse_rs(&config, "// needs-sanitizer-address").ignore);
-    assert!(!parse_rs(&config, "// needs-sanitizer-leak").ignore);
-    assert!(!parse_rs(&config, "// needs-sanitizer-memory").ignore);
-    assert!(!parse_rs(&config, "// needs-sanitizer-thread").ignore);
+    assert!(!check_ignore(&config, "// needs-sanitizer-address"));
+    assert!(!check_ignore(&config, "// needs-sanitizer-leak"));
+    assert!(!check_ignore(&config, "// needs-sanitizer-memory"));
+    assert!(!check_ignore(&config, "// needs-sanitizer-thread"));
 
     // Target that doesn't support sanitizers:
     config.target = "wasm32-unknown-emscripten".to_owned();
-    assert!(parse_rs(&config, "// needs-sanitizer-address").ignore);
-    assert!(parse_rs(&config, "// needs-sanitizer-leak").ignore);
-    assert!(parse_rs(&config, "// needs-sanitizer-memory").ignore);
-    assert!(parse_rs(&config, "// needs-sanitizer-thread").ignore);
+    assert!(check_ignore(&config, "// needs-sanitizer-address"));
+    assert!(check_ignore(&config, "// needs-sanitizer-leak"));
+    assert!(check_ignore(&config, "// needs-sanitizer-memory"));
+    assert!(check_ignore(&config, "// needs-sanitizer-thread"));
 }
 
 #[test]
@@ -229,10 +240,10 @@ fn asm_support() {
     let mut config = config();
 
     config.target = "avr-unknown-gnu-atmega328".to_owned();
-    assert!(parse_rs(&config, "// needs-asm-support").ignore);
+    assert!(check_ignore(&config, "// needs-asm-support"));
 
     config.target = "i686-unknown-netbsd".to_owned();
-    assert!(!parse_rs(&config, "// needs-asm-support").ignore);
+    assert!(!check_ignore(&config, "// needs-asm-support"));
 }
 
 #[test]
@@ -240,13 +251,13 @@ fn channel() {
     let mut config = config();
     config.channel = "beta".into();
 
-    assert!(parse_rs(&config, "// ignore-beta").ignore);
-    assert!(parse_rs(&config, "// only-nightly").ignore);
-    assert!(parse_rs(&config, "// only-stable").ignore);
+    assert!(check_ignore(&config, "// ignore-beta"));
+    assert!(check_ignore(&config, "// only-nightly"));
+    assert!(check_ignore(&config, "// only-stable"));
 
-    assert!(!parse_rs(&config, "// only-beta").ignore);
-    assert!(!parse_rs(&config, "// ignore-nightly").ignore);
-    assert!(!parse_rs(&config, "// ignore-stable").ignore);
+    assert!(!check_ignore(&config, "// only-beta"));
+    assert!(!check_ignore(&config, "// ignore-nightly"));
+    assert!(!check_ignore(&config, "// ignore-stable"));
 }
 
 #[test]
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index c854663706a..46432d5e4f5 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -8,7 +8,7 @@ extern crate test;
 use crate::common::{
     expected_output_path, output_base_dir, output_relative_path, PanicStrategy, UI_EXTENSIONS,
 };
-use crate::common::{CompareMode, Config, Debugger, Mode, PassMode, Pretty, TestPaths};
+use crate::common::{CompareMode, Config, Debugger, Mode, PassMode, TestPaths};
 use crate::util::logv;
 use getopts::Options;
 use std::env;
@@ -22,7 +22,7 @@ use test::ColorConfig;
 use tracing::*;
 use walkdir::WalkDir;
 
-use self::header::EarlyProps;
+use self::header::{make_test_description, EarlyProps};
 
 #[cfg(test)]
 mod tests;
@@ -620,26 +620,13 @@ pub fn is_test(file_name: &OsString) -> bool {
 }
 
 fn make_test(config: &Config, testpaths: &TestPaths, inputs: &Stamp) -> Vec<test::TestDescAndFn> {
-    let early_props = if config.mode == Mode::RunMake {
-        // Allow `ignore` directives to be in the Makefile.
-        EarlyProps::from_file(config, &testpaths.file.join("Makefile"))
+    let test_path = if config.mode == Mode::RunMake {
+        // Parse directives in the Makefile
+        testpaths.file.join("Makefile")
     } else {
-        EarlyProps::from_file(config, &testpaths.file)
-    };
-
-    // The `should-fail` annotation doesn't apply to pretty tests,
-    // since we run the pretty printer across all tests by default.
-    // If desired, we could add a `should-fail-pretty` annotation.
-    let should_panic = match config.mode {
-        Pretty => test::ShouldPanic::No,
-        _ => {
-            if early_props.should_fail {
-                test::ShouldPanic::Yes
-            } else {
-                test::ShouldPanic::No
-            }
-        }
+        PathBuf::from(&testpaths.file)
     };
+    let early_props = EarlyProps::from_file(config, &test_path);
 
     // Incremental tests are special, they inherently cannot be run in parallel.
     // `runtest::run` will be responsible for iterating over revisions.
@@ -651,29 +638,20 @@ fn make_test(config: &Config, testpaths: &TestPaths, inputs: &Stamp) -> Vec<test
     revisions
         .into_iter()
         .map(|revision| {
-            let ignore = early_props.ignore
-                // Ignore tests that already run and are up to date with respect to inputs.
-                || is_up_to_date(
-                    config,
-                    testpaths,
-                    &early_props,
-                    revision.map(|s| s.as_str()),
-                    inputs,
-                );
-            test::TestDescAndFn {
-                desc: test::TestDesc {
-                    name: make_test_name(config, testpaths, revision),
-                    ignore,
-                    should_panic,
-                    allow_fail: false,
-                    #[cfg(not(bootstrap))]
-                    compile_fail: false,
-                    #[cfg(not(bootstrap))]
-                    no_run: false,
-                    test_type: test::TestType::Unknown,
-                },
-                testfn: make_test_closure(config, testpaths, revision),
-            }
+            let src_file =
+                std::fs::File::open(&test_path).expect("open test file to parse ignores");
+            let cfg = revision.map(|v| &**v);
+            let test_name = crate::make_test_name(config, testpaths, revision);
+            let mut desc = make_test_description(config, test_name, &test_path, src_file, cfg);
+            // Ignore tests that already run and are up to date with respect to inputs.
+            desc.ignore |= is_up_to_date(
+                config,
+                testpaths,
+                &early_props,
+                revision.map(|s| s.as_str()),
+                inputs,
+            );
+            test::TestDescAndFn { desc, testfn: make_test_closure(config, testpaths, revision) }
         })
         .collect()
 }
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 6a1faee1d8e..49731b2d7dc 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -778,6 +778,14 @@ impl<'test> TestCx<'test> {
         script_str.push_str("version\n"); // List CDB (and more) version info in test output
         script_str.push_str(".nvlist\n"); // List loaded `*.natvis` files, bulk of custom MSVC debug
 
+        // If a .js file exists next to the source file being tested, then this is a JavaScript
+        // debugging extension that needs to be loaded.
+        let mut js_extension = self.testpaths.file.clone();
+        js_extension.set_extension("cdb.js");
+        if js_extension.exists() {
+            script_str.push_str(&format!(".scriptload \"{}\"\n", js_extension.to_string_lossy()));
+        }
+
         // Set breakpoints on every line that contains the string "#break"
         let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy();
         for line in &breakpoint_lines {
@@ -2329,13 +2337,17 @@ impl<'test> TestCx<'test> {
         // useful flag.
         //
         // For now, though…
-        if let Some(rev) = self.revision {
-            let prefixes = format!("CHECK,{}", rev);
-            if self.config.llvm_version.unwrap_or(0) >= 130000 {
-                filecheck.args(&["--allow-unused-prefixes", "--check-prefixes", &prefixes]);
-            } else {
-                filecheck.args(&["--check-prefixes", &prefixes]);
-            }
+        let prefix_for_target =
+            if self.config.target.contains("msvc") { "MSVC" } else { "NONMSVC" };
+        let prefixes = if let Some(rev) = self.revision {
+            format!("CHECK,{},{}", prefix_for_target, rev)
+        } else {
+            format!("CHECK,{}", prefix_for_target)
+        };
+        if self.config.llvm_version.unwrap_or(0) >= 130000 {
+            filecheck.args(&["--allow-unused-prefixes", "--check-prefixes", &prefixes]);
+        } else {
+            filecheck.args(&["--check-prefixes", &prefixes]);
         }
         self.compose_and_run(filecheck, "", None, None)
     }
diff --git a/src/tools/html-checker/Cargo.toml b/src/tools/html-checker/Cargo.toml
new file mode 100644
index 00000000000..fe35df823b6
--- /dev/null
+++ b/src/tools/html-checker/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "html-checker"
+version = "0.1.0"
+authors = ["Guillaume Gomez <guillaume1.gomez@gmail.com>"]
+edition = "2018"
+
+[[bin]]
+name = "html-checker"
+path = "main.rs"
+
+[dependencies]
+walkdir = "2"
diff --git a/src/tools/html-checker/main.rs b/src/tools/html-checker/main.rs
new file mode 100644
index 00000000000..bf2830254e8
--- /dev/null
+++ b/src/tools/html-checker/main.rs
@@ -0,0 +1,93 @@
+use std::env;
+use std::path::Path;
+use std::process::{Command, Output};
+
+fn check_html_file(file: &Path) -> usize {
+    let to_mute = &[
+        // "disabled" on <link> or "autocomplete" on <select> emit this warning
+        "PROPRIETARY_ATTRIBUTE",
+        // It complains when multiple in the same page link to the same anchor for some reason...
+        "ANCHOR_NOT_UNIQUE",
+        // If a <span> contains only HTML elements and no text, it complains about it.
+        "TRIM_EMPTY_ELEMENT",
+        // FIXME: the three next warnings are about <pre> elements which are not supposed to
+        //        contain HTML. The solution here would be to replace them with a <div>
+        "MISSING_ENDTAG_BEFORE",
+        "INSERTING_TAG",
+        "DISCARDING_UNEXPECTED",
+    ];
+    let to_mute_s = to_mute.join(",");
+    let mut command = Command::new("tidy");
+    command
+        .arg("-errors")
+        .arg("-quiet")
+        .arg("--mute-id") // this option is useful in case we want to mute more warnings
+        .arg("yes")
+        .arg("--mute")
+        .arg(&to_mute_s)
+        .arg(file);
+
+    let Output { status, stderr, .. } = command.output().expect("failed to run tidy command");
+    if status.success() {
+        0
+    } else {
+        let stderr = String::from_utf8(stderr).expect("String::from_utf8 failed...");
+        if stderr.is_empty() && status.code() != Some(2) {
+            0
+        } else {
+            eprintln!(
+                "=> Errors for `{}` (error code: {}) <=",
+                file.display(),
+                status.code().unwrap_or(-1)
+            );
+            eprintln!("{}", stderr);
+            stderr.lines().count()
+        }
+    }
+}
+
+const DOCS_TO_CHECK: &[&str] =
+    &["alloc", "core", "proc_macro", "implementors", "src", "std", "test"];
+
+// Returns the number of files read and the number of errors.
+fn find_all_html_files(dir: &Path) -> (usize, usize) {
+    let mut files_read = 0;
+    let mut errors = 0;
+
+    for entry in walkdir::WalkDir::new(dir).into_iter().filter_entry(|e| {
+        e.depth() != 1
+            || e.file_name()
+                .to_str()
+                .map(|s| DOCS_TO_CHECK.into_iter().any(|d| *d == s))
+                .unwrap_or(false)
+    }) {
+        let entry = entry.expect("failed to read file");
+        if !entry.file_type().is_file() {
+            continue;
+        }
+        let entry = entry.path();
+        if entry.extension().and_then(|s| s.to_str()) == Some("html") {
+            errors += check_html_file(&entry);
+            files_read += 1;
+        }
+    }
+    (files_read, errors)
+}
+
+fn main() -> Result<(), String> {
+    let args = env::args().collect::<Vec<_>>();
+    if args.len() != 2 {
+        return Err(format!("Usage: {} <doc folder>", args[0]));
+    }
+
+    println!("Running HTML checker...");
+
+    let (files_read, errors) = find_all_html_files(&Path::new(&args[1]));
+    println!("Done! Read {} files...", files_read);
+    if errors > 0 {
+        Err(format!("HTML check failed: {} errors", errors))
+    } else {
+        println!("No error found!");
+        Ok(())
+    }
+}
diff --git a/src/tools/miri b/src/tools/miri
-Subproject 23f05fc603252b7906bd7e44208ab24038f8da1
+Subproject 05fdec916a3a9755c6ea603bab79cdb2f7c062b
diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer
-Subproject 13da28cc2bc1b59f7af817eca36927a71edb023
+Subproject 1fa82adfdca502a13f4dd952f9a50574870f5b7
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index 4a4b26da54c..26d6081c881 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -78,7 +78,7 @@ syn = { version = "1", features = ['fold', 'full', 'extra-traits', 'visit', 'vis
 url = { version = "2.0", features = ['serde'] }
 
 [target.'cfg(not(windows))'.dependencies]
-openssl = { version = "0.10.12", optional = true }
+openssl = { version = "0.10.35", optional = true }
 
 [features]
 all-static = ['openssl/vendored', 'curl-sys/static-curl', 'curl-sys/force-system-lib-on-osx']
diff --git a/src/tools/rustfmt/src/lib.rs b/src/tools/rustfmt/src/lib.rs
index cde5d390cf2..ce8a45eea65 100644
--- a/src/tools/rustfmt/src/lib.rs
+++ b/src/tools/rustfmt/src/lib.rs
@@ -1,6 +1,7 @@
 #![feature(rustc_private)]
 #![deny(rust_2018_idioms)]
 #![warn(unreachable_pub)]
+#![recursion_limit = "256"]
 
 #[macro_use]
 extern crate derive_new;
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index a7e700b935e..338dfd11310 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -301,6 +301,7 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features
             let mut parts = line.split(',');
             let level = match parts.next().map(|l| l.trim().trim_start_matches('(')) {
                 Some("active") => Status::Unstable,
+                Some("incomplete") => Status::Unstable,
                 Some("removed") => Status::Removed,
                 Some("accepted") => Status::Stable,
                 _ => return None,
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index fcb27dae9ea..a1c41eb9981 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -47,6 +47,7 @@ pub mod extdeps;
 pub mod features;
 pub mod pal;
 pub mod style;
+pub mod target_specific_tests;
 pub mod ui_tests;
 pub mod unit_tests;
 pub mod unstable_book;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index 10356a2fdc5..440c352ea53 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -55,6 +55,8 @@ fn main() {
             }
         }
 
+        check!(target_specific_tests, &src_path);
+
         // Checks that are done on the cargo workspace.
         check!(deps, &root_path, &cargo);
         check!(extdeps, &root_path);
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 3d5f39e8c90..15ed2f7a0a9 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -52,6 +52,7 @@ const ANNOTATIONS_TO_IGNORE: &[&str] = &[
     "// error-pattern",
     "// gdb",
     "// lldb",
+    "// cdb",
     "// normalize-stderr-test",
 ];
 
diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs
new file mode 100644
index 00000000000..8e1749196d2
--- /dev/null
+++ b/src/tools/tidy/src/target_specific_tests.rs
@@ -0,0 +1,96 @@
+//! Tidy check to ensure that all target specific tests (those that require a `--target` flag)
+//! also require the pre-requisite LLVM components to run.
+
+use std::collections::BTreeMap;
+use std::path::Path;
+
+const COMMENT: &str = "//";
+const LLVM_COMPONENTS_HEADER: &str = "needs-llvm-components:";
+const COMPILE_FLAGS_HEADER: &str = "compile-flags:";
+
+/// Iterate through compiletest headers in a test contents.
+///
+/// Adjusted from compiletest/src/header.rs.
+fn iter_header<'a>(contents: &'a str, it: &mut dyn FnMut(Option<&'a str>, &'a str)) {
+    for ln in contents.lines() {
+        let ln = ln.trim();
+        if ln.starts_with(COMMENT) && ln[COMMENT.len()..].trim_start().starts_with('[') {
+            if let Some(close_brace) = ln.find(']') {
+                let open_brace = ln.find('[').unwrap();
+                let lncfg = &ln[open_brace + 1..close_brace];
+                it(Some(lncfg), ln[(close_brace + 1)..].trim_start());
+            } else {
+                panic!("malformed condition directive: expected `//[foo]`, found `{}`", ln)
+            }
+        } else if ln.starts_with(COMMENT) {
+            it(None, ln[COMMENT.len()..].trim_start());
+        }
+    }
+}
+
+#[derive(Default, Debug)]
+struct RevisionInfo<'a> {
+    target_arch: Option<&'a str>,
+    llvm_components: Option<Vec<&'a str>>,
+}
+
+pub fn check(path: &Path, bad: &mut bool) {
+    let tests = path.join("test");
+    super::walk(
+        &tests,
+        &mut |path| path.extension().map(|p| p == "rs") == Some(false),
+        &mut |entry, content| {
+            let file = entry.path().display();
+            let mut header_map = BTreeMap::new();
+            iter_header(content, &mut |cfg, directive| {
+                if let Some(value) = directive.strip_prefix(LLVM_COMPONENTS_HEADER) {
+                    let info = header_map.entry(cfg).or_insert(RevisionInfo::default());
+                    let comp_vec = info.llvm_components.get_or_insert(Vec::new());
+                    for component in value.split(' ') {
+                        let component = component.trim();
+                        if !component.is_empty() {
+                            comp_vec.push(component);
+                        }
+                    }
+                } else if directive.starts_with(COMPILE_FLAGS_HEADER) {
+                    let compile_flags = &directive[COMPILE_FLAGS_HEADER.len()..];
+                    if let Some((_, v)) = compile_flags.split_once("--target") {
+                        if let Some((arch, _)) =
+                            v.trim_start_matches(|c| c == ' ' || c == '=').split_once("-")
+                        {
+                            let info = header_map.entry(cfg).or_insert(RevisionInfo::default());
+                            info.target_arch.replace(arch);
+                        } else {
+                            eprintln!("{}: seems to have a malformed --target value", file);
+                            *bad = true;
+                        }
+                    }
+                }
+            });
+            for (rev, RevisionInfo { target_arch, llvm_components }) in &header_map {
+                let rev = rev.unwrap_or("[unspecified]");
+                match (target_arch, llvm_components) {
+                    (None, None) => {}
+                    (Some(_), None) => {
+                        eprintln!(
+                            "{}: revision {} should specify `{}` as it has `--target` set",
+                            file, rev, LLVM_COMPONENTS_HEADER
+                        );
+                        *bad = true;
+                    }
+                    (None, Some(_)) => {
+                        eprintln!(
+                            "{}: revision {} should not specify `{}` as it doesn't need `--target`",
+                            file, rev, LLVM_COMPONENTS_HEADER
+                        );
+                        *bad = true;
+                    }
+                    (Some(_), Some(_)) => {
+                        // FIXME: check specified components against the target architectures we
+                        // gathered.
+                    }
+                }
+            }
+        },
+    );
+}
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index f61295c8830..66d05d9f00e 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -7,8 +7,8 @@ use std::path::Path;
 
 const ENTRY_LIMIT: usize = 1000;
 // FIXME: The following limits should be reduced eventually.
-const ROOT_ENTRY_LIMIT: usize = 1371;
-const ISSUES_ENTRY_LIMIT: usize = 2559;
+const ROOT_ENTRY_LIMIT: usize = 1345;
+const ISSUES_ENTRY_LIMIT: usize = 2530;
 
 fn check_entries(path: &Path, bad: &mut bool) {
     let dirs = walkdir::WalkDir::new(&path.join("test/ui"))