about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorCorey Farwell <coreyf@rwell.org>2020-12-31 23:27:33 -0500
committerCorey Farwell <coreyf@rwell.org>2020-12-31 23:27:33 -0500
commitd482de30ea70d537dced8ec04a3903e3264cf106 (patch)
tree67d6cd380ef7a66e785a54993bb0ca93b07b43ec /src
parent26cc060756d0456b17fdc53ac5d34e7f7bdc873d (diff)
parent99ad5a1a2824fea1ecf60068fd3636beae7ea2da (diff)
downloadrust-d482de30ea70d537dced8ec04a3903e3264cf106.tar.gz
rust-d482de30ea70d537dced8ec04a3903e3264cf106.zip
Merge remote-tracking branch 'origin/master' into frewsxcv-san
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/CHANGELOG.md7
-rw-r--r--src/bootstrap/README.md1
-rw-r--r--src/bootstrap/bootstrap.py31
-rw-r--r--src/bootstrap/builder.rs17
-rw-r--r--src/bootstrap/compile.rs73
-rw-r--r--src/bootstrap/config.rs17
-rwxr-xr-xsrc/bootstrap/configure.py4
-rw-r--r--src/bootstrap/dist.rs1073
-rw-r--r--src/bootstrap/doc.rs17
-rw-r--r--src/bootstrap/download-ci-llvm-stamp2
-rw-r--r--src/bootstrap/flags.rs7
-rw-r--r--src/bootstrap/install.rs120
-rw-r--r--src/bootstrap/lib.rs26
-rw-r--r--src/bootstrap/mk/Makefile.in4
-rw-r--r--src/bootstrap/sanity.rs44
-rw-r--r--src/bootstrap/tarball.rs333
-rw-r--r--src/bootstrap/test.rs21
-rw-r--r--src/bootstrap/tool.rs37
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile9
-rw-r--r--src/ci/docker/host-x86_64/test-various/Dockerfile1
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile5
-rwxr-xr-xsrc/ci/pgo.sh47
-rwxr-xr-xsrc/ci/run.sh5
m---------src/doc/book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
-rw-r--r--src/doc/rustc/book.toml3
-rw-r--r--src/doc/rustdoc/book.toml3
-rw-r--r--src/doc/rustdoc/src/command-line-arguments.md20
-rw-r--r--src/doc/rustdoc/src/what-is-rustdoc.md2
-rw-r--r--src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md6
-rw-r--r--src/doc/unstable-book/src/language-features/const-fn.md23
-rw-r--r--src/doc/unstable-book/src/language-features/ffi-pure.md2
-rwxr-xr-xsrc/etc/generate-deriving-span-tests.py2
-rw-r--r--src/etc/natvis/intrinsic.natvis18
-rw-r--r--src/etc/natvis/liballoc.natvis46
-rw-r--r--src/etc/natvis/libcore.natvis26
-rw-r--r--src/etc/natvis/libstd.natvis8
-rw-r--r--src/librustdoc/clean/auto_trait.rs36
-rw-r--r--src/librustdoc/clean/blanket_impl.rs7
-rw-r--r--src/librustdoc/clean/inline.rs37
-rw-r--r--src/librustdoc/clean/mod.rs261
-rw-r--r--src/librustdoc/clean/simplify.rs5
-rw-r--r--src/librustdoc/clean/types.rs248
-rw-r--r--src/librustdoc/clean/utils.rs92
-rw-r--r--src/librustdoc/config.rs15
-rw-r--r--src/librustdoc/core.rs122
-rw-r--r--src/librustdoc/doctest.rs76
-rw-r--r--src/librustdoc/doctest/tests.rs69
-rw-r--r--src/librustdoc/doctree.rs4
-rw-r--r--src/librustdoc/fold.rs12
-rw-r--r--src/librustdoc/formats/cache.rs64
-rw-r--r--src/librustdoc/formats/item_type.rs2
-rw-r--r--src/librustdoc/formats/mod.rs2
-rw-r--r--src/librustdoc/formats/renderer.rs13
-rw-r--r--src/librustdoc/html/format.rs95
-rw-r--r--src/librustdoc/html/highlight.rs37
-rw-r--r--src/librustdoc/html/highlight/tests.rs5
-rw-r--r--src/librustdoc/html/layout.rs2
-rw-r--r--src/librustdoc/html/markdown.rs99
-rw-r--r--src/librustdoc/html/markdown/tests.rs131
-rw-r--r--src/librustdoc/html/render/cache.rs20
-rw-r--r--src/librustdoc/html/render/mod.rs458
-rw-r--r--src/librustdoc/html/sources.rs36
-rw-r--r--src/librustdoc/html/static/main.js15
-rw-r--r--src/librustdoc/html/static/noscript.css10
-rw-r--r--src/librustdoc/html/static/rustdoc.css45
-rw-r--r--src/librustdoc/html/static/themes/ayu.css14
-rw-r--r--src/librustdoc/html/static/themes/dark.css11
-rw-r--r--src/librustdoc/html/static/themes/light.css11
-rw-r--r--src/librustdoc/json/conversions.rs123
-rw-r--r--src/librustdoc/json/mod.rs23
-rw-r--r--src/librustdoc/lib.rs126
-rw-r--r--src/librustdoc/passes/calculate_doc_coverage.rs21
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs609
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs70
-rw-r--r--src/librustdoc/passes/doc_test_lints.rs27
-rw-r--r--src/librustdoc/passes/strip_hidden.rs4
-rw-r--r--src/librustdoc/passes/stripper.rs12
-rw-r--r--src/librustdoc/visit_ast.rs6
m---------src/llvm-project0
-rw-r--r--src/stage0.txt2
-rw-r--r--src/test/codegen/slice-ref-equality.rs16
-rw-r--r--src/test/codegen/transmute-scalar.rs85
-rw-r--r--src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs15
-rw-r--r--src/test/compile-fail/auxiliary/panic-runtime-unwind.rs17
-rw-r--r--src/test/compile-fail/auxiliary/panic-runtime-unwind2.rs17
-rw-r--r--src/test/compile-fail/auxiliary/some-panic-impl.rs11
-rw-r--r--src/test/compile-fail/auxiliary/wants-panic-runtime-unwind.rs6
-rw-r--r--src/test/compile-fail/runtime-depend-on-needs-runtime.stderr4
-rw-r--r--src/test/debuginfo/pretty-std-collections-hash.rs8
-rw-r--r--src/test/debuginfo/pretty-std.rs14
-rw-r--r--src/test/incremental/auxiliary/issue-79890.rs1
-rw-r--r--src/test/incremental/issue-79890-imported-crates-changed.rs7
-rw-r--r--src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff115
-rw-r--r--src/test/mir-opt/const_debuginfo.rs24
-rw-r--r--src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff3
-rw-r--r--src/test/mir-opt/const_prop/indirect.main.ConstProp.diff3
-rw-r--r--src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff3
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff3
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff3
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff3
-rw-r--r--src/test/mir-opt/const_prop/return_place.add.ConstProp.diff3
-rw-r--r--src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff3
-rw-r--r--src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot2
-rw-r--r--src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot2
-rw-r--r--src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff2
-rw-r--r--src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff8
-rw-r--r--src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff128
-rw-r--r--src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff32
-rw-r--r--src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff4
-rw-r--r--src/test/mir-opt/lower_intrinsics.rs20
-rw-r--r--src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff4
-rw-r--r--src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff4
-rw-r--r--src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff4
-rw-r--r--src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff3
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/Makefile157
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.abort.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.async.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.closure.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.conditions.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.dead_code.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.drop_trait.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.generics.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if_else.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.inner_items.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.lazy_boolean.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loop_break_value.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loops_branches.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.nested_loops.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.partial_eq.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_loop.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_match.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.tight_inf_loop.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.try_error_result.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.uses_crate.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while_early_ret.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.yield.json59
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt8
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt79
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt50
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt10
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt8
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt4
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.abort.txt67
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt57
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt311
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.closure.txt153
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.conditions.txt253
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.dead_code.txt47
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.drop_trait.txt18
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.generics.txt44
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if.txt17
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if_else.txt30
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.inner_items.txt44
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.lazy_boolean.txt111
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loop_break_value.txt6
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loops_branches.txt33
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.nested_loops.txt58
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt52
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt53
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.partial_eq.txt66
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_loop.txt29
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_match.txt45
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.tight_inf_loop.txt10
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.try_error_result.txt63
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.uses_crate.txt110
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while.txt18
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while_early_ret.txt38
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.yield.txt94
-rwxr-xr-xsrc/test/run-make-fulldeps/coverage-reports/normalize_paths.py12
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/prettify_json.py9
-rw-r--r--src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html127
-rw-r--r--src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html173
-rw-r--r--src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html271
-rw-r--r--src/test/run-make-fulldeps/coverage/compiletest-ignore-dir4
-rw-r--r--src/test/run-make-fulldeps/coverage/coverage_tools.mk4
-rw-r--r--src/test/run-make-fulldeps/coverage/doctest.rs66
-rw-r--r--src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs9
-rw-r--r--src/test/run-make-fulldeps/coverage/match_or_pattern.rs45
-rw-r--r--src/test/run-make-fulldeps/many-crates-but-no-match/Makefile7
-rw-r--r--src/test/run-make-fulldeps/separate-link/Makefile6
-rw-r--r--src/test/run-make-fulldeps/split-dwarf/Makefile8
-rw-r--r--src/test/run-make-fulldeps/split-dwarf/foo.rs1
-rw-r--r--src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs2
-rw-r--r--src/test/rustdoc-ui/auxiliary/issue-61592.rs3
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/const-generics.rs1
-rw-r--r--src/test/rustdoc-ui/intra-doc/non-path-primitives.rs34
-rw-r--r--src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr69
-rw-r--r--src/test/rustdoc-ui/issue-61592-2.rs10
-rw-r--r--src/test/rustdoc-ui/issue-61592-2.stderr12
-rw-r--r--src/test/rustdoc-ui/issue-61592.rs8
-rw-r--r--src/test/rustdoc-ui/issue-61592.stderr11
-rw-r--r--src/test/rustdoc-ui/reference-link-has-one-warning.rs6
-rw-r--r--src/test/rustdoc-ui/reference-link-has-one-warning.stderr10
-rw-r--r--src/test/rustdoc-ui/reference-links.rs7
-rw-r--r--src/test/rustdoc-ui/reference-links.stderr20
-rw-r--r--src/test/rustdoc/async-fn.rs46
-rw-r--r--src/test/rustdoc/auxiliary/issue-61592.rs4
-rw-r--r--src/test/rustdoc/codeblock-title.rs11
-rw-r--r--src/test/rustdoc/const-generics/auxiliary/extern_crate.rs2
-rw-r--r--src/test/rustdoc/const-generics/const-generics-docs.rs1
-rw-r--r--src/test/rustdoc/const-generics/type-alias.rs1
-rw-r--r--src/test/rustdoc/doc-cfg.rs3
-rw-r--r--src/test/rustdoc/intra-doc/non-path-primitives.rs39
-rw-r--r--src/test/rustdoc/intra-link-self-cache.rs14
-rw-r--r--src/test/rustdoc/issue-61592.rs15
-rw-r--r--src/test/rustdoc/issue-79201.rs41
-rw-r--r--src/test/rustdoc/pub-restricted.rs32
-rw-r--r--src/test/rustdoc/rustc_deprecated-future.rs12
-rw-r--r--src/test/rustdoc/visibility.rs44
-rw-r--r--src/test/ui-fulldeps/dropck-tarena-cycle-checked.rs4
-rw-r--r--src/test/ui-fulldeps/dropck_tarena_sound_drop.rs2
-rw-r--r--src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs7
-rw-r--r--src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs7
-rw-r--r--src/test/ui/array-slice-vec/copy-out-of-array-1.rs2
-rw-r--r--src/test/ui/array-slice-vec/match_arr_unknown_len.stderr1
-rw-r--r--src/test/ui/array-slice-vec/nested-vec-3.rs7
-rw-r--r--src/test/ui/associated-consts/associated-const-type-parameter-arrays.rs5
-rw-r--r--src/test/ui/associated-consts/associated-const-type-parameter-arrays.stderr16
-rw-r--r--src/test/ui/associated-item/associated-item-duplicate-bounds.rs2
-rw-r--r--src/test/ui/associated-item/associated-item-duplicate-bounds.stderr10
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed2
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs2
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr3
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs8
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr9
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed4
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs4
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr5
-rw-r--r--src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs2
-rw-r--r--src/test/ui/associated-types/defaults-cyclic-fail-1.rs4
-rw-r--r--src/test/ui/associated-types/defaults-cyclic-fail-1.stderr10
-rw-r--r--src/test/ui/associated-types/defaults-cyclic-fail-2.rs4
-rw-r--r--src/test/ui/associated-types/defaults-cyclic-fail-2.stderr10
-rw-r--r--src/test/ui/associated-types/defaults-wf.stderr2
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-1.rs29
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-1.stderr39
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-2.rs16
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-2.stderr25
-rw-r--r--src/test/ui/associated-types/issue-23595-1.rs (renamed from src/test/compile-fail/issue-23595-1.rs)0
-rw-r--r--src/test/ui/associated-types/issue-23595-1.stderr16
-rw-r--r--src/test/ui/associated-types/issue-27675-unchecked-bounds.rs (renamed from src/test/compile-fail/issue-27675-unchecked-bounds.rs)0
-rw-r--r--src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr17
-rw-r--r--src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr2
-rw-r--r--src/test/ui/async-await/issue-75785-confusing-named-region.rs13
-rw-r--r--src/test/ui/async-await/issue-75785-confusing-named-region.stderr15
-rw-r--r--src/test/ui/async-await/issues/issue-78654.full.stderr4
-rw-r--r--src/test/ui/async-await/issues/issue-78654.min.stderr4
-rw-r--r--src/test/ui/async-await/issues/issue-78654.rs1
-rw-r--r--src/test/ui/bad/bad-sized.stderr2
-rw-r--r--src/test/ui/binding/const-param.full.stderr9
-rw-r--r--src/test/ui/binding/const-param.min.stderr9
-rw-r--r--src/test/ui/binding/const-param.rs5
-rw-r--r--src/test/ui/binding/const-param.stderr19
-rw-r--r--src/test/ui/binop/issue-77910-1.rs11
-rw-r--r--src/test/ui/binop/issue-77910-1.stderr26
-rw-r--r--src/test/ui/binop/issue-77910-2.rs9
-rw-r--r--src/test/ui/binop/issue-77910-2.stderr11
-rw-r--r--src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr2
-rw-r--r--src/test/ui/borrowck/mut-borrow-in-loop.stderr6
-rw-r--r--src/test/ui/borrowck/two-phase-across-loop.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs86
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr111
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/box.rs65
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr55
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.rs28
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr26
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.rs26
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr26
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/box.rs97
-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/capture-disjoint-field-struct.rs28
-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.rs23
-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.rs24
-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/disjoint-capture-in-same-closure.rs27
-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/filter-on-struct-member.rs41
-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/multilevel-path-1.rs36
-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.rs34
-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.rs31
-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/nested-closure.rs40
-rw-r--r--src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.stderr11
-rw-r--r--src/test/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.rs (renamed from src/test/compile-fail/coerce-unsafe-closure-to-unsafe-fn-ptr.rs)0
-rw-r--r--src/test/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.stderr11
-rw-r--r--src/test/ui/closures/coerce-unsafe-to-closure.rs (renamed from src/test/compile-fail/coerce-unsafe-to-closure.rs)0
-rw-r--r--src/test/ui/closures/coerce-unsafe-to-closure.stderr11
-rw-r--r--src/test/ui/const-generics/apit-with-const-param.rs1
-rw-r--r--src/test/ui/const-generics/arg-in-pat-1.rs23
-rw-r--r--src/test/ui/const-generics/arg-in-pat-2.rs10
-rw-r--r--src/test/ui/const-generics/arg-in-pat-3.rs43
-rw-r--r--src/test/ui/const-generics/argument_order.full.stderr4
-rw-r--r--src/test/ui/const-generics/argument_order.min.stderr8
-rw-r--r--src/test/ui/const-generics/argument_order.rs1
-rw-r--r--src/test/ui/const-generics/array-size-in-generic-struct-param.full.stderr4
-rw-r--r--src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr6
-rw-r--r--src/test/ui/const-generics/array-size-in-generic-struct-param.rs1
-rw-r--r--src/test/ui/const-generics/array-wrapper-struct-ctor.rs1
-rw-r--r--src/test/ui/const-generics/associated-type-bound-fail.full.stderr2
-rw-r--r--src/test/ui/const-generics/associated-type-bound-fail.min.stderr2
-rw-r--r--src/test/ui/const-generics/associated-type-bound-fail.rs1
-rw-r--r--src/test/ui/const-generics/associated-type-bound.rs1
-rw-r--r--src/test/ui/const-generics/auxiliary/const_generic_lib.rs1
-rw-r--r--src/test/ui/const-generics/auxiliary/crayte.rs1
-rw-r--r--src/test/ui/const-generics/auxiliary/impl-const.rs1
-rw-r--r--src/test/ui/const-generics/broken-mir-1.rs1
-rw-r--r--src/test/ui/const-generics/broken-mir-2.rs1
-rw-r--r--src/test/ui/const-generics/cannot-infer-type-for-const-param.rs1
-rw-r--r--src/test/ui/const-generics/closing-args-token.full.stderr10
-rw-r--r--src/test/ui/const-generics/closing-args-token.min.stderr10
-rw-r--r--src/test/ui/const-generics/closing-args-token.rs1
-rw-r--r--src/test/ui/const-generics/coerce_unsized_array.rs1
-rw-r--r--src/test/ui/const-generics/concrete-const-as-fn-arg.rs1
-rw-r--r--src/test/ui/const-generics/concrete-const-impl-method.rs1
-rw-r--r--src/test/ui/const-generics/condition-in-trait-const-arg.rs1
-rw-r--r--src/test/ui/const-generics/const-arg-in-const-arg.min.stderr46
-rw-r--r--src/test/ui/const-generics/const-arg-in-const-arg.rs1
-rw-r--r--src/test/ui/const-generics/const-arg-in-fn.rs1
-rw-r--r--src/test/ui/const-generics/const-arg-type-arg-misordered.full.stderr2
-rw-r--r--src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr2
-rw-r--r--src/test/ui/const-generics/const-arg-type-arg-misordered.rs1
-rw-r--r--src/test/ui/const-generics/const-argument-if-length.full.stderr4
-rw-r--r--src/test/ui/const-generics/const-argument-if-length.min.stderr4
-rw-r--r--src/test/ui/const-generics/const-argument-if-length.rs1
-rw-r--r--src/test/ui/const-generics/const-expression-parameter.full.stderr2
-rw-r--r--src/test/ui/const-generics/const-expression-parameter.min.stderr2
-rw-r--r--src/test/ui/const-generics/const-expression-parameter.rs1
-rw-r--r--src/test/ui/const-generics/const-fn-with-const-param.rs1
-rw-r--r--src/test/ui/const-generics/const-generic-array-wrapper.rs1
-rw-r--r--src/test/ui/const-generics/const-generic-type_name.rs1
-rw-r--r--src/test/ui/const-generics/const-param-after-const-literal-arg.rs1
-rw-r--r--src/test/ui/const-generics/const-param-before-other-params.full.stderr2
-rw-r--r--src/test/ui/const-generics/const-param-before-other-params.min.stderr8
-rw-r--r--src/test/ui/const-generics/const-param-before-other-params.rs1
-rw-r--r--src/test/ui/const-generics/const-param-elided-lifetime.full.stderr10
-rw-r--r--src/test/ui/const-generics/const-param-elided-lifetime.min.stderr20
-rw-r--r--src/test/ui/const-generics/const-param-elided-lifetime.rs1
-rw-r--r--src/test/ui/const-generics/const-param-from-outer-fn.full.stderr2
-rw-r--r--src/test/ui/const-generics/const-param-from-outer-fn.min.stderr2
-rw-r--r--src/test/ui/const-generics/const-param-from-outer-fn.rs1
-rw-r--r--src/test/ui/const-generics/const-param-hygiene.rs1
-rw-r--r--src/test/ui/const-generics/const-param-in-async.rs1
-rw-r--r--src/test/ui/const-generics/const-param-in-trait-ungated.rs3
-rw-r--r--src/test/ui/const-generics/const-param-in-trait-ungated.stderr12
-rw-r--r--src/test/ui/const-generics/const-param-in-trait.rs1
-rw-r--r--src/test/ui/const-generics/const-param-shadowing.rs2
-rw-r--r--src/test/ui/const-generics/const-param-shadowing.stderr2
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-const-param.full.stderr4
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-const-param.min.stderr8
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-const-param.rs1
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs2
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr14
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param.full.stderr4
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param.min.stderr4
-rw-r--r--src/test/ui/const-generics/const-param-type-depends-on-type-param.rs1
-rw-r--r--src/test/ui/const-generics/const-parameter-uppercase-lint.full.stderr4
-rw-r--r--src/test/ui/const-generics/const-parameter-uppercase-lint.min.stderr4
-rw-r--r--src/test/ui/const-generics/const-parameter-uppercase-lint.rs1
-rw-r--r--src/test/ui/const-generics/const-types.rs1
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.full.stderr2
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.min.stderr2
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs1
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/simple.min.stderr4
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/simple.rs1
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/simple_fail.full.stderr2
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/simple_fail.min.stderr2
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs1
-rw-r--r--src/test/ui/const-generics/core-types.rs1
-rw-r--r--src/test/ui/const-generics/cross_crate_complex.rs1
-rw-r--r--src/test/ui/const-generics/defaults/complex-unord-param.min.stderr4
-rw-r--r--src/test/ui/const-generics/defaults/complex-unord-param.rs1
-rw-r--r--src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr8
-rw-r--r--src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr16
-rw-r--r--src/test/ui/const-generics/defaults/intermixed-lifetime.rs1
-rw-r--r--src/test/ui/const-generics/defaults/needs-feature.min.stderr4
-rw-r--r--src/test/ui/const-generics/defaults/needs-feature.none.stderr16
-rw-r--r--src/test/ui/const-generics/defaults/needs-feature.rs7
-rw-r--r--src/test/ui/const-generics/defaults/simple-defaults.min.stderr4
-rw-r--r--src/test/ui/const-generics/defaults/simple-defaults.rs1
-rw-r--r--src/test/ui/const-generics/defaults/wrong-order.full.stderr3
-rw-r--r--src/test/ui/const-generics/defaults/wrong-order.min.stderr2
-rw-r--r--src/test/ui/const-generics/defaults/wrong-order.rs1
-rw-r--r--src/test/ui/const-generics/derive-debug-array-wrapper.rs1
-rw-r--r--src/test/ui/const-generics/different_byref.full.stderr2
-rw-r--r--src/test/ui/const-generics/different_byref.min.stderr2
-rw-r--r--src/test/ui/const-generics/different_byref.rs1
-rw-r--r--src/test/ui/const-generics/different_byref_simple.full.stderr2
-rw-r--r--src/test/ui/const-generics/different_byref_simple.min.stderr2
-rw-r--r--src/test/ui/const-generics/different_byref_simple.rs1
-rw-r--r--src/test/ui/const-generics/dyn-supertraits.rs1
-rw-r--r--src/test/ui/const-generics/exhaustive-value.full.stderr2
-rw-r--r--src/test/ui/const-generics/exhaustive-value.min.stderr2
-rw-r--r--src/test/ui/const-generics/exhaustive-value.rs1
-rw-r--r--src/test/ui/const-generics/fn-const-param-call.full.stderr4
-rw-r--r--src/test/ui/const-generics/fn-const-param-call.min.stderr4
-rw-r--r--src/test/ui/const-generics/fn-const-param-call.rs1
-rw-r--r--src/test/ui/const-generics/fn-const-param-infer.full.stderr2
-rw-r--r--src/test/ui/const-generics/fn-const-param-infer.min.stderr2
-rw-r--r--src/test/ui/const-generics/fn-const-param-infer.rs1
-rw-r--r--src/test/ui/const-generics/fn-taking-const-generic-array.rs1
-rw-r--r--src/test/ui/const-generics/forbid-non-structural_match-types.full.stderr2
-rw-r--r--src/test/ui/const-generics/forbid-non-structural_match-types.min.stderr6
-rw-r--r--src/test/ui/const-generics/forbid-non-structural_match-types.rs1
-rw-r--r--src/test/ui/const-generics/foreign-item-const-parameter.full.stderr4
-rw-r--r--src/test/ui/const-generics/foreign-item-const-parameter.min.stderr4
-rw-r--r--src/test/ui/const-generics/foreign-item-const-parameter.rs1
-rw-r--r--src/test/ui/const-generics/generic-function-call-in-array-length.full.stderr2
-rw-r--r--src/test/ui/const-generics/generic-function-call-in-array-length.min.stderr4
-rw-r--r--src/test/ui/const-generics/generic-function-call-in-array-length.rs1
-rw-r--r--src/test/ui/const-generics/generic-param-mismatch.full.stderr2
-rw-r--r--src/test/ui/const-generics/generic-param-mismatch.min.stderr2
-rw-r--r--src/test/ui/const-generics/generic-param-mismatch.rs1
-rw-r--r--src/test/ui/const-generics/generic-sum-in-array-length.full.stderr2
-rw-r--r--src/test/ui/const-generics/generic-sum-in-array-length.min.stderr4
-rw-r--r--src/test/ui/const-generics/generic-sum-in-array-length.rs1
-rw-r--r--src/test/ui/const-generics/impl-const-generic-struct.rs1
-rw-r--r--src/test/ui/const-generics/impl-trait-with-const-arguments.full.stderr2
-rw-r--r--src/test/ui/const-generics/impl-trait-with-const-arguments.min.stderr2
-rw-r--r--src/test/ui/const-generics/impl-trait-with-const-arguments.rs1
-rw-r--r--src/test/ui/const-generics/incorrect-number-of-const-args.full.stderr4
-rw-r--r--src/test/ui/const-generics/incorrect-number-of-const-args.min.stderr4
-rw-r--r--src/test/ui/const-generics/incorrect-number-of-const-args.rs1
-rw-r--r--src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr2
-rw-r--r--src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr2
-rw-r--r--src/test/ui/const-generics/infer/cannot-infer-const-args.rs1
-rw-r--r--src/test/ui/const-generics/infer/issue-77092.rs2
-rw-r--r--src/test/ui/const-generics/infer/issue-77092.stderr2
-rw-r--r--src/test/ui/const-generics/infer/method-chain.full.stderr2
-rw-r--r--src/test/ui/const-generics/infer/method-chain.min.stderr2
-rw-r--r--src/test/ui/const-generics/infer/method-chain.rs1
-rw-r--r--src/test/ui/const-generics/infer/uninferred-consts.full.stderr2
-rw-r--r--src/test/ui/const-generics/infer/uninferred-consts.min.stderr2
-rw-r--r--src/test/ui/const-generics/infer/uninferred-consts.rs1
-rw-r--r--src/test/ui/const-generics/infer_arg_from_pat.rs1
-rw-r--r--src/test/ui/const-generics/infer_arr_len_from_pat.rs1
-rw-r--r--src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs1
-rw-r--r--src/test/ui/const-generics/intrinsics-type_name-as-const-argument.full.stderr2
-rw-r--r--src/test/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr4
-rw-r--r--src/test/ui/const-generics/intrinsics-type_name-as-const-argument.rs1
-rw-r--r--src/test/ui/const-generics/issue-61522-array-len-succ.full.stderr4
-rw-r--r--src/test/ui/const-generics/issue-61522-array-len-succ.min.stderr4
-rw-r--r--src/test/ui/const-generics/issue-61522-array-len-succ.rs1
-rw-r--r--src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.min.stderr2
-rw-r--r--src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs1
-rw-r--r--src/test/ui/const-generics/issue-67375.full.stderr4
-rw-r--r--src/test/ui/const-generics/issue-67375.min.stderr4
-rw-r--r--src/test/ui/const-generics/issue-67375.rs1
-rw-r--r--src/test/ui/const-generics/issue-67945-1.full.stderr4
-rw-r--r--src/test/ui/const-generics/issue-67945-1.min.stderr6
-rw-r--r--src/test/ui/const-generics/issue-67945-1.rs1
-rw-r--r--src/test/ui/const-generics/issue-67945-2.full.stderr4
-rw-r--r--src/test/ui/const-generics/issue-67945-2.min.stderr6
-rw-r--r--src/test/ui/const-generics/issue-67945-2.rs1
-rw-r--r--src/test/ui/const-generics/issue-67945-3.full.stderr2
-rw-r--r--src/test/ui/const-generics/issue-67945-3.min.stderr2
-rw-r--r--src/test/ui/const-generics/issue-67945-3.rs1
-rw-r--r--src/test/ui/const-generics/issue-68104-print-stack-overflow.rs1
-rw-r--r--src/test/ui/const-generics/issue-70180-1-stalled_on.rs1
-rw-r--r--src/test/ui/const-generics/issue-70180-2-stalled_on.rs1
-rw-r--r--src/test/ui/const-generics/issue-71986.rs1
-rw-r--r--src/test/ui/const-generics/issue-74906.rs1
-rw-r--r--src/test/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-56445.full.stderr3
-rw-r--r--src/test/ui/const-generics/issues/issue-56445.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-56445.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-60263.rs9
-rw-r--r--src/test/ui/const-generics/issues/issue-60263.stderr12
-rw-r--r--src/test/ui/const-generics/issues/issue-60818-struct-constructors.full.stderr1
-rw-r--r--src/test/ui/const-generics/issues/issue-60818-struct-constructors.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-61336-1.full.stderr1
-rw-r--r--src/test/ui/const-generics/issues/issue-61336-1.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-61336-2.full.stderr3
-rw-r--r--src/test/ui/const-generics/issues/issue-61336-2.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-61336-2.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-61336.full.stderr3
-rw-r--r--src/test/ui/const-generics/issues/issue-61336.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-61336.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-61422.full.stderr1
-rw-r--r--src/test/ui/const-generics/issues/issue-61422.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-61432.full.stderr1
-rw-r--r--src/test/ui/const-generics/issues/issue-61432.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-61747.full.stderr3
-rw-r--r--src/test/ui/const-generics/issues/issue-61747.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-61747.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-61935.full.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-61935.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-61935.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-62220.full.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-62220.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-62220.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-62456.full.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-62456.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-62456.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-62504.full.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-62504.min.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-62504.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-62579-no-match.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-62579-no-match.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-62878.full.stderr6
-rw-r--r--src/test/ui/const-generics/issues/issue-62878.min.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-62878.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-64494.full.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-64494.min.stderr6
-rw-r--r--src/test/ui/const-generics/issues/issue-64494.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-64519.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-66205.full.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-66205.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-66205.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-66906.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-67185-1.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-67185-2.full.stderr12
-rw-r--r--src/test/ui/const-generics/issues/issue-67185-2.min.stderr12
-rw-r--r--src/test/ui/const-generics/issues/issue-67185-2.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-67739.full.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-67739.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-67739.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-68366.full.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-68366.min.stderr6
-rw-r--r--src/test/ui/const-generics/issues/issue-68366.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-68596.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-68615-adt.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-68615-adt.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-68615-array.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-68615-array.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-68977.full.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-68977.min.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-68977.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-70125-1.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-70125-2.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-70167.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-71169.full.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-71169.min.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-71169.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-71381.full.stderr8
-rw-r--r--src/test/ui/const-generics/issues/issue-71381.min.stderr8
-rw-r--r--src/test/ui/const-generics/issues/issue-71381.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-71382.full.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-71382.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-71382.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-71611.full.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-71611.min.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-71611.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-72352.full.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-72352.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-72352.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-72787.full.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-72787.min.stderr12
-rw-r--r--src/test/ui/const-generics/issues/issue-72787.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.full.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-73491.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-73491.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-73508.full.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-73508.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-73508.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-74101.min.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-74101.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-74255.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-74255.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-74950.min.stderr10
-rw-r--r--src/test/ui/const-generics/issues/issue-74950.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-75047.min.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-75047.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.full.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.min.stderr4
-rw-r--r--src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.rs1
-rw-r--r--src/test/ui/const-generics/issues/issue-80062.rs10
-rw-r--r--src/test/ui/const-generics/issues/issue-80062.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue-80375.rs4
-rw-r--r--src/test/ui/const-generics/issues/issue-80375.stderr11
-rw-r--r--src/test/ui/const-generics/issues/issue70273-assoc-fn.rs1
-rw-r--r--src/test/ui/const-generics/macro_rules-braces.full.stderr12
-rw-r--r--src/test/ui/const-generics/macro_rules-braces.min.stderr12
-rw-r--r--src/test/ui/const-generics/macro_rules-braces.rs1
-rw-r--r--src/test/ui/const-generics/min-and-full-same-time.rs7
-rw-r--r--src/test/ui/const-generics/min-and-full-same-time.stderr13
-rw-r--r--src/test/ui/const-generics/min_const_generics/assoc_const.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/complex-expression.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/complex-expression.stderr16
-rw-r--r--src/test/ui/const-generics/min_const_generics/complex-types.rs1
-rw-r--r--src/test/ui/const-generics/min_const_generics/complex-types.stderr14
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs1
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr6
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr26
-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.stderr30
-rw-r--r--src/test/ui/const-generics/min_const_generics/const_fn_in_generics.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/default_function_param.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/default_function_param.stderr2
-rw-r--r--src/test/ui/const-generics/min_const_generics/default_trait_param.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/default_trait_param.stderr2
-rw-r--r--src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.rs4
-rw-r--r--src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.stderr12
-rw-r--r--src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr4
-rw-r--r--src/test/ui/const-generics/min_const_generics/invalid-patterns.rs1
-rw-r--r--src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr16
-rw-r--r--src/test/ui/const-generics/min_const_generics/macro-fail.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/macro-fail.stderr16
-rw-r--r--src/test/ui/const-generics/min_const_generics/macro.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr6
-rw-r--r--src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr4
-rw-r--r--src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.stderr2
-rw-r--r--src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr2
-rw-r--r--src/test/ui/const-generics/mut-ref-const-param-array.rs1
-rw-r--r--src/test/ui/const-generics/nested-type.full.stderr2
-rw-r--r--src/test/ui/const-generics/nested-type.min.stderr4
-rw-r--r--src/test/ui/const-generics/nested-type.rs1
-rw-r--r--src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr1
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-5.rs20
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-5.stderr12
-rw-r--r--src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr6
-rw-r--r--src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr6
-rw-r--r--src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs1
-rw-r--r--src/test/ui/const-generics/promotion.rs2
-rw-r--r--src/test/ui/const-generics/raw-ptr-const-param-deref.full.stderr4
-rw-r--r--src/test/ui/const-generics/raw-ptr-const-param-deref.min.stderr4
-rw-r--r--src/test/ui/const-generics/raw-ptr-const-param-deref.rs1
-rw-r--r--src/test/ui/const-generics/raw-ptr-const-param.full.stderr2
-rw-r--r--src/test/ui/const-generics/raw-ptr-const-param.min.stderr2
-rw-r--r--src/test/ui/const-generics/raw-ptr-const-param.rs1
-rw-r--r--src/test/ui/const-generics/slice-const-param-mismatch.full.stderr6
-rw-r--r--src/test/ui/const-generics/slice-const-param-mismatch.min.stderr4
-rw-r--r--src/test/ui/const-generics/slice-const-param-mismatch.rs1
-rw-r--r--src/test/ui/const-generics/slice-const-param.min.stderr4
-rw-r--r--src/test/ui/const-generics/slice-const-param.rs1
-rw-r--r--src/test/ui/const-generics/std/const-generics-range.min.stderr12
-rw-r--r--src/test/ui/const-generics/std/const-generics-range.rs1
-rw-r--r--src/test/ui/const-generics/struct-with-invalid-const-param.full.stderr2
-rw-r--r--src/test/ui/const-generics/struct-with-invalid-const-param.min.stderr2
-rw-r--r--src/test/ui/const-generics/struct-with-invalid-const-param.rs1
-rw-r--r--src/test/ui/const-generics/trait-const-args.rs1
-rw-r--r--src/test/ui/const-generics/transparent-maybeunit-array-wrapper.rs1
-rw-r--r--src/test/ui/const-generics/type-after-const-ok.min.stderr2
-rw-r--r--src/test/ui/const-generics/type-after-const-ok.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-61936.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-63695.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-67144-1.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-67144-2.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-69816.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-70217.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-70507.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-70586.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71348.min.stderr4
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71348.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71382.full.stderr2
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71382.min.stderr2
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71382.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71805.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-73730.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/non-local.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/qpath.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/simple.rs1
-rw-r--r--src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr2
-rw-r--r--src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr2
-rw-r--r--src/test/ui/const-generics/type-dependent/type-mismatch.rs1
-rw-r--r--src/test/ui/const-generics/type_of_anon_const.rs1
-rw-r--r--src/test/ui/const-generics/types-mismatch-const-args.full.stderr4
-rw-r--r--src/test/ui/const-generics/types-mismatch-const-args.min.stderr4
-rw-r--r--src/test/ui/const-generics/types-mismatch-const-args.rs1
-rw-r--r--src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs1
-rw-r--r--src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs1
-rw-r--r--src/test/ui/const-generics/unknown_adt.full.stderr2
-rw-r--r--src/test/ui/const-generics/unknown_adt.min.stderr2
-rw-r--r--src/test/ui/const-generics/unknown_adt.rs1
-rw-r--r--src/test/ui/const-generics/unused-const-param.rs1
-rw-r--r--src/test/ui/const-generics/unused_braces.full.fixed1
-rw-r--r--src/test/ui/const-generics/unused_braces.full.stderr4
-rw-r--r--src/test/ui/const-generics/unused_braces.min.fixed1
-rw-r--r--src/test/ui/const-generics/unused_braces.min.stderr4
-rw-r--r--src/test/ui/const-generics/unused_braces.rs1
-rw-r--r--src/test/ui/const-generics/wf-misc.full.stderr4
-rw-r--r--src/test/ui/const-generics/wf-misc.min.stderr4
-rw-r--r--src/test/ui/const-generics/wf-misc.rs1
-rw-r--r--src/test/ui/const-generics/where-clauses.rs1
-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.stderr54
-rw-r--r--src/test/ui/consts/assume-type-intrinsics.rs13
-rw-r--r--src/test/ui/consts/assume-type-intrinsics.stderr21
-rw-r--r--src/test/ui/consts/const-fn-error.rs (renamed from src/test/compile-fail/consts/const-fn-error.rs)0
-rw-r--r--src/test/ui/consts/const-fn-error.stderr49
-rw-r--r--src/test/ui/consts/const-size_of_val-align_of_val.rs7
-rw-r--r--src/test/ui/consts/issue-44415.rs (renamed from src/test/compile-fail/issue-44415.rs)0
-rw-r--r--src/test/ui/consts/issue-44415.stderr28
-rw-r--r--src/test/ui/consts/issue-55878.rs (renamed from src/test/compile-fail/consts/issue-55878.rs)1
-rw-r--r--src/test/ui/consts/issue-55878.stderr25
-rw-r--r--src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr5
-rw-r--r--src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-repeat.rs27
-rw-r--r--src/test/ui/crate-loading/auxiliary/crateresolve1-1.rs (renamed from src/test/compile-fail/auxiliary/crateresolve1-1.rs)0
-rw-r--r--src/test/ui/crate-loading/auxiliary/crateresolve1-2.rs (renamed from src/test/compile-fail/auxiliary/crateresolve1-2.rs)0
-rw-r--r--src/test/ui/crate-loading/auxiliary/crateresolve1-3.rs (renamed from src/test/compile-fail/auxiliary/crateresolve1-3.rs)0
-rw-r--r--src/test/ui/crate-loading/crateresolve1.rs (renamed from src/test/compile-fail/crateresolve1.rs)1
-rw-r--r--src/test/ui/deprecation/rustc_deprecation-in-future.rs9
-rw-r--r--src/test/ui/deprecation/rustc_deprecation-in-future.stderr16
-rw-r--r--src/test/ui/dropck/dropck_trait_cycle_checked.rs2
-rw-r--r--src/test/ui/dropck/reject-specialized-drops-8142.rs2
-rw-r--r--src/test/ui/dropck/reject-specialized-drops-8142.stderr62
-rw-r--r--src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs2
-rw-r--r--src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr9
-rw-r--r--src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs2
-rw-r--r--src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr9
-rw-r--r--src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs4
-rw-r--r--src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr13
-rw-r--r--src/test/ui/enum/issue-67945-1.rs4
-rw-r--r--src/test/ui/enum/issue-67945-1.stderr27
-rw-r--r--src/test/ui/enum/issue-67945-2.rs5
-rw-r--r--src/test/ui/enum/issue-67945-2.stderr25
-rw-r--r--src/test/ui/error-codes/E0396.rs11
-rw-r--r--src/test/ui/error-codes/E0396.stderr20
-rw-r--r--src/test/ui/error-codes/E0730.stderr1
-rw-r--r--src/test/ui/error-codes/E0771.stderr1
-rw-r--r--src/test/ui/extern-flag/empty-extern-arg.rs (renamed from src/test/compile-fail/empty-extern-arg.rs)0
-rw-r--r--src/test/ui/extern-flag/empty-extern-arg.stderr4
-rw-r--r--src/test/ui/feature-gate-edition_macro_pats.rs8
-rw-r--r--src/test/ui/feature-gate-edition_macro_pats.stderr21
-rw-r--r--src/test/ui/feature-gates/feature-gate-const_generics-ptr.rs9
-rw-r--r--src/test/ui/feature-gates/feature-gate-const_generics-ptr.stderr33
-rw-r--r--src/test/ui/feature-gates/feature-gate-const_generics.rs4
-rw-r--r--src/test/ui/feature-gates/feature-gate-const_generics.stderr22
-rw-r--r--src/test/ui/fn/fn-recover-return-sign.fixed28
-rw-r--r--src/test/ui/fn/fn-recover-return-sign.rs28
-rw-r--r--src/test/ui/fn/fn-recover-return-sign.stderr26
-rw-r--r--src/test/ui/fn/fn-recover-return-sign2.rs8
-rw-r--r--src/test/ui/fn/fn-recover-return-sign2.stderr14
-rw-r--r--src/test/ui/fn/issue-80179.rs27
-rw-r--r--src/test/ui/fn/issue-80179.stderr21
-rw-r--r--src/test/ui/fsu-moves-and-copies.rs2
-rw-r--r--src/test/ui/functions-closures/closure-expected-type/README.md2
-rw-r--r--src/test/ui/generator/yielding-in-match-guards.rs11
-rw-r--r--src/test/ui/generic-associated-types/issue-74824.rs27
-rw-r--r--src/test/ui/generic-associated-types/issue-74824.stderr27
-rw-r--r--src/test/ui/generics/param-in-ct-in-ty-param-default.rs2
-rw-r--r--src/test/ui/generics/param-in-ct-in-ty-param-default.stderr7
-rw-r--r--src/test/ui/hygiene/generic_params.stderr1
-rw-r--r--src/test/ui/hygiene/issue-61574-const-parameters.stderr1
-rw-r--r--src/test/ui/inherent-impls-overlap-check/auxiliary/repeat.rs54
-rw-r--r--src/test/ui/inherent-impls-overlap-check/no-overlap.rs34
-rw-r--r--src/test/ui/inherent-impls-overlap-check/overlap.rs71
-rw-r--r--src/test/ui/inherent-impls-overlap-check/overlap.stderr47
-rw-r--r--src/test/ui/inline-const/macro-with-const.rs20
-rw-r--r--src/test/ui/issues/issue-20433.stderr2
-rw-r--r--src/test/ui/issues/issue-21475.rs2
-rw-r--r--src/test/ui/issues/issue-23122-2.stderr3
-rw-r--r--src/test/ui/issues/issue-26251.rs2
-rw-r--r--src/test/ui/issues/issue-26996.rs2
-rw-r--r--src/test/ui/issues/issue-27021.rs2
-rw-r--r--src/test/ui/issues/issue-28498-ugeh-with-lifetime-param.rs2
-rw-r--r--src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs2
-rw-r--r--src/test/ui/issues/issue-28498-ugeh-with-trait-bound.rs2
-rw-r--r--src/test/ui/issues/issue-39559.rs2
-rw-r--r--src/test/ui/issues/issue-39559.stderr10
-rw-r--r--src/test/ui/issues/issue-40000.nll.stderr8
-rw-r--r--src/test/ui/issues/issue-49298.rs2
-rw-r--r--src/test/ui/issues/issue-59508-1.stderr1
-rw-r--r--src/test/ui/issues/issue-59508.stderr2
-rw-r--r--src/test/ui/issues/issue-75763.rs3
-rw-r--r--src/test/ui/issues/issue-78957.rs30
-rw-r--r--src/test/ui/issues/issue-78957.stderr69
-rw-r--r--src/test/ui/issues/issue-79593.rs29
-rw-r--r--src/test/ui/issues/issue-79593.stderr33
-rw-r--r--src/test/ui/issues/issue-80512-param-reordering-with-defaults.rs4
-rw-r--r--src/test/ui/issues/issue-80512-param-reordering-with-defaults.stderr8
-rw-r--r--src/test/ui/label/label_misspelled.rs18
-rw-r--r--src/test/ui/label/label_misspelled.stderr47
-rw-r--r--src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs2
-rw-r--r--src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.stderr16
-rw-r--r--src/test/ui/lifetime-before-type-params.stderr8
-rw-r--r--src/test/ui/linkage-attr/invalid-link-args.rs (renamed from src/test/compile-fail/invalid-link-args.rs)2
-rw-r--r--src/test/ui/linkage-attr/issue-10755.rs (renamed from src/test/compile-fail/issue-10755.rs)2
-rw-r--r--src/test/ui/lint/expansion-time.rs4
-rw-r--r--src/test/ui/lint/expansion-time.stderr22
-rw-r--r--src/test/ui/lint/function-item-references.rs2
-rw-r--r--src/test/ui/lint/lint-const-item-mutation.rs8
-rw-r--r--src/test/ui/lint/lint-const-item-mutation.stderr18
-rw-r--r--src/test/ui/lint/must_use-in-stdlib-traits.rs (renamed from src/test/compile-fail/must_use-in-stdlib-traits.rs)0
-rw-r--r--src/test/ui/lint/must_use-in-stdlib-traits.stderr47
-rw-r--r--src/test/ui/lint/redundant-semicolon/item-stmt-semi.rs8
-rw-r--r--src/test/ui/lint/redundant-semicolon/item-stmt-semi.stderr20
-rw-r--r--src/test/ui/llvm-asm/asm-src-loc-codegen-units.rs (renamed from src/test/compile-fail/asm-src-loc-codegen-units.rs)2
-rw-r--r--src/test/ui/llvm-asm/asm-src-loc.rs (renamed from src/test/compile-fail/asm-src-loc.rs)2
-rw-r--r--src/test/ui/loops/loop-break-value.rs6
-rw-r--r--src/test/ui/loops/loop-break-value.stderr24
-rw-r--r--src/test/ui/macros/edition-macro-pats.rs14
-rw-r--r--src/test/ui/macros/issue-39404.rs1
-rw-r--r--src/test/ui/macros/issue-39404.stderr4
-rw-r--r--src/test/ui/macros/macro-comma-behavior-rpass.rs28
-rw-r--r--src/test/ui/macros/macro-comma-behavior.core.stderr14
-rw-r--r--src/test/ui/macros/macro-comma-behavior.rs20
-rw-r--r--src/test/ui/macros/macro-comma-behavior.std.stderr30
-rw-r--r--src/test/ui/macros/macro-comma-support-rpass.rs2
-rw-r--r--src/test/ui/macros/macro-match-nonterminal.rs1
-rw-r--r--src/test/ui/macros/macro-match-nonterminal.stderr4
-rw-r--r--src/test/ui/macros/macro-pat-follow-2018.rs15
-rw-r--r--src/test/ui/macros/macro-pat-follow.rs16
-rw-r--r--src/test/ui/macros/not-utf8.bin (renamed from src/test/compile-fail/not-utf8.bin)bin3036 -> 3036 bytes
-rw-r--r--src/test/ui/macros/not-utf8.rs (renamed from src/test/compile-fail/not-utf8.rs)0
-rw-r--r--src/test/ui/macros/not-utf8.stderr10
-rw-r--r--src/test/ui/meta/meta-expected-error-wrong-rev.a.stderr16
-rw-r--r--src/test/ui/meta/meta-expected-error-wrong-rev.rs (renamed from src/test/compile-fail/meta-expected-error-wrong-rev.rs)0
-rw-r--r--src/test/ui/mir/issue-78496.rs16
-rw-r--r--src/test/ui/mir/mir-inlining/array-clone-with-generic-size.rs2
-rw-r--r--src/test/ui/never_type/issue-52443.rs (renamed from src/test/compile-fail/issue-52443.rs)0
-rw-r--r--src/test/ui/never_type/issue-52443.stderr57
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument-callee.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr2
-rw-r--r--src/test/ui/nll/closures-in-loops.stderr2
-rw-r--r--src/test/ui/nll/issue-62007-assign-const-index.stderr4
-rw-r--r--src/test/ui/nll/issue-62007-assign-differing-fields.stderr4
-rw-r--r--src/test/ui/nll/polonius/assignment-to-differing-field.stderr8
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr4
-rw-r--r--src/test/ui/no-std-macros.rs13
-rw-r--r--src/test/ui/object-lifetime-default-from-rptr-box.rs2
-rw-r--r--src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs29
-rw-r--r--src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr22
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.rs15
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr20
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-fail.rs10
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr48
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs14
-rw-r--r--src/test/ui/panic-handler/auxiliary/weak-lang-items.rs (renamed from src/test/compile-fail/auxiliary/weak-lang-items.rs)0
-rw-r--r--src/test/ui/panic-handler/panic-handler-missing.rs (renamed from src/test/compile-fail/panic-handler-missing.rs)1
-rw-r--r--src/test/ui/panic-handler/panic-handler-twice.rs (renamed from src/test/compile-fail/panic-handler-twice.rs)1
-rw-r--r--src/test/ui/panic-handler/weak-lang-item.rs (renamed from src/test/compile-fail/weak-lang-item.rs)0
-rw-r--r--src/test/ui/panic-handler/weak-lang-item.stderr19
-rw-r--r--src/test/ui/panic-runtime/auxiliary/depends.rs (renamed from src/test/compile-fail/auxiliary/depends.rs)0
-rw-r--r--src/test/ui/panic-runtime/auxiliary/needs-panic-runtime.rs (renamed from src/test/compile-fail/auxiliary/needs-panic-runtime.rs)0
-rw-r--r--src/test/ui/panic-runtime/runtime-depend-on-needs-runtime.rs (renamed from src/test/compile-fail/runtime-depend-on-needs-runtime.rs)1
-rw-r--r--src/test/ui/panic-runtime/two-panic-runtimes.rs (renamed from src/test/compile-fail/two-panic-runtimes.rs)2
-rw-r--r--src/test/ui/panic-runtime/unwind-tables-panic-required.rs (renamed from src/test/compile-fail/unwind-tables-panic-required.rs)1
-rw-r--r--src/test/ui/panic-runtime/unwind-tables-target-required.rs (renamed from src/test/compile-fail/unwind-tables-target-required.rs)0
-rw-r--r--src/test/ui/panic-runtime/want-abort-got-unwind.rs (renamed from src/test/compile-fail/want-abort-got-unwind.rs)2
-rw-r--r--src/test/ui/panic-runtime/want-abort-got-unwind2.rs (renamed from src/test/compile-fail/want-abort-got-unwind2.rs)2
-rw-r--r--src/test/ui/parser/fn-colon-return-type.rs3
-rw-r--r--src/test/ui/parser/fn-colon-return-type.stderr4
-rw-r--r--src/test/ui/parser/incorrect-move-async-order-issue-79694.fixed8
-rw-r--r--src/test/ui/parser/incorrect-move-async-order-issue-79694.rs8
-rw-r--r--src/test/ui/parser/incorrect-move-async-order-issue-79694.stderr13
-rw-r--r--src/test/ui/parser/issue-14303-enum.stderr2
-rw-r--r--src/test/ui/parser/issue-14303-fn-def.stderr2
-rw-r--r--src/test/ui/parser/issue-14303-impl.stderr2
-rw-r--r--src/test/ui/parser/issue-14303-struct.stderr2
-rw-r--r--src/test/ui/parser/issue-14303-trait.stderr2
-rw-r--r--src/test/ui/parser/macro/issue-33569.rs1
-rw-r--r--src/test/ui/parser/macro/issue-33569.stderr16
-rw-r--r--src/test/ui/parser/multibyte-char-use-seperator-issue-80134.rs12
-rw-r--r--src/test/ui/parser/multibyte-char-use-seperator-issue-80134.stderr52
-rw-r--r--src/test/ui/parser/not-a-pred.rs13
-rw-r--r--src/test/ui/parser/not-a-pred.stderr32
-rw-r--r--src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs12
-rw-r--r--src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr12
-rw-r--r--src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs9
-rw-r--r--src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.stderr10
-rw-r--r--src/test/ui/pattern/or-pattern-macro-pat.rs44
-rw-r--r--src/test/ui/pattern/usefulness/consts-opaque.rs39
-rw-r--r--src/test/ui/pattern/usefulness/consts-opaque.stderr60
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs1
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr24
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs26
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr87
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/reachability.rs1
-rw-r--r--src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr50
-rw-r--r--src/test/ui/pattern/usefulness/issue-15129.rs8
-rw-r--r--src/test/ui/pattern/usefulness/issue-15129.stderr4
-rw-r--r--src/test/ui/pattern/usefulness/issue-2111.rs13
-rw-r--r--src/test/ui/pattern/usefulness/issue-2111.stderr8
-rw-r--r--src/test/ui/pattern/usefulness/issue-56379.rs14
-rw-r--r--src/test/ui/pattern/usefulness/issue-56379.stderr22
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match.rs2
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match.stderr4
-rw-r--r--src/test/ui/polymorphization/const_parameters/closures.stderr1
-rw-r--r--src/test/ui/polymorphization/const_parameters/functions.stderr1
-rw-r--r--src/test/ui/polymorphization/generators.stderr1
-rw-r--r--src/test/ui/print_type_sizes/niche-filling.rs16
-rw-r--r--src/test/ui/print_type_sizes/niche-filling.stdout6
-rw-r--r--src/test/ui/privacy/issue-46209-private-enum-variant-reexport.rs (renamed from src/test/compile-fail/issue-46209-private-enum-variant-reexport.rs)0
-rw-r--r--src/test/ui/privacy/issue-46209-private-enum-variant-reexport.stderr44
-rw-r--r--src/test/ui/proc-macro/ambiguous-builtin-attrs.rs4
-rw-r--r--src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr14
-rw-r--r--src/test/ui/proc-macro/capture-unglued-token.rs20
-rw-r--r--src/test/ui/proc-macro/capture-unglued-token.stdout28
-rw-r--r--src/test/ui/regions/regions-early-bound-trait-param.rs2
-rw-r--r--src/test/ui/regions/regions-variance-contravariant-use-contravariant.rs2
-rw-r--r--src/test/ui/regions/regions-variance-covariant-use-covariant.rs2
-rw-r--r--src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr1
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/bindings.rs10
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/bindings.stderr15
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/feature-gate.rs5
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr83
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/run-pass.rs34
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/typeck.rs16
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/typeck.stderr21
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/warns.rs22
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/warns.stderr26
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr1
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.rs13
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs16
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr24
-rw-r--r--src/test/ui/simd/simd-array-type.rs2
-rw-r--r--src/test/ui/simd/simd-generics.rs2
-rw-r--r--src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs2
-rw-r--r--src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs2
-rw-r--r--src/test/ui/similar-tokens.fixed13
-rw-r--r--src/test/ui/similar-tokens.rs2
-rw-r--r--src/test/ui/similar-tokens.stderr2
-rw-r--r--src/test/ui/span/dropck_arr_cycle_checked.rs2
-rw-r--r--src/test/ui/span/dropck_vec_cycle_checked.rs2
-rw-r--r--src/test/ui/specialization/defaultimpl/projection.rs2
-rw-r--r--src/test/ui/specialization/issue-50452-fail.rs (renamed from src/test/compile-fail/specialization/issue-50452.rs)1
-rw-r--r--src/test/ui/specialization/issue-50452-fail.stderr26
-rw-r--r--src/test/ui/specialization/specialization-projection.rs2
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-sanity.rs6
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-sanity.stderr12
-rw-r--r--src/test/ui/structs-enums/discrim-explicit-23030.rs2
-rw-r--r--src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs2
-rw-r--r--src/test/ui/suggestions/impl-trait-with-missing-bounds.rs8
-rw-r--r--src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr17
-rw-r--r--src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs32
-rw-r--r--src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr33
-rw-r--r--src/test/ui/suggestions/suggest-move-lifetimes.stderr8
-rw-r--r--src/test/ui/svh/auxiliary/svh-uta-base.rs2
-rw-r--r--src/test/ui/svh/auxiliary/svh-uta-change-use-trait.rs2
-rw-r--r--src/test/ui/svh/auxiliary/svh-utb.rs2
-rw-r--r--src/test/ui/svh/svh-use-trait.rs2
-rw-r--r--src/test/ui/symbol-names/const-generics-demangling.rs3
-rw-r--r--src/test/ui/symbol-names/const-generics-demangling.stderr24
-rw-r--r--src/test/ui/symbol-names/const-generics.rs122
-rw-r--r--src/test/ui/symbol-names/issue-76365.rs3
-rw-r--r--src/test/ui/threads-sendsync/issue-43733-2.rs (renamed from src/test/compile-fail/issue-43733-2.rs)2
-rw-r--r--src/test/ui/threads-sendsync/issue-43733.rs (renamed from src/test/ui/issues/issue-43733.rs)0
-rw-r--r--src/test/ui/threads-sendsync/issue-43733.stderr (renamed from src/test/ui/issues/issue-43733.stderr)0
-rw-r--r--src/test/ui/traits/impl-evaluation-order.rs39
-rw-r--r--src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs53
-rw-r--r--src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.stderr60
-rw-r--r--src/test/ui/traits/traits-repeated-supertrait.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/assoc-type-const.stderr1
-rw-r--r--src/test/ui/union/union-unsafe.rs27
-rw-r--r--src/test/ui/union/union-unsafe.stderr56
-rw-r--r--src/test/ui/unsafe-fn-called-from-unsafe-blk.rs2
-rw-r--r--src/test/ui/unsafe-fn-called-from-unsafe-fn.rs2
-rw-r--r--src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs17
-rw-r--r--src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr24
-rw-r--r--src/tools/build-manifest/src/main.rs1
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/.github/workflows/clippy.yml34
-rw-r--r--src/tools/clippy/.github/workflows/clippy_bors.yml97
-rw-r--r--src/tools/clippy/.github/workflows/clippy_dev.yml10
-rw-r--r--src/tools/clippy/CHANGELOG.md3
-rw-r--r--src/tools/clippy/CONTRIBUTING.md61
-rw-r--r--src/tools/clippy/README.md16
-rw-r--r--src/tools/clippy/clippy_dev/src/bless.rs74
-rw-r--r--src/tools/clippy/clippy_dev/src/fmt.rs21
-rw-r--r--src/tools/clippy/clippy_dev/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_dev/src/main.rs102
-rw-r--r--src/tools/clippy/clippy_dev/src/ra_setup.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/await_holding_invalid.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/checked_conversions.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/create_dir.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs139
-rw-r--r--src/tools/clippy/clippy_lints/src/functions.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_ok_or.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/matches.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/mem_replace.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs153
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs31
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_doc.rs64
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrow.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_update.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/non_expressive_names.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs68
-rw-r--r--src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/ranges.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_clone.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_else.rs135
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_field_names.rs25
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/ref_option_ref.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/shadow.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/types.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs25
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/ast_utils.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/conf.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/hir_utils.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/inspector.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints.rs78
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/mod.rs39
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/paths.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/usage.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs107
-rw-r--r--src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs82
-rw-r--r--src/tools/clippy/clippy_workspace_tests/path_dep/Cargo.toml3
-rw-r--r--src/tools/clippy/clippy_workspace_tests/path_dep/src/lib.rs6
-rw-r--r--src/tools/clippy/clippy_workspace_tests/subcrate/Cargo.toml3
-rw-r--r--src/tools/clippy/doc/adding_lints.md70
-rw-r--r--src/tools/clippy/doc/basics.md34
-rw-r--r--src/tools/clippy/rust-toolchain4
-rwxr-xr-xsrc/tools/clippy/setup-toolchain.sh36
-rw-r--r--src/tools/clippy/src/driver.rs44
-rw-r--r--src/tools/clippy/src/main.rs32
-rw-r--r--src/tools/clippy/tests/dogfood.rs71
-rw-r--r--src/tools/clippy/tests/integration.rs2
-rwxr-xr-xsrc/tools/clippy/tests/ui-cargo/update-all-references.sh17
-rwxr-xr-xsrc/tools/clippy/tests/ui-cargo/update-references.sh46
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed33
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs33
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr27
-rwxr-xr-xsrc/tools/clippy/tests/ui-toml/update-all-references.sh17
-rwxr-xr-xsrc/tools/clippy/tests/ui-toml/update-references.sh46
-rw-r--r--src/tools/clippy/tests/ui/clone_on_copy.stderr10
-rw-r--r--src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs5
-rw-r--r--src/tools/clippy/tests/ui/eprint_with_newline.rs49
-rw-r--r--src/tools/clippy/tests/ui/eprint_with_newline.stderr121
-rw-r--r--src/tools/clippy/tests/ui/eta.stderr2
-rw-r--r--src/tools/clippy/tests/ui/formatting.rs87
-rw-r--r--src/tools/clippy/tests/ui/formatting.stderr89
-rw-r--r--src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed2
-rw-r--r--src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs2
-rw-r--r--src/tools/clippy/tests/ui/match_single_binding.fixed28
-rw-r--r--src/tools/clippy/tests/ui/match_single_binding.rs33
-rw-r--r--src/tools/clippy/tests/ui/match_single_binding.stderr13
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_attr.rs84
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_attr.stderr8
-rw-r--r--src/tools/clippy/tests/ui/missing-doc-crate-missing.stderr2
-rw-r--r--src/tools/clippy/tests/ui/missing-doc-impl.stderr12
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.stderr4
-rw-r--r--src/tools/clippy/tests/ui/needless_doc_main.rs10
-rw-r--r--src/tools/clippy/tests/ui/needless_update.rs11
-rw-r--r--src/tools/clippy/tests/ui/needless_update.stderr2
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn.stderr24
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn_assertions.rs48
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr57
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn_debug_assertions.rs48
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn_debug_assertions.stderr57
-rw-r--r--src/tools/clippy/tests/ui/print_stderr.rs8
-rw-r--r--src/tools/clippy/tests/ui/print_stderr.stderr16
-rw-r--r--src/tools/clippy/tests/ui/println_empty_string.fixed7
-rw-r--r--src/tools/clippy/tests/ui/println_empty_string.rs7
-rw-r--r--src/tools/clippy/tests/ui/println_empty_string.stderr14
-rw-r--r--src/tools/clippy/tests/ui/range_contains.fixed5
-rw-r--r--src/tools/clippy/tests/ui/range_contains.rs5
-rw-r--r--src/tools/clippy/tests/ui/redundant_else.rs154
-rw-r--r--src/tools/clippy/tests/ui/redundant_else.stderr80
-rw-r--r--src/tools/clippy/tests/ui/suspicious_else_formatting.rs79
-rw-r--r--src/tools/clippy/tests/ui/suspicious_else_formatting.stderr77
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_clone.stderr12
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs4
-rwxr-xr-xsrc/tools/clippy/tests/ui/update-all-references.sh20
-rwxr-xr-xsrc/tools/clippy/tests/ui/update-references.sh56
-rw-r--r--src/tools/clippy/tests/ui/use_self.fixed1
-rw-r--r--src/tools/clippy/tests/ui/use_self.rs1
-rw-r--r--src/tools/clippy/tests/ui/use_self.stderr38
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_convention.rs49
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_convention.stderr62
-rw-r--r--src/tools/clippy/tests/ui/zero_sized_btreemap_values.rs68
-rw-r--r--src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr107
-rw-r--r--src/tools/clippy/tests/ui/zero_sized_hashmap_values.rs68
-rw-r--r--src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr107
-rw-r--r--src/tools/clippy/triagebot.toml2
-rw-r--r--src/tools/clippy/util/gh-pages/index.html42
-rw-r--r--src/tools/compiletest/src/common.rs17
-rw-r--r--src/tools/compiletest/src/header.rs7
-rw-r--r--src/tools/compiletest/src/main.rs14
-rw-r--r--src/tools/compiletest/src/runtest.rs51
-rw-r--r--src/tools/expand-yaml-anchors/src/main.rs3
-rw-r--r--src/tools/linkchecker/main.rs13
-rw-r--r--src/tools/lint-docs/src/groups.rs22
m---------src/tools/miri18
m---------src/tools/rust-installer0
-rw-r--r--src/tools/rustc-workspace-hack/Cargo.toml2
m---------src/tools/rustfmt10
-rw-r--r--src/tools/tidy/src/cargo.rs9
-rw-r--r--src/tools/tidy/src/deps.rs30
-rw-r--r--src/tools/tidy/src/error_codes_check.rs101
-rw-r--r--src/tools/tidy/src/extdeps.rs5
-rw-r--r--src/tools/tidy/src/features.rs8
-rw-r--r--src/tools/tidy/src/lib.rs6
-rw-r--r--src/tools/tidy/src/main.rs5
-rw-r--r--src/tools/tidy/src/ui_tests.rs63
-rw-r--r--src/tools/x/README.md7
-rw-r--r--src/version2
1123 files changed, 12589 insertions, 8878 deletions
diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md
index a103c9fb0b7..f899f21080e 100644
--- a/src/bootstrap/CHANGELOG.md
+++ b/src/bootstrap/CHANGELOG.md
@@ -4,7 +4,12 @@ All notable changes to bootstrap will be documented in this file.
 
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
-## [Non-breaking changes since the last major version]
+
+## [Changes since the last major version]
+
+- `llvm-libunwind` now accepts `in-tree` (formerly true), `system` or `no` (formerly false) [#77703](https://github.com/rust-lang/rust/pull/77703)
+
+### Non-breaking changes
 
 - `x.py check` needs opt-in to check tests (--all-targets) [#77473](https://github.com/rust-lang/rust/pull/77473)
 - The default bootstrap profiles are now located at `bootstrap/defaults/config.$PROFILE.toml` (previously they were located at `bootstrap/defaults/config.toml.$PROFILE`) [#77558](https://github.com/rust-lang/rust/pull/77558)
diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md
index 84ed9446ae7..a2e596bf4e9 100644
--- a/src/bootstrap/README.md
+++ b/src/bootstrap/README.md
@@ -201,7 +201,6 @@ build/
     # Output for all compiletest-based test suites
     test/
       ui/
-      compile-fail/
       debuginfo/
       ...
 
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index a819e1b6e2f..b8bae69d063 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -192,8 +192,10 @@ def default_build_triple(verbose):
     # If the user already has a host build triple with an existing `rustc`
     # install, use their preference. This fixes most issues with Windows builds
     # being detected as GNU instead of MSVC.
+    default_encoding = sys.getdefaultencoding()
     try:
         version = subprocess.check_output(["rustc", "--version", "--verbose"])
+        version = version.decode(default_encoding)
         host = next(x for x in version.split('\n') if x.startswith("host: "))
         triple = host.split("host: ")[1]
         if verbose:
@@ -204,7 +206,6 @@ def default_build_triple(verbose):
             print("rustup not detected: {}".format(e))
             print("falling back to auto-detect")
 
-    default_encoding = sys.getdefaultencoding()
     required = sys.platform != 'win32'
     ostype = require(["uname", "-s"], exit=required)
     cputype = require(['uname', '-m'], exit=required)
@@ -350,11 +351,13 @@ def output(filepath):
     with open(tmp, 'w') as f:
         yield f
     try:
-        os.remove(filepath)  # PermissionError/OSError on Win32 if in use
-        os.rename(tmp, filepath)
+        if os.path.exists(filepath):
+            os.remove(filepath)  # PermissionError/OSError on Win32 if in use
     except OSError:
         shutil.copy2(tmp, filepath)
         os.remove(tmp)
+        return
+    os.rename(tmp, filepath)
 
 
 class RustBuild(object):
@@ -794,7 +797,7 @@ class RustBuild(object):
         env.setdefault("RUSTFLAGS", "")
         env["RUSTFLAGS"] += " -Cdebuginfo=2"
 
-        build_section = "target.{}".format(self.build_triple())
+        build_section = "target.{}".format(self.build)
         target_features = []
         if self.get_toml("crt-static", build_section) == "true":
             target_features += ["+crt-static"]
@@ -825,7 +828,11 @@ class RustBuild(object):
         run(args, env=env, verbose=self.verbose)
 
     def build_triple(self):
-        """Build triple as in LLVM"""
+        """Build triple as in LLVM
+
+        Note that `default_build_triple` is moderately expensive,
+        so use `self.build` where possible.
+        """
         config = self.get_toml('build')
         if config:
             return config
@@ -892,13 +899,17 @@ class RustBuild(object):
         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:
             if module.endswith("llvm-project"):
-                # Don't sync the llvm-project submodule either if an external LLVM
-                # was provided, or if we are downloading LLVM. Also, if the
-                # submodule has been initialized already, sync it anyways so that
-                # it doesn't mess up contributor pull requests.
-                if self.get_toml('llvm-config') or self.downloading_llvm():
+                # 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
             check = self.check_submodule(module, slow_submodules)
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 6d97943548d..c2abb01fa8c 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -384,7 +384,6 @@ impl<'a> Builder<'a> {
                 test::ExpandYamlAnchors,
                 test::Tidy,
                 test::Ui,
-                test::CompileFail,
                 test::RunPassValgrind,
                 test::MirOpt,
                 test::Codegen,
@@ -471,6 +470,7 @@ impl<'a> Builder<'a> {
                 dist::RustDev,
                 dist::Extended,
                 dist::BuildManifest,
+                dist::ReproducibleArtifacts,
             ),
             Kind::Install => describe!(
                 install::Docs,
@@ -732,11 +732,11 @@ impl<'a> Builder<'a> {
             .env("CFG_RELEASE_CHANNEL", &self.config.channel)
             .env("RUSTDOC_REAL", self.rustdoc(compiler))
             .env("RUSTC_BOOTSTRAP", "1")
-            .arg("-Znormalize_docs")
             .arg("-Winvalid_codeblock_attributes");
         if self.config.deny_warnings {
             cmd.arg("-Dwarnings");
         }
+        cmd.arg("-Znormalize-docs");
 
         // Remove make-related flags that can cause jobserver problems.
         cmd.env_remove("MAKEFLAGS");
@@ -1123,6 +1123,19 @@ impl<'a> Builder<'a> {
             },
         );
 
+        // `dsymutil` adds time to builds on Apple platforms for no clear benefit, and also makes
+        // it more difficult for debuggers to find debug info. The compiler currently defaults to
+        // running `dsymutil` to preserve its historical default, but when compiling the compiler
+        // itself, we skip it by default since we know it's safe to do so in that case.
+        // See https://github.com/rust-lang/rust/issues/79361 for more info on this flag.
+        if target.contains("apple") {
+            if self.config.rust_run_dsymutil {
+                rustflags.arg("-Zrun-dsymutil=yes");
+            } else {
+                rustflags.arg("-Zrun-dsymutil=no");
+            }
+        }
+
         if self.config.cmd.bless() {
             // Bless `expect!` tests.
             cargo.env("UPDATE_EXPECT", "1");
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 3cfb2f2836d..9477a7cb354 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -7,6 +7,7 @@
 //! goes along from the output of the previous stage.
 
 use std::borrow::Cow;
+use std::collections::HashSet;
 use std::env;
 use std::fs;
 use std::io::prelude::*;
@@ -519,6 +520,41 @@ impl Step for Rustc {
         let mut cargo = builder.cargo(compiler, Mode::Rustc, SourceType::InTree, target, "build");
         rustc_cargo(builder, &mut cargo, target);
 
+        if builder.config.rust_profile_use.is_some()
+            && builder.config.rust_profile_generate.is_some()
+        {
+            panic!("Cannot use and generate PGO profiles at the same time");
+        }
+
+        let is_collecting = if let Some(path) = &builder.config.rust_profile_generate {
+            if compiler.stage == 1 {
+                cargo.rustflag(&format!("-Cprofile-generate={}", path));
+                // Apparently necessary to avoid overflowing the counters during
+                // a Cargo build profile
+                cargo.rustflag("-Cllvm-args=-vp-counters-per-site=4");
+                true
+            } else {
+                false
+            }
+        } else if let Some(path) = &builder.config.rust_profile_use {
+            if compiler.stage == 1 {
+                cargo.rustflag(&format!("-Cprofile-use={}", path));
+                cargo.rustflag("-Cllvm-args=-pgo-warn-missing-function");
+                true
+            } else {
+                false
+            }
+        } else {
+            false
+        };
+        if is_collecting {
+            // Ensure paths to Rust sources are relative, not absolute.
+            cargo.rustflag(&format!(
+                "-Cllvm-args=-static-func-strip-dirname-prefix={}",
+                builder.config.src.components().count()
+            ));
+        }
+
         builder.info(&format!(
             "Building stage{} compiler artifacts ({} -> {})",
             compiler.stage, &compiler.host, target
@@ -770,7 +806,7 @@ fn copy_codegen_backends_to_sysroot(
     // Here we're looking for the output dylib of the `CodegenBackend` step and
     // we're copying that into the `codegen-backends` folder.
     let dst = builder.sysroot_codegen_backends(target_compiler);
-    t!(fs::create_dir_all(&dst));
+    t!(fs::create_dir_all(&dst), dst);
 
     if builder.config.dry_run {
         return;
@@ -974,28 +1010,51 @@ impl Step for Assemble {
         builder.info(&format!("Assembling stage{} compiler ({})", stage, host));
 
         // Link in all dylibs to the libdir
+        let stamp = librustc_stamp(builder, build_compiler, target_compiler.host);
+        let proc_macros = builder
+            .read_stamp_file(&stamp)
+            .into_iter()
+            .filter_map(|(path, dependency_type)| {
+                if dependency_type == DependencyType::Host {
+                    Some(path.file_name().unwrap().to_owned().into_string().unwrap())
+                } else {
+                    None
+                }
+            })
+            .collect::<HashSet<_>>();
+
         let sysroot = builder.sysroot(target_compiler);
         let rustc_libdir = builder.rustc_libdir(target_compiler);
         t!(fs::create_dir_all(&rustc_libdir));
         let src_libdir = builder.sysroot_libdir(build_compiler, host);
         for f in builder.read_dir(&src_libdir) {
             let filename = f.file_name().into_string().unwrap();
-            if is_dylib(&filename) {
+            if is_dylib(&filename) && !proc_macros.contains(&filename) {
                 builder.copy(&f.path(), &rustc_libdir.join(&filename));
             }
         }
 
         copy_codegen_backends_to_sysroot(builder, build_compiler, target_compiler);
 
+        // We prepend this bin directory to the user PATH when linking Rust binaries. To
+        // avoid shadowing the system LLD we rename the LLD we provide to `rust-lld`.
         let libdir = builder.sysroot_libdir(target_compiler, target_compiler.host);
+        let libdir_bin = libdir.parent().unwrap().join("bin");
+        t!(fs::create_dir_all(&libdir_bin));
+
         if let Some(lld_install) = lld_install {
             let src_exe = exe("lld", target_compiler.host);
             let dst_exe = exe("rust-lld", target_compiler.host);
-            // we prepend this bin directory to the user PATH when linking Rust binaries. To
-            // avoid shadowing the system LLD we rename the LLD we provide to `rust-lld`.
-            let dst = libdir.parent().unwrap().join("bin");
-            t!(fs::create_dir_all(&dst));
-            builder.copy(&lld_install.join("bin").join(&src_exe), &dst.join(&dst_exe));
+            builder.copy(&lld_install.join("bin").join(&src_exe), &libdir_bin.join(&dst_exe));
+        }
+
+        // Similarly, copy `llvm-dwp` into libdir for Split DWARF.
+        {
+            let src_exe = exe("llvm-dwp", target_compiler.host);
+            let dst_exe = exe("rust-llvm-dwp", target_compiler.host);
+            let llvm_config_bin = builder.ensure(native::Llvm { target: target_compiler.host });
+            let llvm_bin_dir = llvm_config_bin.parent().unwrap();
+            builder.copy(&llvm_bin_dir.join(&src_exe), &libdir_bin.join(&dst_exe));
         }
 
         // Ensure that `libLLVM.so` ends up in the newly build compiler directory,
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index fb2c6d1f92a..f4d89a89c14 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -123,6 +123,7 @@ pub struct Config {
     pub rust_debuginfo_level_std: u32,
     pub rust_debuginfo_level_tools: u32,
     pub rust_debuginfo_level_tests: u32,
+    pub rust_run_dsymutil: bool,
     pub rust_rpath: bool,
     pub rustc_parallel: bool,
     pub rustc_default_linker: Option<String>,
@@ -133,6 +134,8 @@ pub struct Config {
     pub rust_thin_lto_import_instr_limit: Option<u32>,
     pub rust_remap_debuginfo: bool,
     pub rust_new_symbol_mangling: bool,
+    pub rust_profile_use: Option<String>,
+    pub rust_profile_generate: Option<String>,
 
     pub build: TargetSelection,
     pub hosts: Vec<TargetSelection>,
@@ -145,6 +148,7 @@ pub struct Config {
     pub dist_sign_folder: Option<PathBuf>,
     pub dist_upload_addr: Option<String>,
     pub dist_gpg_password_file: Option<PathBuf>,
+    pub dist_compression_formats: Option<Vec<String>>,
 
     // libstd features
     pub backtrace: bool, // support for RUST_BACKTRACE
@@ -331,7 +335,7 @@ impl Merge for TomlConfig {
                     *x = Some(new);
                 }
             }
-        };
+        }
         do_merge(&mut self.build, build);
         do_merge(&mut self.install, install);
         do_merge(&mut self.llvm, llvm);
@@ -435,6 +439,7 @@ struct Dist {
     upload_addr: Option<String>,
     src_tarball: Option<bool>,
     missing_tools: Option<bool>,
+    compression_formats: Option<Vec<String>>,
 }
 
 #[derive(Deserialize)]
@@ -466,6 +471,7 @@ struct Rust {
     debuginfo_level_std: Option<u32>,
     debuginfo_level_tools: Option<u32>,
     debuginfo_level_tests: Option<u32>,
+    run_dsymutil: Option<bool>,
     backtrace: Option<bool>,
     incremental: Option<bool>,
     parallel_compiler: Option<bool>,
@@ -494,6 +500,8 @@ struct Rust {
     llvm_libunwind: Option<String>,
     control_flow_guard: Option<bool>,
     new_symbol_mangling: Option<bool>,
+    profile_generate: Option<String>,
+    profile_use: Option<String>,
 }
 
 /// TOML representation of how each build target is configured.
@@ -830,6 +838,7 @@ impl Config {
             debuginfo_level_std = rust.debuginfo_level_std;
             debuginfo_level_tools = rust.debuginfo_level_tools;
             debuginfo_level_tests = rust.debuginfo_level_tests;
+            config.rust_run_dsymutil = rust.run_dsymutil.unwrap_or(false);
             optimize = rust.optimize;
             ignore_git = rust.ignore_git;
             set(&mut config.rust_new_symbol_mangling, rust.new_symbol_mangling);
@@ -871,6 +880,11 @@ impl Config {
 
             config.rust_codegen_units = rust.codegen_units.map(threads_from_config);
             config.rust_codegen_units_std = rust.codegen_units_std.map(threads_from_config);
+            config.rust_profile_use = flags.rust_profile_use.or(rust.profile_use);
+            config.rust_profile_generate = flags.rust_profile_generate.or(rust.profile_generate);
+        } else {
+            config.rust_profile_use = flags.rust_profile_use;
+            config.rust_profile_generate = flags.rust_profile_generate;
         }
 
         if let Some(t) = toml.target {
@@ -924,6 +938,7 @@ impl Config {
             config.dist_sign_folder = t.sign_folder.map(PathBuf::from);
             config.dist_gpg_password_file = t.gpg_password_file.map(PathBuf::from);
             config.dist_upload_addr = t.upload_addr;
+            config.dist_compression_formats = t.compression_formats;
             set(&mut config.rust_dist_src, t.src_tarball);
             set(&mut config.missing_tools, t.missing_tools);
         }
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index 42f00ce9621..2cabaee68ea 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -147,6 +147,8 @@ v("experimental-targets", "llvm.experimental-targets",
   "experimental LLVM targets to build")
 v("release-channel", "rust.channel", "the name of the release channel to build")
 v("release-description", "rust.description", "optional descriptive string for version output")
+v("dist-compression-formats", None,
+  "comma-separated list of compression formats to use")
 
 # Used on systems where "cc" is unavailable
 v("default-linker", "rust.default-linker", "the default linker")
@@ -349,6 +351,8 @@ for key in known_args:
     elif option.name == 'option-checking':
         # this was handled above
         pass
+    elif option.name == 'dist-compression-formats':
+        set('dist.compression-formats', value.split(','))
     else:
         raise RuntimeError("unhandled option {}".format(option.name))
 
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 354be109cf2..daec1656b27 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -19,6 +19,7 @@ use crate::builder::{Builder, RunConfig, ShouldRun, Step};
 use crate::cache::{Interned, INTERNER};
 use crate::compile;
 use crate::config::TargetSelection;
+use crate::tarball::{GeneratedTarball, OverlayKind, Tarball};
 use crate::tool::{self, Tool};
 use crate::util::{exe, is_dylib, timeit};
 use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS};
@@ -36,10 +37,6 @@ pub fn tmpdir(builder: &Builder<'_>) -> PathBuf {
     builder.out.join("tmp/dist")
 }
 
-fn rust_installer(builder: &Builder<'_>) -> Command {
-    builder.tool_cmd(Tool::RustInstaller)
-}
-
 fn missing_tool(tool_name: &str, skip: bool) {
     if skip {
         println!("Unable to build {}, skipping dist", tool_name)
@@ -54,7 +51,7 @@ pub struct Docs {
 }
 
 impl Step for Docs {
-    type Output = PathBuf;
+    type Output = Option<GeneratedTarball>;
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -66,48 +63,20 @@ impl Step for Docs {
     }
 
     /// Builds the `rust-docs` installer component.
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
+    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let host = self.host;
-
-        let name = pkgname(builder, "rust-docs");
-
         if !builder.config.docs {
-            return distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple));
+            return None;
         }
-
         builder.default_doc(None);
 
-        builder.info(&format!("Dist docs ({})", host));
-        let _time = timeit(builder);
+        let dest = "share/doc/rust/html";
 
-        let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple));
-        let _ = fs::remove_dir_all(&image);
-
-        let dst = image.join("share/doc/rust/html");
-        t!(fs::create_dir_all(&dst));
-        let src = builder.doc_out(host);
-        builder.cp_r(&src, &dst);
-        builder.install(&builder.src.join("src/doc/robots.txt"), &dst, 0o644);
-
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust-Documentation")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=Rust-documentation-is-installed.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg(format!("--package-name={}-{}", name, host.triple))
-            .arg("--component-name=rust-docs")
-            .arg("--legacy-manifest-dirs=rustlib,cargo")
-            .arg("--bulk-dirs=share/doc/rust/html");
-        builder.run(&mut cmd);
-        builder.remove_dir(&image);
-
-        distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple))
+        let mut tarball = Tarball::new(builder, "rust-docs", &host.triple);
+        tarball.set_product_name("Rust Documentation");
+        tarball.add_dir(&builder.doc_out(host), dest);
+        tarball.add_file(&builder.src.join("src/doc/robots.txt"), dest, 0o644);
+        Some(tarball.generate())
     }
 }
 
@@ -117,7 +86,7 @@ pub struct RustcDocs {
 }
 
 impl Step for RustcDocs {
-    type Output = PathBuf;
+    type Output = Option<GeneratedTarball>;
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -129,47 +98,17 @@ impl Step for RustcDocs {
     }
 
     /// Builds the `rustc-docs` installer component.
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
+    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let host = self.host;
-
-        let name = pkgname(builder, "rustc-docs");
-
         if !builder.config.compiler_docs {
-            return distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple));
+            return None;
         }
-
         builder.default_doc(None);
 
-        let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple));
-        let _ = fs::remove_dir_all(&image);
-
-        let dst = image.join("share/doc/rust/html/rustc");
-        t!(fs::create_dir_all(&dst));
-        let src = builder.compiler_doc_out(host);
-        builder.cp_r(&src, &dst);
-
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rustc-Documentation")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=Rustc-documentation-is-installed.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg(format!("--package-name={}-{}", name, host.triple))
-            .arg("--component-name=rustc-docs")
-            .arg("--legacy-manifest-dirs=rustlib,cargo")
-            .arg("--bulk-dirs=share/doc/rust/html/rustc");
-
-        builder.info(&format!("Dist compiler docs ({})", host));
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-        builder.remove_dir(&image);
-
-        distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple))
+        let mut tarball = Tarball::new(builder, "rustc-docs", &host.triple);
+        tarball.set_product_name("Rustc Documentation");
+        tarball.add_dir(&builder.compiler_doc_out(host), "share/doc/rust/html/rustc");
+        Some(tarball.generate())
     }
 }
 
@@ -328,7 +267,7 @@ pub struct Mingw {
 }
 
 impl Step for Mingw {
-    type Output = Option<PathBuf>;
+    type Output = Option<GeneratedTarball>;
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -343,43 +282,22 @@ impl Step for Mingw {
     ///
     /// This contains all the bits and pieces to run the MinGW Windows targets
     /// without any extra installed software (e.g., we bundle gcc, libraries, etc).
-    fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
+    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let host = self.host;
-
         if !host.contains("pc-windows-gnu") {
             return None;
         }
 
-        builder.info(&format!("Dist mingw ({})", host));
-        let _time = timeit(builder);
-        let name = pkgname(builder, "rust-mingw");
-        let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple));
-        let _ = fs::remove_dir_all(&image);
-        t!(fs::create_dir_all(&image));
+        let mut tarball = Tarball::new(builder, "rust-mingw", &host.triple);
+        tarball.set_product_name("Rust MinGW");
 
         // The first argument is a "temporary directory" which is just
         // thrown away (this contains the runtime DLLs included in the rustc package
         // above) and the second argument is where to place all the MinGW components
         // (which is what we want).
-        make_win_dist(&tmpdir(builder), &image, host, &builder);
-
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust-MinGW")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=Rust-MinGW-is-installed.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg(format!("--package-name={}-{}", name, host.triple))
-            .arg("--component-name=rust-mingw")
-            .arg("--legacy-manifest-dirs=rustlib,cargo");
-        builder.run(&mut cmd);
-        t!(fs::remove_dir_all(&image));
-        Some(distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple)))
+        make_win_dist(&tmpdir(builder), tarball.image_dir(), host, &builder);
+
+        Some(tarball.generate())
     }
 }
 
@@ -389,7 +307,7 @@ pub struct Rustc {
 }
 
 impl Step for Rustc {
-    type Output = PathBuf;
+    type Output = GeneratedTarball;
     const DEFAULT: bool = true;
     const ONLY_HOSTS: bool = true;
 
@@ -403,34 +321,14 @@ impl Step for Rustc {
     }
 
     /// Creates the `rustc` installer component.
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
+    fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
         let compiler = self.compiler;
         let host = self.compiler.host;
 
-        let name = pkgname(builder, "rustc");
-        let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple));
-        let _ = fs::remove_dir_all(&image);
-        let overlay = tmpdir(builder).join(format!("{}-{}-overlay", name, host.triple));
-        let _ = fs::remove_dir_all(&overlay);
+        let tarball = Tarball::new(builder, "rustc", &host.triple);
 
         // Prepare the rustc "image", what will actually end up getting installed
-        prepare_image(builder, compiler, &image);
-
-        // Prepare the overlay which is part of the tarball but won't actually be
-        // installed
-        let cp = |file: &str| {
-            builder.install(&builder.src.join(file), &overlay, 0o644);
-        };
-        cp("COPYRIGHT");
-        cp("LICENSE-APACHE");
-        cp("LICENSE-MIT");
-        cp("README.md");
-        // tiny morsel of metadata is used by rust-packaging
-        let version = builder.rust_version();
-        builder.create(&overlay.join("version"), &version);
-        if let Some(sha) = builder.rust_sha() {
-            builder.create(&overlay.join("git-commit-hash"), &sha);
-        }
+        prepare_image(builder, compiler, tarball.image_dir());
 
         // On MinGW we've got a few runtime DLL dependencies that we need to
         // include. The first argument to this script is where to put these DLLs
@@ -443,38 +341,11 @@ impl Step for Rustc {
         // install will *also* include the rust-mingw package, which also needs
         // licenses, so to be safe we just include it here in all MinGW packages.
         if host.contains("pc-windows-gnu") {
-            make_win_dist(&image, &tmpdir(builder), host, builder);
-
-            let dst = image.join("share/doc");
-            t!(fs::create_dir_all(&dst));
-            builder.cp_r(&builder.src.join("src/etc/third-party"), &dst);
+            make_win_dist(tarball.image_dir(), &tmpdir(builder), host, builder);
+            tarball.add_dir(builder.src.join("src/etc/third-party"), "share/doc");
         }
 
-        // Finally, wrap everything up in a nice tarball!
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=Rust-is-ready-to-roll.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg("--non-installed-overlay")
-            .arg(&overlay)
-            .arg(format!("--package-name={}-{}", name, host.triple))
-            .arg("--component-name=rustc")
-            .arg("--legacy-manifest-dirs=rustlib,cargo");
-
-        builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host.triple));
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-        builder.remove_dir(&image);
-        builder.remove_dir(&overlay);
-
-        return distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple));
+        return tarball.generate();
 
         fn prepare_image(builder: &Builder<'_>, compiler: Compiler, image: &Path) {
             let host = compiler.host;
@@ -523,17 +394,20 @@ impl Step for Rustc {
             // component for now.
             maybe_install_llvm_runtime(builder, host, image);
 
+            let src_dir = builder.sysroot_libdir(compiler, host).parent().unwrap().join("bin");
+            let dst_dir = image.join("lib/rustlib").join(&*host.triple).join("bin");
+            t!(fs::create_dir_all(&dst_dir));
+
             // Copy over lld if it's there
             if builder.config.lld_enabled {
                 let exe = exe("rust-lld", compiler.host);
-                let src =
-                    builder.sysroot_libdir(compiler, host).parent().unwrap().join("bin").join(&exe);
-                // for the rationale about this rename check `compile::copy_lld_to_sysroot`
-                let dst = image.join("lib/rustlib").join(&*host.triple).join("bin").join(&exe);
-                t!(fs::create_dir_all(&dst.parent().unwrap()));
-                builder.copy(&src, &dst);
+                builder.copy(&src_dir.join(&exe), &dst_dir.join(&exe));
             }
 
+            // Copy over llvm-dwp if it's there
+            let exe = exe("rust-llvm-dwp", compiler.host);
+            builder.copy(&src_dir.join(&exe), &dst_dir.join(&exe));
+
             // Man pages
             t!(fs::create_dir_all(image.join("share/man/man1")));
             let man_src = builder.src.join("src/doc/man");
@@ -681,7 +555,7 @@ pub struct Std {
 }
 
 impl Step for Std {
-    type Output = PathBuf;
+    type Output = Option<GeneratedTarball>;
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -699,46 +573,24 @@ impl Step for Std {
         });
     }
 
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
+    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let compiler = self.compiler;
         let target = self.target;
 
-        let name = pkgname(builder, "rust-std");
-        let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple));
         if skip_host_target_lib(builder, compiler) {
-            return archive;
+            return None;
         }
 
         builder.ensure(compile::Std { compiler, target });
 
-        let image = tmpdir(builder).join(format!("{}-{}-image", name, target.triple));
-        let _ = fs::remove_dir_all(&image);
+        let mut tarball = Tarball::new(builder, "rust-std", &target.triple);
+        tarball.include_target_in_component_name(true);
 
         let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
         let stamp = compile::libstd_stamp(builder, compiler_to_use, target);
-        copy_target_libs(builder, target, &image, &stamp);
-
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=std-is-standing-at-the-ready.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg(format!("--package-name={}-{}", name, target.triple))
-            .arg(format!("--component-name=rust-std-{}", target.triple))
-            .arg("--legacy-manifest-dirs=rustlib,cargo");
-
-        builder
-            .info(&format!("Dist std stage{} ({} -> {})", compiler.stage, &compiler.host, target));
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-        builder.remove_dir(&image);
-        archive
+        copy_target_libs(builder, target, &tarball.image_dir(), &stamp);
+
+        Some(tarball.generate())
     }
 }
 
@@ -749,7 +601,7 @@ pub struct RustcDev {
 }
 
 impl Step for RustcDev {
-    type Output = PathBuf;
+    type Output = Option<GeneratedTarball>;
     const DEFAULT: bool = true;
     const ONLY_HOSTS: bool = true;
 
@@ -768,60 +620,36 @@ impl Step for RustcDev {
         });
     }
 
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
+    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let compiler = self.compiler;
         let target = self.target;
-
-        let name = pkgname(builder, "rustc-dev");
-        let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple));
         if skip_host_target_lib(builder, compiler) {
-            return archive;
+            return None;
         }
 
         builder.ensure(compile::Rustc { compiler, target });
 
-        let image = tmpdir(builder).join(format!("{}-{}-image", name, target.triple));
-        let _ = fs::remove_dir_all(&image);
+        let tarball = Tarball::new(builder, "rustc-dev", &target.triple);
 
         let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
         let stamp = compile::librustc_stamp(builder, compiler_to_use, target);
-        copy_target_libs(builder, target, &image, &stamp);
+        copy_target_libs(builder, target, tarball.image_dir(), &stamp);
 
-        // Copy compiler sources.
-        let dst_src = image.join("lib/rustlib/rustc-src/rust");
-        t!(fs::create_dir_all(&dst_src));
-
-        let src_files = ["Cargo.lock"];
+        let src_files = &["Cargo.lock"];
         // This is the reduced set of paths which will become the rustc-dev component
         // (essentially the compiler crates and all of their path dependencies).
-        copy_src_dirs(builder, &builder.src, &["compiler"], &[], &dst_src);
-        for file in src_files.iter() {
-            builder.copy(&builder.src.join(file), &dst_src.join(file));
+        copy_src_dirs(
+            builder,
+            &builder.src,
+            &["compiler"],
+            &[],
+            &tarball.image_dir().join("lib/rustlib/rustc-src/rust"),
+        );
+        for file in src_files {
+            tarball.add_file(builder.src.join(file), "lib/rustlib/rustc-src/rust", 0o644);
         }
 
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=Rust-is-ready-to-develop.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg(format!("--package-name={}-{}", name, target.triple))
-            .arg(format!("--component-name=rustc-dev-{}", target.triple))
-            .arg("--legacy-manifest-dirs=rustlib,cargo");
-
-        builder.info(&format!(
-            "Dist rustc-dev stage{} ({} -> {})",
-            compiler.stage, &compiler.host, target
-        ));
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-        builder.remove_dir(&image);
-        archive
+        Some(tarball.generate())
     }
 }
 
@@ -832,7 +660,7 @@ pub struct Analysis {
 }
 
 impl Step for Analysis {
-    type Output = PathBuf;
+    type Output = Option<GeneratedTarball>;
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -855,52 +683,26 @@ impl Step for Analysis {
     }
 
     /// Creates a tarball of save-analysis metadata, if available.
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
+    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let compiler = self.compiler;
         let target = self.target;
         assert!(builder.config.extended);
-        let name = pkgname(builder, "rust-analysis");
-
         if compiler.host != builder.config.build {
-            return distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple));
+            return None;
         }
 
         builder.ensure(compile::Std { compiler, target });
-
-        let image = tmpdir(builder).join(format!("{}-{}-image", name, target.triple));
-
         let src = builder
             .stage_out(compiler, Mode::Std)
             .join(target.triple)
             .join(builder.cargo_dir())
-            .join("deps");
+            .join("deps")
+            .join("save-analysis");
 
-        let image_src = src.join("save-analysis");
-        let dst = image.join("lib/rustlib").join(target.triple).join("analysis");
-        t!(fs::create_dir_all(&dst));
-        builder.info(&format!("image_src: {:?}, dst: {:?}", image_src, dst));
-        builder.cp_r(&image_src, &dst);
-
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=save-analysis-saved.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg(format!("--package-name={}-{}", name, target.triple))
-            .arg(format!("--component-name=rust-analysis-{}", target.triple))
-            .arg("--legacy-manifest-dirs=rustlib,cargo");
-
-        builder.info("Dist analysis");
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-        builder.remove_dir(&image);
-        distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))
+        let mut tarball = Tarball::new(builder, "rust-analysis", &target.triple);
+        tarball.include_target_in_component_name(true);
+        tarball.add_dir(src, format!("lib/rustlib/{}/analysis", target.triple));
+        Some(tarball.generate())
     }
 }
 
@@ -994,7 +796,7 @@ pub struct Src;
 
 impl Step for Src {
     /// The output path of the src installer tarball
-    type Output = PathBuf;
+    type Output = GeneratedTarball;
     const DEFAULT: bool = true;
     const ONLY_HOSTS: bool = true;
 
@@ -1007,10 +809,8 @@ impl Step for Src {
     }
 
     /// Creates the `rust-src` installer component
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
-        let name = pkgname(builder, "rust-src");
-        let image = tmpdir(builder).join(format!("{}-image", name));
-        let _ = fs::remove_dir_all(&image);
+    fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
+        let tarball = Tarball::new_targetless(builder, "rust-src");
 
         // A lot of tools expect the rust-src component to be entirely in this directory, so if you
         // change that (e.g. by adding another directory `lib/rustlib/src/foo` or
@@ -1019,8 +819,7 @@ impl Step for Src {
         //
         // NOTE: if you update the paths here, you also should update the "virtual" path
         // translation code in `imported_source_files` in `src/librustc_metadata/rmeta/decoder.rs`
-        let dst_src = image.join("lib/rustlib/src/rust");
-        t!(fs::create_dir_all(&dst_src));
+        let dst_src = tarball.image_dir().join("lib/rustlib/src/rust");
 
         let src_files = ["Cargo.lock"];
         // This is the reduced set of paths which will become the rust-src component
@@ -1040,50 +839,7 @@ impl Step for Src {
             builder.copy(&builder.src.join(file), &dst_src.join(file));
         }
 
-        // libtest includes std and everything else, so vendoring it
-        // creates exactly what's needed for `cargo -Zbuild-std` or any
-        // other analysis of the stdlib's source. Cargo also needs help
-        // finding the lock, so we copy it to libtest temporarily.
-        //
-        // Note that this requires std to only have one version of each
-        // crate. e.g. two versions of getopts won't be patchable.
-        let dst_libtest = dst_src.join("library/test");
-        let dst_vendor = dst_src.join("vendor");
-        let root_lock = dst_src.join("Cargo.lock");
-        let temp_lock = dst_libtest.join("Cargo.lock");
-
-        // `cargo vendor` will delete everything from the lockfile that
-        // isn't used by libtest, so we need to not use any links!
-        builder.really_copy(&root_lock, &temp_lock);
-
-        let mut cmd = Command::new(&builder.initial_cargo);
-        cmd.arg("vendor").arg(dst_vendor).current_dir(&dst_libtest);
-        builder.info("Dist src");
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-
-        builder.remove(&temp_lock);
-
-        // Create source tarball in rust-installer format
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=Awesome-Source.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg(format!("--package-name={}", name))
-            .arg("--component-name=rust-src")
-            .arg("--legacy-manifest-dirs=rustlib,cargo");
-
-        builder.run(&mut cmd);
-
-        builder.remove_dir(&image);
-        distdir(builder).join(&format!("{}.tar.gz", name))
+        tarball.generate()
     }
 }
 
@@ -1092,7 +848,7 @@ pub struct PlainSourceTarball;
 
 impl Step for PlainSourceTarball {
     /// Produces the location of the tarball generated
-    type Output = PathBuf;
+    type Output = GeneratedTarball;
     const DEFAULT: bool = true;
     const ONLY_HOSTS: bool = true;
 
@@ -1106,12 +862,9 @@ impl Step for PlainSourceTarball {
     }
 
     /// Creates the plain source tarball
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
-        // Make sure that the root folder of tarball has the correct name
-        let plain_name = format!("{}-src", pkgname(builder, "rustc"));
-        let plain_dst_src = tmpdir(builder).join(&plain_name);
-        let _ = fs::remove_dir_all(&plain_dst_src);
-        t!(fs::create_dir_all(&plain_dst_src));
+    fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
+        let tarball = Tarball::new(builder, "rustc", "src");
+        let plain_dst_src = tarball.image_dir();
 
         // This is the set of root paths which will become part of the source package
         let src_files = [
@@ -1154,28 +907,7 @@ impl Step for PlainSourceTarball {
             builder.run(&mut cmd);
         }
 
-        // Create plain source tarball
-        let plain_name = format!("rustc-{}-src", builder.rust_package_vers());
-        let mut tarball = distdir(builder).join(&format!("{}.tar.gz", plain_name));
-        tarball.set_extension(""); // strip .gz
-        tarball.set_extension(""); // strip .tar
-        if let Some(dir) = tarball.parent() {
-            builder.create_dir(&dir);
-        }
-        builder.info("running installer");
-        let mut cmd = rust_installer(builder);
-        cmd.arg("tarball")
-            .arg("--input")
-            .arg(&plain_name)
-            .arg("--output")
-            .arg(&tarball)
-            .arg("--work-dir=.")
-            .current_dir(tmpdir(builder));
-
-        builder.info("Create plain source tarball");
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-        distdir(builder).join(&format!("{}.tar.gz", plain_name))
+        tarball.bare()
     }
 }
 
@@ -1186,7 +918,7 @@ pub fn sanitize_sh(path: &Path) -> String {
     return change_drive(unc_to_lfs(&path)).unwrap_or(path);
 
     fn unc_to_lfs(s: &str) -> &str {
-        if s.starts_with("//?/") { &s[4..] } else { s }
+        s.strip_prefix("//?/").unwrap_or(s)
     }
 
     fn change_drive(s: &str) -> Option<String> {
@@ -1209,7 +941,7 @@ pub struct Cargo {
 }
 
 impl Step for Cargo {
-    type Output = PathBuf;
+    type Output = GeneratedTarball;
     const ONLY_HOSTS: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -1227,70 +959,32 @@ impl Step for Cargo {
         });
     }
 
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
+    fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
         let compiler = self.compiler;
         let target = self.target;
 
+        let cargo = builder.ensure(tool::Cargo { compiler, target });
         let src = builder.src.join("src/tools/cargo");
         let etc = src.join("src/etc");
-        let release_num = builder.release_num("cargo");
-        let name = pkgname(builder, "cargo");
-        let version = builder.cargo_info.version(builder, &release_num);
-
-        let tmp = tmpdir(builder);
-        let image = tmp.join("cargo-image");
-        drop(fs::remove_dir_all(&image));
-        builder.create_dir(&image);
 
         // Prepare the image directory
-        builder.create_dir(&image.join("share/zsh/site-functions"));
-        builder.create_dir(&image.join("etc/bash_completion.d"));
-        let cargo = builder.ensure(tool::Cargo { compiler, target });
-        builder.install(&cargo, &image.join("bin"), 0o755);
-        for man in t!(etc.join("man").read_dir()) {
-            let man = t!(man);
-            builder.install(&man.path(), &image.join("share/man/man1"), 0o644);
+        let mut tarball = Tarball::new(builder, "cargo", &target.triple);
+        tarball.set_overlay(OverlayKind::Cargo);
+
+        tarball.add_file(&cargo, "bin", 0o755);
+        tarball.add_file(etc.join("_cargo"), "share/zsh/site-functions", 0o644);
+        tarball.add_renamed_file(etc.join("cargo.bashcomp.sh"), "etc/bash_completion.d", "cargo");
+        tarball.add_dir(etc.join("man"), "share/man/man1");
+        tarball.add_legal_and_readme_to("share/doc/cargo");
+
+        for dirent in fs::read_dir(cargo.parent().unwrap()).expect("read_dir") {
+            let dirent = dirent.expect("read dir entry");
+            if dirent.file_name().to_str().expect("utf8").starts_with("cargo-credential-") {
+                tarball.add_file(&dirent.path(), "libexec", 0o755);
+            }
         }
-        builder.install(&etc.join("_cargo"), &image.join("share/zsh/site-functions"), 0o644);
-        builder.copy(&etc.join("cargo.bashcomp.sh"), &image.join("etc/bash_completion.d/cargo"));
-        let doc = image.join("share/doc/cargo");
-        builder.install(&src.join("README.md"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-THIRD-PARTY"), &doc, 0o644);
-
-        // Prepare the overlay
-        let overlay = tmp.join("cargo-overlay");
-        drop(fs::remove_dir_all(&overlay));
-        builder.create_dir(&overlay);
-        builder.install(&src.join("README.md"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE-MIT"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE-APACHE"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE-THIRD-PARTY"), &overlay, 0o644);
-        builder.create(&overlay.join("version"), &version);
-
-        // Generate the installer tarball
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=Rust-is-ready-to-roll.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg("--non-installed-overlay")
-            .arg(&overlay)
-            .arg(format!("--package-name={}-{}", name, target.triple))
-            .arg("--component-name=cargo")
-            .arg("--legacy-manifest-dirs=rustlib,cargo");
-
-        builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target));
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-        distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))
+
+        tarball.generate()
     }
 }
 
@@ -1301,7 +995,7 @@ pub struct Rls {
 }
 
 impl Step for Rls {
-    type Output = Option<PathBuf>;
+    type Output = Option<GeneratedTarball>;
     const ONLY_HOSTS: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -1319,24 +1013,11 @@ impl Step for Rls {
         });
     }
 
-    fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
+    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let compiler = self.compiler;
         let target = self.target;
         assert!(builder.config.extended);
 
-        let src = builder.src.join("src/tools/rls");
-        let release_num = builder.release_num("rls");
-        let name = pkgname(builder, "rls");
-        let version = builder.rls_info.version(builder, &release_num);
-
-        let tmp = tmpdir(builder);
-        let image = tmp.join("rls-image");
-        drop(fs::remove_dir_all(&image));
-        t!(fs::create_dir_all(&image));
-
-        // Prepare the image directory
-        // We expect RLS to build, because we've exited this step above if tool
-        // state for RLS isn't testing.
         let rls = builder
             .ensure(tool::Rls { compiler, target, extra_features: Vec::new() })
             .or_else(|| {
@@ -1344,43 +1025,12 @@ impl Step for Rls {
                 None
             })?;
 
-        builder.install(&rls, &image.join("bin"), 0o755);
-        let doc = image.join("share/doc/rls");
-        builder.install(&src.join("README.md"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
-
-        // Prepare the overlay
-        let overlay = tmp.join("rls-overlay");
-        drop(fs::remove_dir_all(&overlay));
-        t!(fs::create_dir_all(&overlay));
-        builder.install(&src.join("README.md"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE-MIT"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE-APACHE"), &overlay, 0o644);
-        builder.create(&overlay.join("version"), &version);
-
-        // Generate the installer tarball
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=RLS-ready-to-serve.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg("--non-installed-overlay")
-            .arg(&overlay)
-            .arg(format!("--package-name={}-{}", name, target.triple))
-            .arg("--legacy-manifest-dirs=rustlib,cargo")
-            .arg("--component-name=rls-preview");
-
-        builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target.triple));
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-        Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
+        let mut tarball = Tarball::new(builder, "rls", &target.triple);
+        tarball.set_overlay(OverlayKind::RLS);
+        tarball.is_preview(true);
+        tarball.add_file(rls, "bin", 0o755);
+        tarball.add_legal_and_readme_to("share/doc/rls");
+        Some(tarball.generate())
     }
 }
 
@@ -1391,7 +1041,7 @@ pub struct RustAnalyzer {
 }
 
 impl Step for RustAnalyzer {
-    type Output = Option<PathBuf>;
+    type Output = Option<GeneratedTarball>;
     const ONLY_HOSTS: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -1409,7 +1059,7 @@ impl Step for RustAnalyzer {
         });
     }
 
-    fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
+    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let compiler = self.compiler;
         let target = self.target;
         assert!(builder.config.extended);
@@ -1420,60 +1070,16 @@ impl Step for RustAnalyzer {
             return None;
         }
 
-        let src = builder.src.join("src/tools/rust-analyzer");
-        let release_num = builder.release_num("rust-analyzer/crates/rust-analyzer");
-        let name = pkgname(builder, "rust-analyzer");
-        let version = builder.rust_analyzer_info.version(builder, &release_num);
-
-        let tmp = tmpdir(builder);
-        let image = tmp.join("rust-analyzer-image");
-        drop(fs::remove_dir_all(&image));
-        builder.create_dir(&image);
-
-        // Prepare the image directory
-        // We expect rust-analyer to always build, as it doesn't depend on rustc internals
-        // and doesn't have associated toolstate.
         let rust_analyzer = builder
             .ensure(tool::RustAnalyzer { compiler, target, extra_features: Vec::new() })
             .expect("rust-analyzer always builds");
 
-        builder.install(&rust_analyzer, &image.join("bin"), 0o755);
-        let doc = image.join("share/doc/rust-analyzer");
-        builder.install(&src.join("README.md"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
-
-        // Prepare the overlay
-        let overlay = tmp.join("rust-analyzer-overlay");
-        drop(fs::remove_dir_all(&overlay));
-        t!(fs::create_dir_all(&overlay));
-        builder.install(&src.join("README.md"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
-        builder.create(&overlay.join("version"), &version);
-
-        // Generate the installer tarball
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=rust-analyzer-ready-to-serve.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg("--non-installed-overlay")
-            .arg(&overlay)
-            .arg(format!("--package-name={}-{}", name, target.triple))
-            .arg("--legacy-manifest-dirs=rustlib,cargo")
-            .arg("--component-name=rust-analyzer-preview");
-
-        builder.info(&format!("Dist rust-analyzer stage{} ({})", compiler.stage, target));
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-        Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
+        let mut tarball = Tarball::new(builder, "rust-analyzer", &target.triple);
+        tarball.set_overlay(OverlayKind::RustAnalyzer);
+        tarball.is_preview(true);
+        tarball.add_file(rust_analyzer, "bin", 0o755);
+        tarball.add_legal_and_readme_to("share/doc/rust-analyzer");
+        Some(tarball.generate())
     }
 }
 
@@ -1484,7 +1090,7 @@ pub struct Clippy {
 }
 
 impl Step for Clippy {
-    type Output = PathBuf;
+    type Output = GeneratedTarball;
     const ONLY_HOSTS: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -1502,21 +1108,11 @@ impl Step for Clippy {
         });
     }
 
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
+    fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
         let compiler = self.compiler;
         let target = self.target;
         assert!(builder.config.extended);
 
-        let src = builder.src.join("src/tools/clippy");
-        let release_num = builder.release_num("clippy");
-        let name = pkgname(builder, "clippy");
-        let version = builder.clippy_info.version(builder, &release_num);
-
-        let tmp = tmpdir(builder);
-        let image = tmp.join("clippy-image");
-        drop(fs::remove_dir_all(&image));
-        builder.create_dir(&image);
-
         // Prepare the image directory
         // We expect clippy to build, because we've exited this step above if tool
         // state for clippy isn't testing.
@@ -1527,44 +1123,13 @@ impl Step for Clippy {
             .ensure(tool::CargoClippy { compiler, target, extra_features: Vec::new() })
             .expect("clippy expected to build - essential tool");
 
-        builder.install(&clippy, &image.join("bin"), 0o755);
-        builder.install(&cargoclippy, &image.join("bin"), 0o755);
-        let doc = image.join("share/doc/clippy");
-        builder.install(&src.join("README.md"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
-
-        // Prepare the overlay
-        let overlay = tmp.join("clippy-overlay");
-        drop(fs::remove_dir_all(&overlay));
-        t!(fs::create_dir_all(&overlay));
-        builder.install(&src.join("README.md"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
-        builder.create(&overlay.join("version"), &version);
-
-        // Generate the installer tarball
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=clippy-ready-to-serve.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg("--non-installed-overlay")
-            .arg(&overlay)
-            .arg(format!("--package-name={}-{}", name, target.triple))
-            .arg("--legacy-manifest-dirs=rustlib,cargo")
-            .arg("--component-name=clippy-preview");
-
-        builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target));
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-        distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))
+        let mut tarball = Tarball::new(builder, "clippy", &target.triple);
+        tarball.set_overlay(OverlayKind::Clippy);
+        tarball.is_preview(true);
+        tarball.add_file(clippy, "bin", 0o755);
+        tarball.add_file(cargoclippy, "bin", 0o755);
+        tarball.add_legal_and_readme_to("share/doc/clippy");
+        tarball.generate()
     }
 }
 
@@ -1575,7 +1140,7 @@ pub struct Miri {
 }
 
 impl Step for Miri {
-    type Output = Option<PathBuf>;
+    type Output = Option<GeneratedTarball>;
     const ONLY_HOSTS: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -1593,24 +1158,11 @@ impl Step for Miri {
         });
     }
 
-    fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
+    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let compiler = self.compiler;
         let target = self.target;
         assert!(builder.config.extended);
 
-        let src = builder.src.join("src/tools/miri");
-        let release_num = builder.release_num("miri");
-        let name = pkgname(builder, "miri");
-        let version = builder.miri_info.version(builder, &release_num);
-
-        let tmp = tmpdir(builder);
-        let image = tmp.join("miri-image");
-        drop(fs::remove_dir_all(&image));
-        builder.create_dir(&image);
-
-        // Prepare the image directory
-        // We expect miri to build, because we've exited this step above if tool
-        // state for miri isn't testing.
         let miri = builder
             .ensure(tool::Miri { compiler, target, extra_features: Vec::new() })
             .or_else(|| {
@@ -1624,44 +1176,13 @@ impl Step for Miri {
                 None
             })?;
 
-        builder.install(&miri, &image.join("bin"), 0o755);
-        builder.install(&cargomiri, &image.join("bin"), 0o755);
-        let doc = image.join("share/doc/miri");
-        builder.install(&src.join("README.md"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
-
-        // Prepare the overlay
-        let overlay = tmp.join("miri-overlay");
-        drop(fs::remove_dir_all(&overlay));
-        t!(fs::create_dir_all(&overlay));
-        builder.install(&src.join("README.md"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
-        builder.create(&overlay.join("version"), &version);
-
-        // Generate the installer tarball
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=miri-ready-to-serve.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg("--non-installed-overlay")
-            .arg(&overlay)
-            .arg(format!("--package-name={}-{}", name, target.triple))
-            .arg("--legacy-manifest-dirs=rustlib,cargo")
-            .arg("--component-name=miri-preview");
-
-        builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target));
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-        Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
+        let mut tarball = Tarball::new(builder, "miri", &target.triple);
+        tarball.set_overlay(OverlayKind::Miri);
+        tarball.is_preview(true);
+        tarball.add_file(miri, "bin", 0o755);
+        tarball.add_file(cargomiri, "bin", 0o755);
+        tarball.add_legal_and_readme_to("share/doc/miri");
+        Some(tarball.generate())
     }
 }
 
@@ -1672,7 +1193,7 @@ pub struct Rustfmt {
 }
 
 impl Step for Rustfmt {
-    type Output = Option<PathBuf>;
+    type Output = Option<GeneratedTarball>;
     const ONLY_HOSTS: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -1690,21 +1211,10 @@ impl Step for Rustfmt {
         });
     }
 
-    fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
+    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let compiler = self.compiler;
         let target = self.target;
 
-        let src = builder.src.join("src/tools/rustfmt");
-        let release_num = builder.release_num("rustfmt");
-        let name = pkgname(builder, "rustfmt");
-        let version = builder.rustfmt_info.version(builder, &release_num);
-
-        let tmp = tmpdir(builder);
-        let image = tmp.join("rustfmt-image");
-        drop(fs::remove_dir_all(&image));
-        builder.create_dir(&image);
-
-        // Prepare the image directory
         let rustfmt = builder
             .ensure(tool::Rustfmt { compiler, target, extra_features: Vec::new() })
             .or_else(|| {
@@ -1718,44 +1228,13 @@ impl Step for Rustfmt {
                 None
             })?;
 
-        builder.install(&rustfmt, &image.join("bin"), 0o755);
-        builder.install(&cargofmt, &image.join("bin"), 0o755);
-        let doc = image.join("share/doc/rustfmt");
-        builder.install(&src.join("README.md"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
-        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
-
-        // Prepare the overlay
-        let overlay = tmp.join("rustfmt-overlay");
-        drop(fs::remove_dir_all(&overlay));
-        builder.create_dir(&overlay);
-        builder.install(&src.join("README.md"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE-MIT"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE-APACHE"), &overlay, 0o644);
-        builder.create(&overlay.join("version"), &version);
-
-        // Generate the installer tarball
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=rustfmt-ready-to-fmt.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg("--non-installed-overlay")
-            .arg(&overlay)
-            .arg(format!("--package-name={}-{}", name, target.triple))
-            .arg("--legacy-manifest-dirs=rustlib,cargo")
-            .arg("--component-name=rustfmt-preview");
-
-        builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target));
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-        Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
+        let mut tarball = Tarball::new(builder, "rustfmt", &target.triple);
+        tarball.set_overlay(OverlayKind::Rustfmt);
+        tarball.is_preview(true);
+        tarball.add_file(rustfmt, "bin", 0o755);
+        tarball.add_file(cargofmt, "bin", 0o755);
+        tarball.add_legal_and_readme_to("share/doc/rustfmt");
+        Some(tarball.generate())
     }
 }
 
@@ -1804,24 +1283,14 @@ impl Step for Extended {
         let analysis_installer = builder.ensure(Analysis { compiler, target });
 
         let docs_installer = builder.ensure(Docs { host: target });
-        let std_installer =
-            builder.ensure(Std { compiler: builder.compiler(stage, target), target });
+        let std_installer = builder.ensure(Std { compiler, target });
 
-        let tmp = tmpdir(builder);
-        let overlay = tmp.join("extended-overlay");
         let etc = builder.src.join("src/etc/installer");
-        let work = tmp.join("work");
-
-        let _ = fs::remove_dir_all(&overlay);
-        builder.install(&builder.src.join("COPYRIGHT"), &overlay, 0o644);
-        builder.install(&builder.src.join("LICENSE-APACHE"), &overlay, 0o644);
-        builder.install(&builder.src.join("LICENSE-MIT"), &overlay, 0o644);
-        let version = builder.rust_version();
-        builder.create(&overlay.join("version"), &version);
-        if let Some(sha) = builder.rust_sha() {
-            builder.create(&overlay.join("git-commit-hash"), &sha);
+
+        // Avoid producing tarballs during a dry run.
+        if builder.config.dry_run {
+            return;
         }
-        builder.install(&etc.join("README.md"), &overlay, 0o644);
 
         // When rust-std package split from rustc, we needed to ensure that during
         // upgrades rustc was upgraded before rust-std. To avoid rustc clobbering
@@ -1836,39 +1305,22 @@ impl Step for Extended {
         tarballs.extend(miri_installer.clone());
         tarballs.extend(rustfmt_installer.clone());
         tarballs.extend(llvm_tools_installer);
-        tarballs.push(analysis_installer);
-        tarballs.push(std_installer);
-        if builder.config.docs {
+        if let Some(analysis_installer) = analysis_installer {
+            tarballs.push(analysis_installer);
+        }
+        tarballs.push(std_installer.expect("missing std"));
+        if let Some(docs_installer) = docs_installer {
             tarballs.push(docs_installer);
         }
         if target.contains("pc-windows-gnu") {
             tarballs.push(mingw_installer.unwrap());
         }
-        let mut input_tarballs = tarballs[0].as_os_str().to_owned();
-        for tarball in &tarballs[1..] {
-            input_tarballs.push(",");
-            input_tarballs.push(tarball);
-        }
 
-        builder.info("building combined installer");
-        let mut cmd = rust_installer(builder);
-        cmd.arg("combine")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=Rust-is-ready-to-roll.")
-            .arg("--work-dir")
-            .arg(&work)
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg(format!("--package-name={}-{}", pkgname(builder, "rust"), target.triple))
-            .arg("--legacy-manifest-dirs=rustlib,cargo")
-            .arg("--input-tarballs")
-            .arg(input_tarballs)
-            .arg("--non-installed-overlay")
-            .arg(&overlay);
-        let time = timeit(&builder);
-        builder.run(&mut cmd);
-        drop(time);
+        let tarball = Tarball::new(builder, "rust", &target.triple);
+        let generated = tarball.combine(&tarballs);
+
+        let tmp = tmpdir(builder).join("combined-tarball");
+        let work = generated.work_dir();
 
         let mut license = String::new();
         license += &builder.read(&builder.src.join("COPYRIGHT"));
@@ -2418,7 +1870,7 @@ pub struct LlvmTools {
 }
 
 impl Step for LlvmTools {
-    type Output = Option<PathBuf>;
+    type Output = Option<GeneratedTarball>;
     const ONLY_HOSTS: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -2429,7 +1881,7 @@ impl Step for LlvmTools {
         run.builder.ensure(LlvmTools { target: run.target });
     }
 
-    fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
+    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let target = self.target;
         assert!(builder.config.extended);
 
@@ -2441,58 +1893,25 @@ impl Step for LlvmTools {
             }
         }
 
-        builder.info(&format!("Dist LlvmTools ({})", target));
-        let _time = timeit(builder);
-        let src = builder.src.join("src/llvm-project/llvm");
-        let name = pkgname(builder, "llvm-tools");
-
-        let tmp = tmpdir(builder);
-        let image = tmp.join("llvm-tools-image");
-        drop(fs::remove_dir_all(&image));
+        let mut tarball = Tarball::new(builder, "llvm-tools", &target.triple);
+        tarball.set_overlay(OverlayKind::LLVM);
+        tarball.is_preview(true);
 
         // Prepare the image directory
         let src_bindir = builder.llvm_out(target).join("bin");
-        let dst_bindir = image.join("lib/rustlib").join(&*target.triple).join("bin");
-        t!(fs::create_dir_all(&dst_bindir));
+        let dst_bindir = format!("lib/rustlib/{}/bin", target.triple);
         for tool in LLVM_TOOLS {
             let exe = src_bindir.join(exe(tool, target));
-            builder.install(&exe, &dst_bindir, 0o755);
+            tarball.add_file(&exe, &dst_bindir, 0o755);
         }
 
         // Copy libLLVM.so to the target lib dir as well, so the RPATH like
         // `$ORIGIN/../lib` can find it. It may also be used as a dependency
         // of `rustc-dev` to support the inherited `-lLLVM` when using the
         // compiler libraries.
-        maybe_install_llvm_target(builder, target, &image);
-
-        // Prepare the overlay
-        let overlay = tmp.join("llvm-tools-overlay");
-        drop(fs::remove_dir_all(&overlay));
-        builder.create_dir(&overlay);
-        builder.install(&src.join("README.txt"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE.TXT"), &overlay, 0o644);
-        builder.create(&overlay.join("version"), &builder.llvm_tools_vers());
-
-        // Generate the installer tarball
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=llvm-tools-installed.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg("--non-installed-overlay")
-            .arg(&overlay)
-            .arg(format!("--package-name={}-{}", name, target.triple))
-            .arg("--legacy-manifest-dirs=rustlib,cargo")
-            .arg("--component-name=llvm-tools-preview");
-
-        builder.run(&mut cmd);
-        Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
+        maybe_install_llvm_target(builder, target, tarball.image_dir());
+
+        Some(tarball.generate())
     }
 }
 
@@ -2505,7 +1924,7 @@ pub struct RustDev {
 }
 
 impl Step for RustDev {
-    type Output = Option<PathBuf>;
+    type Output = Option<GeneratedTarball>;
     const DEFAULT: bool = true;
     const ONLY_HOSTS: bool = true;
 
@@ -2517,7 +1936,7 @@ impl Step for RustDev {
         run.builder.ensure(RustDev { target: run.target });
     }
 
-    fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
+    fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let target = self.target;
 
         /* run only if llvm-config isn't used */
@@ -2528,69 +1947,35 @@ impl Step for RustDev {
             }
         }
 
-        builder.info(&format!("Dist RustDev ({})", target));
-        let _time = timeit(builder);
-        let src = builder.src.join("src/llvm-project/llvm");
-        let name = pkgname(builder, "rust-dev");
-
-        let tmp = tmpdir(builder);
-        let image = tmp.join("rust-dev-image");
-        drop(fs::remove_dir_all(&image));
-
-        // Prepare the image directory
-        let dst_bindir = image.join("bin");
-        t!(fs::create_dir_all(&dst_bindir));
+        let mut tarball = Tarball::new(builder, "rust-dev", &target.triple);
+        tarball.set_overlay(OverlayKind::LLVM);
 
         let src_bindir = builder.llvm_out(target).join("bin");
-        let install_bin =
-            |name| builder.install(&src_bindir.join(exe(name, target)), &dst_bindir, 0o755);
-        install_bin("llvm-config");
-        install_bin("llvm-ar");
-        install_bin("llvm-objdump");
-        install_bin("llvm-profdata");
-        install_bin("llvm-bcanalyzer");
-        install_bin("llvm-cov");
-        builder.install(&builder.llvm_filecheck(target), &dst_bindir, 0o755);
+        for bin in &[
+            "llvm-config",
+            "llvm-ar",
+            "llvm-objdump",
+            "llvm-profdata",
+            "llvm-bcanalyzer",
+            "llvm-cov",
+            "llvm-dwp",
+        ] {
+            tarball.add_file(src_bindir.join(exe(bin, target)), "bin", 0o755);
+        }
+        tarball.add_file(&builder.llvm_filecheck(target), "bin", 0o755);
 
         // Copy the include directory as well; needed mostly to build
         // librustc_llvm properly (e.g., llvm-config.h is in here). But also
         // just broadly useful to be able to link against the bundled LLVM.
-        builder.cp_r(&builder.llvm_out(target).join("include"), &image.join("include"));
+        tarball.add_dir(&builder.llvm_out(target).join("include"), "include");
 
         // Copy libLLVM.so to the target lib dir as well, so the RPATH like
         // `$ORIGIN/../lib` can find it. It may also be used as a dependency
         // of `rustc-dev` to support the inherited `-lLLVM` when using the
         // compiler libraries.
-        maybe_install_llvm(builder, target, &image.join("lib"));
-
-        // Prepare the overlay
-        let overlay = tmp.join("rust-dev-overlay");
-        drop(fs::remove_dir_all(&overlay));
-        builder.create_dir(&overlay);
-        builder.install(&src.join("README.txt"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE.TXT"), &overlay, 0o644);
-        builder.create(&overlay.join("version"), &builder.rust_version());
-
-        // Generate the installer tarball
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=rust-dev-installed.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg("--non-installed-overlay")
-            .arg(&overlay)
-            .arg(format!("--package-name={}-{}", name, target.triple))
-            .arg("--legacy-manifest-dirs=rustlib,cargo")
-            .arg("--component-name=rust-dev");
-
-        builder.run(&mut cmd);
-        Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
+        maybe_install_llvm(builder, target, &tarball.image_dir().join("lib"));
+
+        Some(tarball.generate())
     }
 }
 
@@ -2604,7 +1989,7 @@ pub struct BuildManifest {
 }
 
 impl Step for BuildManifest {
-    type Output = PathBuf;
+    type Output = GeneratedTarball;
     const DEFAULT: bool = false;
     const ONLY_HOSTS: bool = true;
 
@@ -2616,47 +2001,43 @@ impl Step for BuildManifest {
         run.builder.ensure(BuildManifest { target: run.target });
     }
 
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
+    fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
         let build_manifest = builder.tool_exe(Tool::BuildManifest);
 
-        let name = pkgname(builder, "build-manifest");
-        let tmp = tmpdir(builder);
-
-        // Prepare the image.
-        let image = tmp.join("build-manifest-image");
-        let image_bin = image.join("bin");
-        let _ = fs::remove_dir_all(&image);
-        t!(fs::create_dir_all(&image_bin));
-        builder.install(&build_manifest, &image_bin, 0o755);
-
-        // Prepare the overlay.
-        let overlay = tmp.join("build-manifest-overlay");
-        let _ = fs::remove_dir_all(&overlay);
-        builder.create_dir(&overlay);
-        builder.create(&overlay.join("version"), &builder.rust_version());
-        for file in &["COPYRIGHT", "LICENSE-APACHE", "LICENSE-MIT", "README.md"] {
-            builder.install(&builder.src.join(file), &overlay, 0o644);
-        }
+        let tarball = Tarball::new(builder, "build-manifest", &self.target.triple);
+        tarball.add_file(&build_manifest, "bin", 0o755);
+        tarball.generate()
+    }
+}
+
+/// Tarball containing artifacts necessary to reproduce the build of rustc.
+///
+/// Currently this is the PGO profile data.
+///
+/// Should not be considered stable by end users.
+#[derive(Clone, Debug, Eq, Hash, PartialEq)]
+pub struct ReproducibleArtifacts {
+    pub target: TargetSelection,
+}
+
+impl Step for ReproducibleArtifacts {
+    type Output = Option<GeneratedTarball>;
+    const DEFAULT: bool = true;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("reproducible")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(ReproducibleArtifacts { target: run.target });
+    }
+
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        let path = builder.config.rust_profile_use.as_ref()?;
 
-        // Create the final tarball.
-        let mut cmd = rust_installer(builder);
-        cmd.arg("generate")
-            .arg("--product-name=Rust")
-            .arg("--rel-manifest-dir=rustlib")
-            .arg("--success-message=build-manifest installed.")
-            .arg("--image-dir")
-            .arg(&image)
-            .arg("--work-dir")
-            .arg(&tmpdir(builder))
-            .arg("--output-dir")
-            .arg(&distdir(builder))
-            .arg("--non-installed-overlay")
-            .arg(&overlay)
-            .arg(format!("--package-name={}-{}", name, self.target.triple))
-            .arg("--legacy-manifest-dirs=rustlib,cargo")
-            .arg("--component-name=build-manifest");
-
-        builder.run(&mut cmd);
-        distdir(builder).join(format!("{}-{}.tar.gz", name, self.target.triple))
+        let tarball = Tarball::new(builder, "reproducible-artifacts", &self.target.triple);
+        tarball.add_file(path, ".", 0o644);
+        Some(tarball.generate())
     }
 }
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index a296a1fe3f4..8c849846676 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -500,18 +500,17 @@ impl Step for Rustc {
         let target = self.target;
         builder.info(&format!("Documenting stage{} compiler ({})", stage, target));
 
-        // This is the intended out directory for compiler documentation.
-        let out = builder.compiler_doc_out(target);
-        t!(fs::create_dir_all(&out));
-
-        let compiler = builder.compiler(stage, builder.config.build);
-
         if !builder.config.compiler_docs {
             builder.info("\tskipping - compiler/librustdoc docs disabled");
             return;
         }
 
+        // This is the intended out directory for compiler documentation.
+        let out = builder.compiler_doc_out(target);
+        t!(fs::create_dir_all(&out));
+
         // Build rustc.
+        let compiler = builder.compiler(stage, builder.config.build);
         builder.ensure(compile::Rustc { compiler, target });
 
         // This uses a shared directory so that librustdoc documentation gets
@@ -521,6 +520,10 @@ impl Step for Rustc {
         // merging the search index, or generating local (relative) links.
         let out_dir = builder.stage_out(compiler, Mode::Rustc).join(target.triple).join("doc");
         t!(symlink_dir_force(&builder.config, &out, &out_dir));
+        // Cargo puts proc macros in `target/doc` even if you pass `--target`
+        // explicitly (https://github.com/rust-lang/cargo/issues/7677).
+        let proc_macro_out_dir = builder.stage_out(compiler, Mode::Rustc).join("doc");
+        t!(symlink_dir_force(&builder.config, &out, &proc_macro_out_dir));
 
         // Build cargo command.
         let mut cargo = builder.cargo(compiler, Mode::Rustc, SourceType::InTree, target, "doc");
@@ -625,6 +628,8 @@ impl Step for Rustdoc {
         cargo.arg("-p").arg("rustdoc");
 
         cargo.rustdocflag("--document-private-items");
+        cargo.rustdocflag("--enable-index-page");
+        cargo.rustdocflag("-Zunstable-options");
         builder.run(&mut cargo.into());
     }
 }
diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp
index d857618eefa..b29ecd65401 100644
--- a/src/bootstrap/download-ci-llvm-stamp
+++ b/src/bootstrap/download-ci-llvm-stamp
@@ -1,4 +1,4 @@
 Change this file to make users of the `download-ci-llvm` configuration download
 a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.
 
-Last change is for: https://github.com/rust-lang/rust/pull/78131
+Last change is for: https://github.com/rust-lang/rust/pull/80087
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 5a8096674c6..d6a45f1c170 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -68,6 +68,9 @@ pub struct Flags {
     pub deny_warnings: Option<bool>,
 
     pub llvm_skip_rebuild: Option<bool>,
+
+    pub rust_profile_use: Option<String>,
+    pub rust_profile_generate: Option<String>,
 }
 
 pub enum Subcommand {
@@ -219,6 +222,8 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
              VALUE overrides the skip-rebuild option in config.toml.",
             "VALUE",
         );
+        opts.optopt("", "rust-profile-generate", "rustc error format", "FORMAT");
+        opts.optopt("", "rust-profile-use", "rustc error format", "FORMAT");
 
         // We can't use getopt to parse the options until we have completed specifying which
         // options are valid, but under the current implementation, some options are conditional on
@@ -674,6 +679,8 @@ Arguments:
             color: matches
                 .opt_get_default("color", Color::Auto)
                 .expect("`color` should be `always`, `never`, or `auto`"),
+            rust_profile_use: matches.opt_str("rust-profile-use"),
+            rust_profile_generate: matches.opt_str("rust-profile-generate"),
         }
     }
 }
diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs
index 074f5cd73f3..96164947943 100644
--- a/src/bootstrap/install.rs
+++ b/src/bootstrap/install.rs
@@ -10,60 +10,19 @@ use std::process::Command;
 
 use build_helper::t;
 
-use crate::dist::{self, pkgname, sanitize_sh, tmpdir};
+use crate::dist::{self, sanitize_sh};
+use crate::tarball::GeneratedTarball;
 use crate::Compiler;
 
 use crate::builder::{Builder, RunConfig, ShouldRun, Step};
 use crate::config::{Config, TargetSelection};
 
-pub fn install_docs(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
-    install_sh(builder, "docs", "rust-docs", stage, Some(host));
-}
-
-pub fn install_std(builder: &Builder<'_>, stage: u32, target: TargetSelection) {
-    install_sh(builder, "std", "rust-std", stage, Some(target));
-}
-
-pub fn install_cargo(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
-    install_sh(builder, "cargo", "cargo", stage, Some(host));
-}
-
-pub fn install_rls(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
-    install_sh(builder, "rls", "rls", stage, Some(host));
-}
-
-pub fn install_rust_analyzer(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
-    install_sh(builder, "rust-analyzer", "rust-analyzer", stage, Some(host));
-}
-
-pub fn install_clippy(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
-    install_sh(builder, "clippy", "clippy", stage, Some(host));
-}
-pub fn install_miri(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
-    install_sh(builder, "miri", "miri", stage, Some(host));
-}
-
-pub fn install_rustfmt(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
-    install_sh(builder, "rustfmt", "rustfmt", stage, Some(host));
-}
-
-pub fn install_analysis(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
-    install_sh(builder, "analysis", "rust-analysis", stage, Some(host));
-}
-
-pub fn install_src(builder: &Builder<'_>, stage: u32) {
-    install_sh(builder, "src", "rust-src", stage, None);
-}
-pub fn install_rustc(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
-    install_sh(builder, "rustc", "rustc", stage, Some(host));
-}
-
 fn install_sh(
     builder: &Builder<'_>,
     package: &str,
-    name: &str,
     stage: u32,
     host: Option<TargetSelection>,
+    tarball: &GeneratedTarball,
 ) {
     builder.info(&format!("Install {} stage{} ({:?})", package, stage, host));
 
@@ -73,12 +32,7 @@ fn install_sh(
     let docdir_default = datadir_default.join("doc/rust");
     let libdir_default = PathBuf::from("lib");
     let mandir_default = datadir_default.join("man");
-    let prefix = builder.config.prefix.as_ref().map_or(prefix_default, |p| {
-        fs::create_dir_all(p)
-            .unwrap_or_else(|err| panic!("could not create {}: {}", p.display(), err));
-        fs::canonicalize(p)
-            .unwrap_or_else(|err| panic!("could not canonicalize {}: {}", p.display(), err))
-    });
+    let prefix = builder.config.prefix.as_ref().unwrap_or(&prefix_default);
     let sysconfdir = builder.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default);
     let datadir = builder.config.datadir.as_ref().unwrap_or(&datadir_default);
     let docdir = builder.config.docdir.as_ref().unwrap_or(&docdir_default);
@@ -103,18 +57,20 @@ fn install_sh(
     let libdir = add_destdir(&libdir, &destdir);
     let mandir = add_destdir(&mandir, &destdir);
 
+    let prefix = {
+        fs::create_dir_all(&prefix)
+            .unwrap_or_else(|err| panic!("could not create {}: {}", prefix.display(), err));
+        fs::canonicalize(&prefix)
+            .unwrap_or_else(|err| panic!("could not canonicalize {}: {}", prefix.display(), err))
+    };
+
     let empty_dir = builder.out.join("tmp/empty_dir");
 
     t!(fs::create_dir_all(&empty_dir));
-    let package_name = if let Some(host) = host {
-        format!("{}-{}", pkgname(builder, name), host.triple)
-    } else {
-        pkgname(builder, name)
-    };
 
     let mut cmd = Command::new("sh");
     cmd.current_dir(&empty_dir)
-        .arg(sanitize_sh(&tmpdir(builder).join(&package_name).join("install.sh")))
+        .arg(sanitize_sh(&tarball.decompressed_output().join("install.sh")))
         .arg(format!("--prefix={}", sanitize_sh(&prefix)))
         .arg(format!("--sysconfdir={}", sanitize_sh(&sysconfdir)))
         .arg(format!("--datadir={}", sanitize_sh(&datadir)))
@@ -189,25 +145,25 @@ macro_rules! install {
 
 install!((self, builder, _config),
     Docs, "src/doc", _config.docs, only_hosts: false, {
-        builder.ensure(dist::Docs { host: self.target });
-        install_docs(builder, self.compiler.stage, self.target);
+        let tarball = builder.ensure(dist::Docs { host: self.target }).expect("missing docs");
+        install_sh(builder, "docs", self.compiler.stage, Some(self.target), &tarball);
     };
     Std, "library/std", true, only_hosts: false, {
         for target in &builder.targets {
-            builder.ensure(dist::Std {
+            let tarball = builder.ensure(dist::Std {
                 compiler: self.compiler,
                 target: *target
-            });
-            install_std(builder, self.compiler.stage, *target);
+            }).expect("missing std");
+            install_sh(builder, "std", self.compiler.stage, Some(*target), &tarball);
         }
     };
     Cargo, "cargo", Self::should_build(_config), only_hosts: true, {
-        builder.ensure(dist::Cargo { compiler: self.compiler, target: self.target });
-        install_cargo(builder, self.compiler.stage, self.target);
+        let tarball = builder.ensure(dist::Cargo { compiler: self.compiler, target: self.target });
+        install_sh(builder, "cargo", self.compiler.stage, Some(self.target), &tarball);
     };
     Rls, "rls", Self::should_build(_config), only_hosts: true, {
-        if builder.ensure(dist::Rls { compiler: self.compiler, target: self.target }).is_some() {
-            install_rls(builder, self.compiler.stage, self.target);
+        if let Some(tarball) = builder.ensure(dist::Rls { compiler: self.compiler, target: self.target }) {
+            install_sh(builder, "rls", self.compiler.stage, Some(self.target), &tarball);
         } else {
             builder.info(
                 &format!("skipping Install RLS stage{} ({})", self.compiler.stage, self.target),
@@ -215,16 +171,18 @@ install!((self, builder, _config),
         }
     };
     RustAnalyzer, "rust-analyzer", Self::should_build(_config), only_hosts: true, {
-        builder.ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target });
-        install_rust_analyzer(builder, self.compiler.stage, self.target);
+        let tarball = builder
+            .ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target })
+            .expect("missing rust-analyzer");
+        install_sh(builder, "rust-analyzer", self.compiler.stage, Some(self.target), &tarball);
     };
     Clippy, "clippy", Self::should_build(_config), only_hosts: true, {
-        builder.ensure(dist::Clippy { compiler: self.compiler, target: self.target });
-        install_clippy(builder, self.compiler.stage, self.target);
+        let tarball = builder.ensure(dist::Clippy { compiler: self.compiler, target: self.target });
+        install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball);
     };
     Miri, "miri", Self::should_build(_config), only_hosts: true, {
-        if builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }).is_some() {
-            install_miri(builder, self.compiler.stage, self.target);
+        if let Some(tarball) = builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }) {
+            install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball);
         } else {
             builder.info(
                 &format!("skipping Install miri stage{} ({})", self.compiler.stage, self.target),
@@ -232,11 +190,11 @@ install!((self, builder, _config),
         }
     };
     Rustfmt, "rustfmt", Self::should_build(_config), only_hosts: true, {
-        if builder.ensure(dist::Rustfmt {
+        if let Some(tarball) = builder.ensure(dist::Rustfmt {
             compiler: self.compiler,
             target: self.target
-        }).is_some() {
-            install_rustfmt(builder, self.compiler.stage, self.target);
+        }) {
+            install_sh(builder, "rustfmt", self.compiler.stage, Some(self.target), &tarball);
         } else {
             builder.info(
                 &format!("skipping Install Rustfmt stage{} ({})", self.compiler.stage, self.target),
@@ -244,20 +202,20 @@ install!((self, builder, _config),
         }
     };
     Analysis, "analysis", Self::should_build(_config), only_hosts: false, {
-        builder.ensure(dist::Analysis {
+        let tarball = builder.ensure(dist::Analysis {
             // Find the actual compiler (handling the full bootstrap option) which
             // produced the save-analysis data because that data isn't copied
             // through the sysroot uplifting.
             compiler: builder.compiler_for(builder.top_stage, builder.config.build, self.target),
             target: self.target
-        });
-        install_analysis(builder, self.compiler.stage, self.target);
+        }).expect("missing analysis");
+        install_sh(builder, "analysis", self.compiler.stage, Some(self.target), &tarball);
     };
     Rustc, "src/librustc", true, only_hosts: true, {
-        builder.ensure(dist::Rustc {
+        let tarball = builder.ensure(dist::Rustc {
             compiler: builder.compiler(builder.top_stage, self.target),
         });
-        install_rustc(builder, self.compiler.stage, self.target);
+        install_sh(builder, "rustc", self.compiler.stage, Some(self.target), &tarball);
     };
 );
 
@@ -282,7 +240,7 @@ impl Step for Src {
     }
 
     fn run(self, builder: &Builder<'_>) {
-        builder.ensure(dist::Src);
-        install_src(builder, self.stage);
+        let tarball = builder.ensure(dist::Src);
+        install_sh(builder, "src", self.stage, None, &tarball);
     }
 }
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 06ccd72186d..a47ddfbcc1f 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -142,6 +142,7 @@ mod native;
 mod run;
 mod sanity;
 mod setup;
+mod tarball;
 mod test;
 mod tool;
 mod toolstate;
@@ -1068,10 +1069,6 @@ impl Build {
         self.package_vers(&self.version)
     }
 
-    fn llvm_tools_vers(&self) -> String {
-        self.rust_version()
-    }
-
     fn llvm_link_tools_dynamically(&self, target: TargetSelection) -> bool {
         target.contains("linux-gnu") || target.contains("apple-darwin")
     }
@@ -1182,27 +1179,6 @@ impl Build {
         paths
     }
 
-    /// Copies a file from `src` to `dst` and doesn't use links, so
-    /// that the copy can be modified without affecting the original.
-    pub fn really_copy(&self, src: &Path, dst: &Path) {
-        if self.config.dry_run {
-            return;
-        }
-        self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst));
-        if src == dst {
-            return;
-        }
-        let _ = fs::remove_file(&dst);
-        let metadata = t!(src.symlink_metadata());
-        if let Err(e) = fs::copy(src, dst) {
-            panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e)
-        }
-        t!(fs::set_permissions(dst, metadata.permissions()));
-        let atime = FileTime::from_last_access_time(&metadata);
-        let mtime = FileTime::from_last_modification_time(&metadata);
-        t!(filetime::set_file_times(dst, atime, mtime));
-    }
-
     /// Copies a file from `src` to `dst`
     pub fn copy(&self, src: &Path, dst: &Path) {
         if self.config.dry_run {
diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index 1564cfb0619..fd39944e176 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -66,7 +66,6 @@ check-stage2-T-x86_64-unknown-linux-musl-H-x86_64-unknown-linux-gnu:
 
 TESTS_IN_2 := \
 	src/test/ui \
-	src/test/compile-fail \
 	src/tools/linkchecker
 
 ci-subset-1:
@@ -75,8 +74,7 @@ ci-subset-2:
 	$(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_2)
 
 TESTS_IN_MINGW_2 := \
-	src/test/ui \
-	src/test/compile-fail
+	src/test/ui
 
 ci-mingw-subset-1:
 	$(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_MINGW_2:%=--exclude %)
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index 4cfcf6ca407..acb941d9540 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -17,6 +17,7 @@ use std::process::Command;
 
 use build_helper::{output, t};
 
+use crate::cache::INTERNER;
 use crate::config::Target;
 use crate::Build;
 
@@ -79,18 +80,19 @@ pub fn check(build: &mut Build) {
     }
 
     // We need cmake, but only if we're actually building LLVM or sanitizers.
-    let building_llvm = build
-        .hosts
-        .iter()
-        .map(|host| {
-            build
-                .config
-                .target_config
-                .get(host)
-                .map(|config| config.llvm_config.is_none())
-                .unwrap_or(true)
-        })
-        .any(|build_llvm_ourselves| build_llvm_ourselves);
+    let building_llvm = build.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm"))
+        && build
+            .hosts
+            .iter()
+            .map(|host| {
+                build
+                    .config
+                    .target_config
+                    .get(host)
+                    .map(|config| config.llvm_config.is_none())
+                    .unwrap_or(true)
+            })
+            .any(|build_llvm_ourselves| build_llvm_ourselves);
     if building_llvm || build.config.any_sanitizers_enabled() {
         cmd_finder.must_have("cmake");
     }
@@ -147,10 +149,12 @@ pub fn check(build: &mut Build) {
         }
     }
 
-    // Externally configured LLVM requires FileCheck to exist
-    let filecheck = build.llvm_filecheck(build.build);
-    if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests {
-        panic!("FileCheck executable {:?} does not exist", filecheck);
+    if build.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) {
+        // Externally configured LLVM requires FileCheck to exist
+        let filecheck = build.llvm_filecheck(build.build);
+        if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests {
+            panic!("FileCheck executable {:?} does not exist", filecheck);
+        }
     }
 
     for target in &build.targets {
@@ -159,11 +163,7 @@ pub fn check(build: &mut Build) {
             panic!("the iOS target is only supported on macOS");
         }
 
-        build
-            .config
-            .target_config
-            .entry(target.clone())
-            .or_insert(Target::from_triple(&target.triple));
+        build.config.target_config.entry(*target).or_insert(Target::from_triple(&target.triple));
 
         if target.contains("-none-") || target.contains("nvptx") {
             if build.no_std(*target) == Some(false) {
@@ -176,7 +176,7 @@ pub fn check(build: &mut Build) {
             // If this is a native target (host is also musl) and no musl-root is given,
             // fall back to the system toolchain in /usr before giving up
             if build.musl_root(*target).is_none() && build.config.build == *target {
-                let target = build.config.target_config.entry(target.clone()).or_default();
+                let target = build.config.target_config.entry(*target).or_default();
                 target.musl_root = Some("/usr".into());
             }
             match build.musl_libdir(*target) {
diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs
new file mode 100644
index 00000000000..7fb03056f1b
--- /dev/null
+++ b/src/bootstrap/tarball.rs
@@ -0,0 +1,333 @@
+use std::{
+    path::{Path, PathBuf},
+    process::Command,
+};
+
+use build_helper::t;
+
+use crate::builder::Builder;
+
+#[derive(Copy, Clone)]
+pub(crate) enum OverlayKind {
+    Rust,
+    LLVM,
+    Cargo,
+    Clippy,
+    Miri,
+    Rustfmt,
+    RLS,
+    RustAnalyzer,
+}
+
+impl OverlayKind {
+    fn legal_and_readme(&self) -> &[&str] {
+        match self {
+            OverlayKind::Rust => &["COPYRIGHT", "LICENSE-APACHE", "LICENSE-MIT", "README.md"],
+            OverlayKind::LLVM => {
+                &["src/llvm-project/llvm/LICENSE.TXT", "src/llvm-project/llvm/README.txt"]
+            }
+            OverlayKind::Cargo => &[
+                "src/tools/cargo/README.md",
+                "src/tools/cargo/LICENSE-MIT",
+                "src/tools/cargo/LICENSE-APACHE",
+                "src/tools/cargo/LICENSE-THIRD-PARTY",
+            ],
+            OverlayKind::Clippy => &[
+                "src/tools/clippy/README.md",
+                "src/tools/clippy/LICENSE-APACHE",
+                "src/tools/clippy/LICENSE-MIT",
+            ],
+            OverlayKind::Miri => &[
+                "src/tools/miri/README.md",
+                "src/tools/miri/LICENSE-APACHE",
+                "src/tools/miri/LICENSE-MIT",
+            ],
+            OverlayKind::Rustfmt => &[
+                "src/tools/rustfmt/README.md",
+                "src/tools/rustfmt/LICENSE-APACHE",
+                "src/tools/rustfmt/LICENSE-MIT",
+            ],
+            OverlayKind::RLS => &[
+                "src/tools/rls/README.md",
+                "src/tools/rls/LICENSE-APACHE",
+                "src/tools/rls/LICENSE-MIT",
+            ],
+            OverlayKind::RustAnalyzer => &[
+                "src/tools/rust-analyzer/README.md",
+                "src/tools/rust-analyzer/LICENSE-APACHE",
+                "src/tools/rust-analyzer/LICENSE-MIT",
+            ],
+        }
+    }
+
+    fn version(&self, builder: &Builder<'_>) -> String {
+        match self {
+            OverlayKind::Rust => builder.rust_version(),
+            OverlayKind::LLVM => builder.rust_version(),
+            OverlayKind::Cargo => {
+                builder.cargo_info.version(builder, &builder.release_num("cargo"))
+            }
+            OverlayKind::Clippy => {
+                builder.clippy_info.version(builder, &builder.release_num("clippy"))
+            }
+            OverlayKind::Miri => builder.miri_info.version(builder, &builder.release_num("miri")),
+            OverlayKind::Rustfmt => {
+                builder.rustfmt_info.version(builder, &builder.release_num("rustfmt"))
+            }
+            OverlayKind::RLS => builder.rls_info.version(builder, &builder.release_num("rls")),
+            OverlayKind::RustAnalyzer => builder
+                .rust_analyzer_info
+                .version(builder, &builder.release_num("rust-analyzer/crates/rust-analyzer")),
+        }
+    }
+}
+
+pub(crate) struct Tarball<'a> {
+    builder: &'a Builder<'a>,
+
+    pkgname: String,
+    component: String,
+    target: Option<String>,
+    product_name: String,
+    overlay: OverlayKind,
+
+    temp_dir: PathBuf,
+    image_dir: PathBuf,
+    overlay_dir: PathBuf,
+
+    include_target_in_component_name: bool,
+    is_preview: bool,
+}
+
+impl<'a> Tarball<'a> {
+    pub(crate) fn new(builder: &'a Builder<'a>, component: &str, target: &str) -> Self {
+        Self::new_inner(builder, component, Some(target.into()))
+    }
+
+    pub(crate) fn new_targetless(builder: &'a Builder<'a>, component: &str) -> Self {
+        Self::new_inner(builder, component, None)
+    }
+
+    fn new_inner(builder: &'a Builder<'a>, component: &str, target: Option<String>) -> Self {
+        let pkgname = crate::dist::pkgname(builder, component);
+
+        let mut temp_dir = builder.out.join("tmp").join("tarball").join(component);
+        if let Some(target) = &target {
+            temp_dir = temp_dir.join(target);
+        }
+        let _ = std::fs::remove_dir_all(&temp_dir);
+
+        let image_dir = temp_dir.join("image");
+        let overlay_dir = temp_dir.join("overlay");
+
+        Self {
+            builder,
+
+            pkgname,
+            component: component.into(),
+            target,
+            product_name: "Rust".into(),
+            overlay: OverlayKind::Rust,
+
+            temp_dir,
+            image_dir,
+            overlay_dir,
+
+            include_target_in_component_name: false,
+            is_preview: false,
+        }
+    }
+
+    pub(crate) fn set_overlay(&mut self, overlay: OverlayKind) {
+        self.overlay = overlay;
+    }
+
+    pub(crate) fn set_product_name(&mut self, name: &str) {
+        self.product_name = name.into();
+    }
+
+    pub(crate) fn include_target_in_component_name(&mut self, include: bool) {
+        self.include_target_in_component_name = include;
+    }
+
+    pub(crate) fn is_preview(&mut self, is: bool) {
+        self.is_preview = is;
+    }
+
+    pub(crate) fn image_dir(&self) -> &Path {
+        t!(std::fs::create_dir_all(&self.image_dir));
+        &self.image_dir
+    }
+
+    pub(crate) fn add_file(&self, src: impl AsRef<Path>, destdir: impl AsRef<Path>, perms: u32) {
+        // create_dir_all fails to create `foo/bar/.`, so when the destination is "." this simply
+        // uses the base directory as the destination directory.
+        let destdir = if destdir.as_ref() == Path::new(".") {
+            self.image_dir.clone()
+        } else {
+            self.image_dir.join(destdir.as_ref())
+        };
+
+        t!(std::fs::create_dir_all(&destdir));
+        self.builder.install(src.as_ref(), &destdir, perms);
+    }
+
+    pub(crate) fn add_renamed_file(
+        &self,
+        src: impl AsRef<Path>,
+        destdir: impl AsRef<Path>,
+        new_name: &str,
+    ) {
+        let destdir = self.image_dir.join(destdir.as_ref());
+        t!(std::fs::create_dir_all(&destdir));
+        self.builder.copy(src.as_ref(), &destdir.join(new_name));
+    }
+
+    pub(crate) fn add_legal_and_readme_to(&self, destdir: impl AsRef<Path>) {
+        for file in self.overlay.legal_and_readme() {
+            self.add_file(self.builder.src.join(file), destdir.as_ref(), 0o644);
+        }
+    }
+
+    pub(crate) fn add_dir(&self, src: impl AsRef<Path>, dest: impl AsRef<Path>) {
+        let dest = self.image_dir.join(dest.as_ref());
+
+        t!(std::fs::create_dir_all(&dest));
+        self.builder.cp_r(src.as_ref(), &dest);
+    }
+
+    pub(crate) fn generate(self) -> GeneratedTarball {
+        let mut component_name = self.component.clone();
+        if self.is_preview {
+            component_name.push_str("-preview");
+        }
+        if self.include_target_in_component_name {
+            component_name.push('-');
+            component_name.push_str(
+                &self
+                    .target
+                    .as_ref()
+                    .expect("include_target_in_component_name used in a targetless tarball"),
+            );
+        }
+
+        self.run(|this, cmd| {
+            cmd.arg("generate")
+                .arg("--image-dir")
+                .arg(&this.image_dir)
+                .arg(format!("--component-name={}", &component_name));
+            this.non_bare_args(cmd);
+        })
+    }
+
+    pub(crate) fn combine(self, tarballs: &[GeneratedTarball]) -> GeneratedTarball {
+        let mut input_tarballs = tarballs[0].path.as_os_str().to_os_string();
+        for tarball in &tarballs[1..] {
+            input_tarballs.push(",");
+            input_tarballs.push(&tarball.path);
+        }
+
+        self.run(|this, cmd| {
+            cmd.arg("combine").arg("--input-tarballs").arg(input_tarballs);
+            this.non_bare_args(cmd);
+        })
+    }
+
+    pub(crate) fn bare(self) -> GeneratedTarball {
+        // Bare tarballs should have the top level directory match the package
+        // name, not "image". We rename the image directory just before passing
+        // into rust-installer.
+        let dest = self.temp_dir.join(self.package_name());
+        t!(std::fs::rename(&self.image_dir, &dest));
+
+        self.run(|this, cmd| {
+            cmd.arg("tarball")
+                .arg("--input")
+                .arg(&dest)
+                .arg("--output")
+                .arg(crate::dist::distdir(this.builder).join(this.package_name()));
+        })
+    }
+
+    fn package_name(&self) -> String {
+        if let Some(target) = &self.target {
+            format!("{}-{}", self.pkgname, target)
+        } else {
+            self.pkgname.clone()
+        }
+    }
+
+    fn non_bare_args(&self, cmd: &mut Command) {
+        cmd.arg("--rel-manifest-dir=rustlib")
+            .arg("--legacy-manifest-dirs=rustlib,cargo")
+            .arg(format!("--product-name={}", self.product_name))
+            .arg(format!("--success-message={} installed.", self.component))
+            .arg(format!("--package-name={}", self.package_name()))
+            .arg("--non-installed-overlay")
+            .arg(&self.overlay_dir)
+            .arg("--output-dir")
+            .arg(crate::dist::distdir(self.builder));
+    }
+
+    fn run(self, build_cli: impl FnOnce(&Tarball<'a>, &mut Command)) -> GeneratedTarball {
+        t!(std::fs::create_dir_all(&self.overlay_dir));
+        self.builder.create(&self.overlay_dir.join("version"), &self.overlay.version(self.builder));
+        if let Some(sha) = self.builder.rust_sha() {
+            self.builder.create(&self.overlay_dir.join("git-commit-hash"), &sha);
+        }
+        for file in self.overlay.legal_and_readme() {
+            self.builder.install(&self.builder.src.join(file), &self.overlay_dir, 0o644);
+        }
+
+        let mut cmd = self.builder.tool_cmd(crate::tool::Tool::RustInstaller);
+
+        let package_name = self.package_name();
+        self.builder.info(&format!("Dist {}", package_name));
+        let _time = crate::util::timeit(self.builder);
+
+        build_cli(&self, &mut cmd);
+        cmd.arg("--work-dir").arg(&self.temp_dir);
+        if let Some(formats) = &self.builder.config.dist_compression_formats {
+            assert!(!formats.is_empty(), "dist.compression-formats can't be empty");
+            cmd.arg("--compression-formats").arg(formats.join(","));
+        }
+        self.builder.run(&mut cmd);
+
+        // Use either the first compression format defined, or "gz" as the default.
+        let ext = self
+            .builder
+            .config
+            .dist_compression_formats
+            .as_ref()
+            .and_then(|formats| formats.get(0))
+            .map(|s| s.as_str())
+            .unwrap_or("gz");
+
+        GeneratedTarball {
+            path: crate::dist::distdir(self.builder).join(format!("{}.tar.{}", package_name, ext)),
+            decompressed_output: self.temp_dir.join(package_name),
+            work: self.temp_dir,
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct GeneratedTarball {
+    path: PathBuf,
+    decompressed_output: PathBuf,
+    work: PathBuf,
+}
+
+impl GeneratedTarball {
+    pub(crate) fn tarball(&self) -> &Path {
+        &self.path
+    }
+
+    pub(crate) fn decompressed_output(&self) -> &Path {
+        &self.decompressed_output
+    }
+
+    pub(crate) fn work_dir(&self) -> &Path {
+        &self.work
+    }
+}
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 78b5de7897d..33e252a63c9 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -869,12 +869,6 @@ default_test_with_compare_mode!(Ui {
     compare_mode: "nll"
 });
 
-default_test!(CompileFail {
-    path: "src/test/compile-fail",
-    mode: "compile-fail",
-    suite: "compile-fail"
-});
-
 default_test!(RunPassValgrind {
     path: "src/test/run-pass-valgrind",
     mode: "run-pass-valgrind",
@@ -897,7 +891,12 @@ default_test!(Incremental {
     suite: "incremental"
 });
 
-default_test!(Debuginfo { path: "src/test/debuginfo", mode: "debuginfo", suite: "debuginfo" });
+default_test_with_compare_mode!(Debuginfo {
+    path: "src/test/debuginfo",
+    mode: "debuginfo",
+    suite: "debuginfo",
+    compare_mode: "split-dwarf"
+});
 
 host_test!(UiFullDeps { path: "src/test/ui-fulldeps", mode: "ui", suite: "ui-fulldeps" });
 
@@ -1963,8 +1962,8 @@ impl Step for Distcheck {
         builder.ensure(dist::Src);
 
         let mut cmd = Command::new("tar");
-        cmd.arg("-xzf")
-            .arg(builder.ensure(dist::PlainSourceTarball))
+        cmd.arg("-xf")
+            .arg(builder.ensure(dist::PlainSourceTarball).tarball())
             .arg("--strip-components=1")
             .current_dir(&dir);
         builder.run(&mut cmd);
@@ -1987,8 +1986,8 @@ impl Step for Distcheck {
         t!(fs::create_dir_all(&dir));
 
         let mut cmd = Command::new("tar");
-        cmd.arg("-xzf")
-            .arg(builder.ensure(dist::Src))
+        cmd.arg("-xf")
+            .arg(builder.ensure(dist::Src).tarball())
             .arg("--strip-components=1")
             .current_dir(&dir);
         builder.run(&mut cmd);
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 290e3744852..dc786249d99 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -563,7 +563,7 @@ impl Step for Cargo {
     }
 
     fn run(self, builder: &Builder<'_>) -> PathBuf {
-        builder
+        let cargo_bin_path = builder
             .ensure(ToolBuild {
                 compiler: self.compiler,
                 target: self.target,
@@ -574,7 +574,40 @@ impl Step for Cargo {
                 source_type: SourceType::Submodule,
                 extra_features: Vec::new(),
             })
-            .expect("expected to build -- essential tool")
+            .expect("expected to build -- essential tool");
+
+        let build_cred = |name, path| {
+            // These credential helpers are currently experimental.
+            // Any build failures will be ignored.
+            let _ = builder.ensure(ToolBuild {
+                compiler: self.compiler,
+                target: self.target,
+                tool: name,
+                mode: Mode::ToolRustc,
+                path,
+                is_optional_tool: true,
+                source_type: SourceType::Submodule,
+                extra_features: Vec::new(),
+            });
+        };
+
+        if self.target.contains("windows") {
+            build_cred(
+                "cargo-credential-wincred",
+                "src/tools/cargo/crates/credential/cargo-credential-wincred",
+            );
+        }
+        if self.target.contains("apple-darwin") {
+            build_cred(
+                "cargo-credential-macos-keychain",
+                "src/tools/cargo/crates/credential/cargo-credential-macos-keychain",
+            );
+        }
+        build_cred(
+            "cargo-credential-1password",
+            "src/tools/cargo/crates/credential/cargo-credential-1password",
+        );
+        cargo_bin_path
     }
 }
 
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index 14700aeea05..d1b4bbf7fff 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -85,6 +85,8 @@ ENV CC=clang CXX=clang++
 COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
+ENV PGO_HOST=x86_64-unknown-linux-gnu
+
 ENV HOSTS=x86_64-unknown-linux-gnu
 
 ENV RUST_CONFIGURE_ARGS \
@@ -98,9 +100,10 @@ ENV RUST_CONFIGURE_ARGS \
       --set llvm.thin-lto=true \
       --set llvm.ninja=false \
       --set rust.jemalloc
-ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS \
-        --include-default-paths \
-        src/tools/build-manifest
+ENV SCRIPT ../src/ci/pgo.sh python2.7 ../x.py dist \
+    --host $HOSTS --target $HOSTS \
+    --include-default-paths \
+    src/tools/build-manifest
 ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang
 
 # This is the only builder which will create source tarballs
diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile
index 8653aecc12c..147de5f8015 100644
--- a/src/ci/docker/host-x86_64/test-various/Dockerfile
+++ b/src/ci/docker/host-x86_64/test-various/Dockerfile
@@ -44,7 +44,6 @@ ENV WASM_TARGETS=wasm32-unknown-unknown
 ENV WASM_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $WASM_TARGETS \
   src/test/run-make \
   src/test/ui \
-  src/test/compile-fail \
   src/test/mir-opt \
   src/test/codegen-units \
   library/core
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile
index f4071961f8e..77510d7ac62 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile
@@ -1,6 +1,7 @@
-FROM ubuntu:16.04
+FROM ubuntu:20.04
 
-RUN apt-get update && apt-get install -y --no-install-recommends \
+# Avoid interactive prompts while installing `tzdata` dependency with `DEBIAN_FRONTEND`.
+RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
   g++ \
   make \
   ninja-build \
diff --git a/src/ci/pgo.sh b/src/ci/pgo.sh
new file mode 100755
index 00000000000..13b8ca91f89
--- /dev/null
+++ b/src/ci/pgo.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+set -euxo pipefail
+
+rm -rf /tmp/rustc-pgo
+
+python2.7 ../x.py build --target=$PGO_HOST --host=$PGO_HOST \
+    --stage 2 library/std --rust-profile-generate=/tmp/rustc-pgo
+
+./build/$PGO_HOST/stage2/bin/rustc --edition=2018 \
+    --crate-type=lib ../library/core/src/lib.rs
+
+# Download and build a single-file stress test benchmark on perf.rust-lang.org.
+function pgo_perf_benchmark {
+    local PERF=e095f5021bf01cf3800f50b3a9f14a9683eb3e4e
+    local github_prefix=https://raw.githubusercontent.com/rust-lang/rustc-perf/$PERF
+    local name=$1
+    curl -o /tmp/$name.rs $github_prefix/collector/benchmarks/$name/src/lib.rs
+    ./build/$PGO_HOST/stage2/bin/rustc --edition=2018 --crate-type=lib /tmp/$name.rs
+}
+
+pgo_perf_benchmark externs
+pgo_perf_benchmark ctfe-stress-4
+
+cp -pri ../src/tools/cargo /tmp/cargo
+
+# Build cargo (with some flags)
+function pgo_cargo {
+    RUSTC=./build/$PGO_HOST/stage2/bin/rustc \
+        ./build/$PGO_HOST/stage0/bin/cargo $@ \
+        --manifest-path /tmp/cargo/Cargo.toml
+}
+
+# Build a couple different variants of Cargo
+CARGO_INCREMENTAL=1 pgo_cargo check
+echo 'pub fn barbarbar() {}' >> /tmp/cargo/src/cargo/lib.rs
+CARGO_INCREMENTAL=1 pgo_cargo check
+touch /tmp/cargo/src/cargo/lib.rs
+CARGO_INCREMENTAL=1 pgo_cargo check
+pgo_cargo build --release
+
+# Merge the profile data we gathered
+./build/$PGO_HOST/llvm/bin/llvm-profdata \
+    merge -o /tmp/rustc-pgo.profdata /tmp/rustc-pgo
+
+# This produces the actual final set of artifacts.
+$@ --rust-profile-use=/tmp/rustc-pgo.profdata
diff --git a/src/ci/run.sh b/src/ci/run.sh
index 181a7fcb732..1958b6ee41d 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -53,6 +53,11 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-locked-deps"
 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-cargo-native-static"
 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-units-std=1"
 
+# Only produce xz tarballs on CI. gz tarballs will be generated by the release
+# process by recompressing the existing xz ones. This decreases the storage
+# space required for CI artifacts.
+RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --dist-compression-formats=xz"
+
 if [ "$DIST_SRC" = "" ]; then
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src"
 fi
diff --git a/src/doc/book b/src/doc/book
-Subproject a190438d77d28041f24da4f6592e287fab073a6
+Subproject 5bb44f8b5b0aa105c8b22602e9b18800484afa2
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject d8383b65f7948c2ca19191b3b4bd709b403aaf4
+Subproject a5a48441d411f61556b57d762b03d6874afe575
diff --git a/src/doc/reference b/src/doc/reference
-Subproject a8afdca5d0715b2257b6f8b9a032fd4dd7dae85
+Subproject b278478b766178491a8b6f67afa4bcd6b64d977
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 236c734a2cb323541b3394f98682cb981b9ec08
+Subproject 1cce0737d6a7d3ceafb139b4a206861fb1dcb2a
diff --git a/src/doc/rustc/book.toml b/src/doc/rustc/book.toml
index 8adc05c5137..21d127c39c9 100644
--- a/src/doc/rustc/book.toml
+++ b/src/doc/rustc/book.toml
@@ -3,3 +3,6 @@ authors = ["The Rust Project Developers"]
 multilingual = false
 src = "src"
 title = "The rustc book"
+
+[output.html]
+git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/rustc"
diff --git a/src/doc/rustdoc/book.toml b/src/doc/rustdoc/book.toml
index ba30c107667..c2e7ff58906 100644
--- a/src/doc/rustdoc/book.toml
+++ b/src/doc/rustdoc/book.toml
@@ -2,3 +2,6 @@
 authors = ["The Rust Project Developers"]
 src = "src"
 title = "The rustdoc book"
+
+[output.html]
+git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/rustdoc"
diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md
index 31e002810ce..80f7851debf 100644
--- a/src/doc/rustdoc/src/command-line-arguments.md
+++ b/src/doc/rustdoc/src/command-line-arguments.md
@@ -237,6 +237,26 @@ for a target triple that's different than your host triple.
 
 All of the usual caveats of cross-compiling code apply.
 
+## `--default-theme`: set the default theme
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs --default-theme=ayu
+```
+
+Sets the default theme (for users whose browser has not remembered a
+previous theme selection from the on-page theme picker).
+
+The supplied value should be the lowercase version of the theme name.
+The set of available themes can be seen in the theme picker in the
+generated output.
+
+Note that the set of available themes - and their appearance - is not
+necessarily stable from one rustdoc version to the next.  If the
+requested theme does not exist, the builtin default (currently
+`light`) is used instead.
+
 ## `--markdown-css`: include more CSS files when rendering markdown
 
 Using this flag looks like this:
diff --git a/src/doc/rustdoc/src/what-is-rustdoc.md b/src/doc/rustdoc/src/what-is-rustdoc.md
index 1f6dced180b..32dc1e02bb3 100644
--- a/src/doc/rustdoc/src/what-is-rustdoc.md
+++ b/src/doc/rustdoc/src/what-is-rustdoc.md
@@ -10,7 +10,7 @@ CSS, and JavaScript.
 Let's give it a try! Create a new project with Cargo:
 
 ```bash
-$ cargo new docs
+$ cargo new docs --lib
 $ cd docs
 ```
 
diff --git a/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md b/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md
index 6ca5ae40707..98bcadd12ee 100644
--- a/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md
+++ b/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md
@@ -118,7 +118,7 @@ LLVM's supplies two tools—`llvm-profdata` and `llvm-cov`—that process covera
 * If you are building the Rust compiler from source, you can optionally use the bundled LLVM tools, built from source. Those tool binaries can typically be found in your build platform directory at something like: `rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-*`.
 * You can install compatible versions of these tools via `rustup`.
 
-The `rustup` option is guaranteed to install a compatible version of the LLVM tools, but they can be hard to find. We recommend [`cargo-bintools`], which installs Rust-specific wrappers around these and other LLVM tools, so you can invoke them via `cargo` commands!
+The `rustup` option is guaranteed to install a compatible version of the LLVM tools, but they can be hard to find. We recommend [`cargo-binutils`], which installs Rust-specific wrappers around these and other LLVM tools, so you can invoke them via `cargo` commands!
 
 ```shell
 $ rustup component add llvm-tools-preview
@@ -320,8 +320,8 @@ Rust's implementation and workflow for source-based code coverage is based on th
 [rustc-dev-guide-how-to-build-and-run]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html
 [`rustfilt`]: https://crates.io/crates/rustfilt
 [`json5format`]: https://crates.io/crates/json5format
-[`cargo-bintools`]: https://crates.io/crates/cargo-bintools
+[`cargo-binutils`]: https://crates.io/crates/cargo-binutils
 [`llvm-profdata merge`]: https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge
 [`llvm-cov report`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report
 [`llvm-cov show`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show
-[source-based code coverage in Clang]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
\ No newline at end of file
+[source-based code coverage in Clang]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
diff --git a/src/doc/unstable-book/src/language-features/const-fn.md b/src/doc/unstable-book/src/language-features/const-fn.md
index 50dbbaf5674..bcf7f78b8fe 100644
--- a/src/doc/unstable-book/src/language-features/const-fn.md
+++ b/src/doc/unstable-book/src/language-features/const-fn.md
@@ -6,24 +6,5 @@ The tracking issue for this feature is: [#57563]
 
 ------------------------
 
-The `const_fn` feature allows marking free functions and inherent methods as
-`const`, enabling them to be called in constants contexts, with constant
-arguments.
-
-## Examples
-
-```rust
-#![feature(const_fn)]
-
-const fn double(x: i32) -> i32 {
-    x * 2
-}
-
-const FIVE: i32 = 5;
-const TEN: i32 = double(FIVE);
-
-fn main() {
-    assert_eq!(5, FIVE);
-    assert_eq!(10, TEN);
-}
-```
+The `const_fn` feature enables additional functionality not stabilized in the
+[minimal subset of `const_fn`](https://github.com/rust-lang/rust/issues/53555)
diff --git a/src/doc/unstable-book/src/language-features/ffi-pure.md b/src/doc/unstable-book/src/language-features/ffi-pure.md
index 4aef4eeab55..236ccb9f905 100644
--- a/src/doc/unstable-book/src/language-features/ffi-pure.md
+++ b/src/doc/unstable-book/src/language-features/ffi-pure.md
@@ -31,7 +31,7 @@ parameters (e.g. pointers), globals, etc. `#[ffi_pure]` functions are not
 referentially-transparent, and are therefore more relaxed than `#[ffi_const]`
 functions.
 
-However, accesing global memory through volatile or atomic reads can violate the
+However, accessing global memory through volatile or atomic reads can violate the
 requirement that two consecutive function calls shall return the same value.
 
 A `pure` function that returns unit has no effect on the abstract machine's
diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py
index a0ba47e1dbe..d38f5add747 100755
--- a/src/etc/generate-deriving-span-tests.py
+++ b/src/etc/generate-deriving-span-tests.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 """
-This script creates a pile of compile-fail tests check that all the
+This script creates a pile of UI tests check that all the
 derives have spans that point to the fields, rather than the
 #[derive(...)] line.
 
diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis
index 874550da8b0..030892a432b 100644
--- a/src/etc/natvis/intrinsic.natvis
+++ b/src/etc/natvis/intrinsic.natvis
@@ -4,17 +4,21 @@
     <DisplayString>{data_ptr,[length]s8}</DisplayString>
     <StringView>data_ptr,[length]s8</StringView>
     <Expand>
-      <Item Name="[size]" ExcludeView="simple">length</Item>
-      <ArrayItems>
-        <Size>length</Size>
-        <ValuePointer>data_ptr</ValuePointer>
-      </ArrayItems>
+      <Item Name="[len]" ExcludeView="simple">length</Item>
+      <Synthetic Name="[chars]">
+        <Expand>
+          <ArrayItems>
+            <Size>length</Size>
+            <ValuePointer>data_ptr</ValuePointer>
+          </ArrayItems>
+        </Expand>
+      </Synthetic>
     </Expand>
   </Type>
   <Type Name="slice&lt;*&gt;">
-    <DisplayString>{{ length={length} }}</DisplayString>
+    <DisplayString>{{ len={length} }}</DisplayString>
     <Expand>
-      <Item Name="[size]" ExcludeView="simple">length</Item>
+      <Item Name="[len]" ExcludeView="simple">length</Item>
       <ArrayItems>
         <Size>length</Size>
         <ValuePointer>data_ptr</ValuePointer>
diff --git a/src/etc/natvis/liballoc.natvis b/src/etc/natvis/liballoc.natvis
index de30b58526a..cfaafc5734b 100644
--- a/src/etc/natvis/liballoc.natvis
+++ b/src/etc/natvis/liballoc.natvis
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
   <Type Name="alloc::vec::Vec&lt;*&gt;">
-    <DisplayString>{{ size={len} }}</DisplayString>
+    <DisplayString>{{ len={len} }}</DisplayString>
     <Expand>
-      <Item Name="[size]" ExcludeView="simple">len</Item>
+      <Item Name="[len]" ExcludeView="simple">len</Item>
       <Item Name="[capacity]" ExcludeView="simple">buf.cap</Item>
       <ArrayItems>
         <Size>len</Size>
@@ -12,9 +12,9 @@
     </Expand>
   </Type>
   <Type Name="alloc::collections::vec_deque::VecDeque&lt;*&gt;">
-    <DisplayString>{{ size={tail &lt;= head ? head - tail : buf.cap - tail + head} }}</DisplayString>
+    <DisplayString>{{ len={tail &lt;= head ? head - tail : buf.cap - tail + head} }}</DisplayString>
     <Expand>
-      <Item Name="[size]" ExcludeView="simple">tail &lt;= head ? head - tail : buf.cap - tail + head</Item>
+      <Item Name="[len]" ExcludeView="simple">tail &lt;= head ? head - tail : buf.cap - tail + head</Item>
       <Item Name="[capacity]" ExcludeView="simple">buf.cap</Item>
       <CustomListItems>
         <Variable Name="i" InitialValue="tail" />
@@ -31,7 +31,7 @@
     </Expand>
   </Type>
   <Type Name="alloc::collections::linked_list::LinkedList&lt;*&gt;">
-    <DisplayString>{{ size={len} }}</DisplayString>
+    <DisplayString>{{ len={len} }}</DisplayString>
     <Expand>
       <LinkedListItems>
         <Size>len</Size>
@@ -42,15 +42,37 @@
     </Expand>
   </Type>
   <Type Name="alloc::string::String">
-    <DisplayString>{*(char**)this,[vec.len]s8}</DisplayString>
-    <StringView>*(char**)this,[vec.len]s8</StringView>
+    <DisplayString>{(char*)vec.buf.ptr.pointer,[vec.len]s8}</DisplayString>
+    <StringView>(char*)vec.buf.ptr.pointer,[vec.len]s8</StringView>
     <Expand>
-      <Item Name="[size]" ExcludeView="simple">vec.len</Item>
+      <Item Name="[len]" ExcludeView="simple">vec.len</Item>
       <Item Name="[capacity]" ExcludeView="simple">vec.buf.cap</Item>
-      <ArrayItems>
-        <Size>vec.len</Size>
-        <ValuePointer>*(char**)this</ValuePointer>
-      </ArrayItems>
+      <Synthetic Name="[chars]">
+        <Expand>
+          <ArrayItems>
+            <Size>vec.len</Size>
+            <ValuePointer>(char*)vec.buf.ptr.pointer</ValuePointer>
+          </ArrayItems>
+        </Expand>
+      </Synthetic>
+    </Expand>
+  </Type>
+  <Type Name="alloc::rc::Rc&lt;*&gt;">
+    <DisplayString>{ptr.pointer->value}</DisplayString>
+    <Expand>
+      <ExpandedItem>ptr.pointer->value</ExpandedItem>
+    </Expand>
+  </Type>
+  <Type Name="alloc::sync::Arc&lt;*&gt;">
+    <DisplayString>{ptr.pointer->data}</DisplayString>
+    <Expand>
+      <ExpandedItem>ptr.pointer->data</ExpandedItem>
+    </Expand>
+  </Type>
+  <Type Name="alloc::sync::Weak&lt;*&gt;">
+    <DisplayString>{ptr.pointer->data}</DisplayString>
+    <Expand>
+      <ExpandedItem>ptr.pointer->data</ExpandedItem>
     </Expand>
   </Type>
 </AutoVisualizer>
diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis
index 0e703b3b950..984a8bfb13c 100644
--- a/src/etc/natvis/libcore.natvis
+++ b/src/etc/natvis/libcore.natvis
@@ -6,34 +6,28 @@
       <Item Name="[ptr]">pointer</Item>
     </Expand>
   </Type>
+
   <Type Name="core::ptr::Shared&lt;*&gt;">
     <DisplayString>{{ Shared {pointer} }}</DisplayString>
     <Expand>
       <Item Name="[ptr]">pointer</Item>
     </Expand>
   </Type>
+
   <Type Name="core::option::Option&lt;*&gt;">
-    <DisplayString Condition="RUST$ENUM$DISR == 0x0">{{ None }}</DisplayString>
-    <DisplayString Condition="RUST$ENUM$DISR == 0x1">{{ Some {__0} }}</DisplayString>
+    <DisplayString Condition="RUST$ENUM$DISR == 0x0">None</DisplayString>
+    <DisplayString Condition="RUST$ENUM$DISR == 0x1">Some({__0})</DisplayString>
     <Expand>
-      <Item Name="[size]" ExcludeView="simple">(ULONG)(RUST$ENUM$DISR != 0)</Item>
-      <Item Name="[value]" ExcludeView="simple">__0</Item>
-      <ArrayItems>
-        <Size>(ULONG)(RUST$ENUM$DISR != 0)</Size>
-        <ValuePointer>&amp;__0</ValuePointer>
-      </ArrayItems>
+      <Item Name="[value]" ExcludeView="simple" Condition="RUST$ENUM$DISR == 1">__0</Item>
     </Expand>
   </Type>
+
   <Type Name="core::option::Option&lt;*&gt;" Priority="MediumLow">
-    <DisplayString Condition="*(PVOID *)this == nullptr">{{ None }}</DisplayString>
-    <DisplayString>{{ Some {($T1 *)this} }}</DisplayString>
+    <DisplayString Condition="*(void**)this == nullptr">None</DisplayString>
+    <DisplayString>Some({($T1 *)this})</DisplayString>
     <Expand>
-      <Item Name="[size]" ExcludeView="simple">(ULONG)(*(PVOID *)this != nullptr)</Item>
-      <Item Name="[value]" ExcludeView="simple" Condition="*(PVOID *)this != nullptr">($T1 *)this</Item>
-      <ArrayItems>
-        <Size>(ULONG)(*(PVOID *)this != nullptr)</Size>
-        <ValuePointer>($T1 *)this</ValuePointer>
-      </ArrayItems>
+      <Item Name="Some" ExcludeView="simple" Condition="*(void**)this != nullptr">($T1 *)this</Item>
     </Expand>
   </Type>
+
 </AutoVisualizer>
\ No newline at end of file
diff --git a/src/etc/natvis/libstd.natvis b/src/etc/natvis/libstd.natvis
index 9550c25f2fc..7e5ee7b13da 100644
--- a/src/etc/natvis/libstd.natvis
+++ b/src/etc/natvis/libstd.natvis
@@ -26,9 +26,9 @@
   -->
 
   <Type Name="std::collections::hash::map::HashMap&lt;*,*,*&gt;">
-    <DisplayString>{{ size={base.table.items} }}</DisplayString>
+    <DisplayString>{{ len={base.table.items} }}</DisplayString>
     <Expand>
-      <Item Name="[size]">base.table.items</Item>
+      <Item Name="[len]">base.table.items</Item>
       <Item Name="[capacity]">base.table.items + base.table.growth_left</Item>
       <Item Name="[state]">base.hash_builder</Item>
 
@@ -50,9 +50,9 @@
   </Type>
 
   <Type Name="std::collections::hash::set::HashSet&lt;*,*&gt;">
-    <DisplayString>{{ size={base.map.table.items} }}</DisplayString>
+    <DisplayString>{{ len={base.map.table.items} }}</DisplayString>
     <Expand>
-      <Item Name="[size]">base.map.table.items</Item>
+      <Item Name="[len]">base.map.table.items</Item>
       <Item Name="[capacity]">base.map.table.items + base.map.table.growth_left</Item>
       <Item Name="[state]">base.map.hash_builder</Item>
 
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 8feef9c259c..2a8b6a321f1 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -61,10 +61,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                             .params
                             .iter()
                             .filter_map(|param| match param.kind {
-                                ty::GenericParamDefKind::Lifetime => Some(param.name.to_string()),
+                                ty::GenericParamDefKind::Lifetime => Some(param.name),
                                 _ => None,
                             })
-                            .map(|name| (name.clone(), Lifetime(name)))
+                            .map(|name| (name, Lifetime(name)))
                             .collect();
                         let lifetime_predicates = self.handle_lifetimes(&region_data, &names_map);
                         let new_generics = self.param_env_to_generics(
@@ -118,15 +118,12 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                 };
 
                 Some(Item {
-                    source: Span::empty(),
+                    source: Span::dummy(),
                     name: None,
                     attrs: Default::default(),
                     visibility: Inherited,
                     def_id: self.cx.next_def_id(param_env_def_id.krate),
-                    stability: None,
-                    const_stability: None,
-                    deprecation: None,
-                    kind: ImplItem(Impl {
+                    kind: box ImplItem(Impl {
                         unsafety: hir::Unsafety::Normal,
                         generics: new_generics,
                         provided_trait_methods: Default::default(),
@@ -145,21 +142,21 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
     fn get_lifetime(
         &self,
         region: Region<'_>,
-        names_map: &FxHashMap<String, Lifetime>,
+        names_map: &FxHashMap<Symbol, Lifetime>,
     ) -> Lifetime {
         self.region_name(region)
             .map(|name| {
                 names_map.get(&name).unwrap_or_else(|| {
-                    panic!("Missing lifetime with name {:?} for {:?}", name, region)
+                    panic!("Missing lifetime with name {:?} for {:?}", name.as_str(), region)
                 })
             })
             .unwrap_or(&Lifetime::statik())
             .clone()
     }
 
-    fn region_name(&self, region: Region<'_>) -> Option<String> {
+    fn region_name(&self, region: Region<'_>) -> Option<Symbol> {
         match region {
-            &ty::ReEarlyBound(r) => Some(r.name.to_string()),
+            &ty::ReEarlyBound(r) => Some(r.name),
             _ => None,
         }
     }
@@ -177,7 +174,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
     fn handle_lifetimes<'cx>(
         &self,
         regions: &RegionConstraintData<'cx>,
-        names_map: &FxHashMap<String, Lifetime>,
+        names_map: &FxHashMap<Symbol, Lifetime>,
     ) -> Vec<WherePredicate> {
         // Our goal is to 'flatten' the list of constraints by eliminating
         // all intermediate RegionVids. At the end, all constraints should
@@ -333,10 +330,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                 match br {
                     // We only care about named late bound regions, as we need to add them
                     // to the 'for<>' section
-                    ty::BrNamed(_, name) => Some(GenericParamDef {
-                        name: name.to_string(),
-                        kind: GenericParamDefKind::Lifetime,
-                    }),
+                    ty::BrNamed(_, name) => {
+                        Some(GenericParamDef { name, kind: GenericParamDefKind::Lifetime })
+                    }
                     _ => None,
                 }
             })
@@ -569,7 +565,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                 }
                 WherePredicate::EqPredicate { lhs, rhs } => {
                     match lhs {
-                        Type::QPath { name: ref left_name, ref self_type, ref trait_ } => {
+                        Type::QPath { name: left_name, ref self_type, ref trait_ } => {
                             let ty = &*self_type;
                             match **trait_ {
                                 Type::ResolvedPath {
@@ -580,7 +576,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                                 } => {
                                     let mut new_trait_path = trait_path.clone();
 
-                                    if self.is_fn_ty(tcx, trait_) && left_name == FN_OUTPUT_NAME {
+                                    if self.is_fn_ty(tcx, trait_) && left_name == sym::Output {
                                         ty_to_fn
                                             .entry(*ty.clone())
                                             .and_modify(|e| *e = (e.0.clone(), Some(rhs.clone())))
@@ -601,7 +597,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                                             ref mut bindings, ..
                                         } => {
                                             bindings.push(TypeBinding {
-                                                name: left_name.clone(),
+                                                name: left_name,
                                                 kind: TypeBindingKind::Equality { ty: rhs },
                                             });
                                         }
@@ -669,7 +665,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                 GenericParamDefKind::Type { ref mut default, ref mut bounds, .. } => {
                     // We never want something like `impl<T=Foo>`.
                     default.take();
-                    let generic_ty = Type::Generic(param.name.clone());
+                    let generic_ty = Type::Generic(param.name);
                     if !has_sized.contains(&generic_ty) {
                         bounds.insert(0, GenericBound::maybe_sized(self.cx));
                     }
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 33b5e84c5e0..ba3eb007e38 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -103,7 +103,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                     .cx
                     .tcx
                     .provided_trait_methods(trait_def_id)
-                    .map(|meth| meth.ident.to_string())
+                    .map(|meth| meth.ident.name)
                     .collect();
 
                 impls.push(Item {
@@ -112,10 +112,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                     attrs: Default::default(),
                     visibility: Inherited,
                     def_id: self.cx.next_def_id(impl_def_id.krate),
-                    stability: None,
-                    const_stability: None,
-                    deprecation: None,
-                    kind: ImplItem(Impl {
+                    kind: box ImplItem(Impl {
                         unsafety: hir::Unsafety::Normal,
                         generics: (
                             self.cx.tcx.generics_of(impl_def_id),
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index f3067360f06..c168c56d30d 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -12,7 +12,7 @@ use rustc_metadata::creader::LoadedMacro;
 use rustc_middle::ty;
 use rustc_mir::const_eval::is_min_const_fn;
 use rustc_span::hygiene::MacroKind;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
 
 use crate::clean::{self, Attributes, GetDefId, ToSource, TypeKind};
@@ -124,7 +124,7 @@ crate fn try_inline(
     let attrs = merge_attrs(cx, Some(parent_module), target_attrs, attrs_clone);
 
     cx.renderinfo.borrow_mut().inlined.insert(did);
-    let what_rustc_thinks = clean::Item::from_def_id_and_parts(did, Some(name.clean(cx)), kind, cx);
+    let what_rustc_thinks = clean::Item::from_def_id_and_parts(did, Some(name), kind, cx);
     ret.push(clean::Item { attrs, ..what_rustc_thinks });
     Some(ret)
 }
@@ -339,9 +339,6 @@ crate fn build_impl(
         return;
     }
 
-    let attrs = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs);
-    debug!("merged_attrs={:?}", attrs);
-
     let tcx = cx.tcx;
     let associated_trait = tcx.impl_trait_ref(did);
 
@@ -430,12 +427,12 @@ crate fn build_impl(
 
     let provided = trait_
         .def_id()
-        .map(|did| tcx.provided_trait_methods(did).map(|meth| meth.ident.to_string()).collect())
+        .map(|did| tcx.provided_trait_methods(did).map(|meth| meth.ident.name).collect())
         .unwrap_or_default();
 
     debug!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id());
 
-    ret.push(clean::Item::from_def_id_and_parts(
+    let mut item = clean::Item::from_def_id_and_parts(
         did,
         None,
         clean::ImplItem(clean::Impl {
@@ -450,7 +447,10 @@ crate fn build_impl(
             blanket_impl: None,
         }),
         cx,
-    ));
+    );
+    item.attrs = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs);
+    debug!("merged_attrs={:?}", item.attrs);
+    ret.push(item);
 }
 
 fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>) -> clean::Module {
@@ -479,20 +479,17 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>)
                     items.push(clean::Item {
                         name: None,
                         attrs: clean::Attributes::default(),
-                        source: clean::Span::empty(),
+                        source: clean::Span::dummy(),
                         def_id: DefId::local(CRATE_DEF_INDEX),
                         visibility: clean::Public,
-                        stability: None,
-                        const_stability: None,
-                        deprecation: None,
-                        kind: clean::ImportItem(clean::Import::new_simple(
-                            item.ident.to_string(),
+                        kind: box clean::ImportItem(clean::Import::new_simple(
+                            item.ident.name,
                             clean::ImportSource {
                                 path: clean::Path {
                                     global: false,
                                     res: item.res,
                                     segments: vec![clean::PathSegment {
-                                        name: clean::PrimitiveType::from(p).as_str().to_string(),
+                                        name: clean::PrimitiveType::from(p).as_sym(),
                                         args: clean::GenericArgs::AngleBracketed {
                                             args: Vec::new(),
                                             bindings: Vec::new(),
@@ -562,11 +559,11 @@ fn build_macro(cx: &DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemKind
                     .collect::<String>()
             );
 
-            clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from).clean(cx) })
+            clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from) })
         }
         LoadedMacro::ProcMacro(ext) => clean::ProcMacroItem(clean::ProcMacro {
             kind: ext.macro_kind(),
-            helpers: ext.helper_attrs.clean(cx),
+            helpers: ext.helper_attrs,
         }),
     }
 }
@@ -583,7 +580,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
     for pred in &mut g.where_predicates {
         match *pred {
             clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref mut bounds }
-                if *s == "Self" =>
+                if *s == kw::SelfUpper =>
             {
                 bounds.retain(|bound| match *bound {
                     clean::GenericBound::TraitBound(
@@ -606,7 +603,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
                     name: ref _name,
                 },
             ref bounds,
-        } => !(bounds.is_empty() || *s == "Self" && did == trait_did),
+        } => !(bounds.is_empty() || *s == kw::SelfUpper && did == trait_did),
         _ => true,
     });
     g
@@ -621,7 +618,7 @@ fn separate_supertrait_bounds(
     let mut ty_bounds = Vec::new();
     g.where_predicates.retain(|pred| match *pred {
         clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds }
-            if *s == "Self" =>
+            if *s == kw::SelfUpper =>
         {
             ty_bounds.extend(bounds.iter().cloned());
             false
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 16274430902..f4eb1924e6f 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -25,7 +25,7 @@ use rustc_middle::ty::{self, AdtKind, Lift, Ty, TyCtxt};
 use rustc_mir::const_eval::{is_const_fn, is_min_const_fn, is_unstable_const_fn};
 use rustc_span::hygiene::{AstPass, MacroKind};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{self, ExpnKind, Pos};
+use rustc_span::{self, ExpnKind};
 use rustc_typeck::hir_ty_to_ty;
 
 use std::collections::hash_map::Entry;
@@ -48,8 +48,6 @@ crate use self::types::Type::*;
 crate use self::types::Visibility::{Inherited, Public};
 crate use self::types::*;
 
-const FN_OUTPUT_NAME: &str = "Output";
-
 crate trait Clean<T> {
     fn clean(&self, cx: &DocContext<'_>) -> T;
 }
@@ -169,7 +167,7 @@ impl Clean<ExternalCrate> for CrateNum {
                 for attr in attrs.lists(sym::doc) {
                     if attr.has_name(sym::keyword) {
                         if let Some(v) = attr.value_str() {
-                            keyword = Some(v.to_string());
+                            keyword = Some(v);
                             break;
                         }
                     }
@@ -209,7 +207,7 @@ impl Clean<ExternalCrate> for CrateNum {
         };
 
         ExternalCrate {
-            name: cx.tcx.crate_name(*self).to_string(),
+            name: cx.tcx.crate_name(*self),
             src: krate_src,
             attrs: cx.tcx.get_attrs(root).clean(cx),
             primitives,
@@ -220,11 +218,6 @@ impl Clean<ExternalCrate> for CrateNum {
 
 impl Clean<Item> for doctree::Module<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
-        // maintain a stack of mod ids, for doc comment path resolution
-        // but we also need to resolve the module's own docs based on whether its docs were written
-        // inside or outside the module, so check for that
-        let attrs = self.attrs.clean(cx);
-
         let mut items: Vec<Item> = vec![];
         items.extend(self.imports.iter().flat_map(|x| x.clean(cx)));
         items.extend(self.foreigns.iter().map(|x| x.clean(cx)));
@@ -253,12 +246,7 @@ impl Clean<Item> for doctree::Module<'_> {
             ModuleItem(Module { is_crate: self.is_crate, items }),
             cx,
         );
-        Item {
-            name: Some(what_rustc_thinks.name.unwrap_or_default()),
-            attrs,
-            source: span.clean(cx),
-            ..what_rustc_thinks
-        }
+        Item { source: span.clean(cx), ..what_rustc_thinks }
     }
 }
 
@@ -334,10 +322,9 @@ impl Clean<GenericBound> for (ty::PolyTraitRef<'_>, &[TypeBinding]) {
             .collect_referenced_late_bound_regions(&poly_trait_ref)
             .into_iter()
             .filter_map(|br| match br {
-                ty::BrNamed(_, name) => Some(GenericParamDef {
-                    name: name.to_string(),
-                    kind: GenericParamDefKind::Lifetime,
-                }),
+                ty::BrNamed(_, name) => {
+                    Some(GenericParamDef { name, kind: GenericParamDefKind::Lifetime })
+                }
                 _ => None,
             })
             .collect();
@@ -387,7 +374,7 @@ impl Clean<Lifetime> for hir::Lifetime {
             }
             _ => {}
         }
-        Lifetime(self.name.ident().to_string())
+        Lifetime(self.name.ident().name)
     }
 }
 
@@ -405,9 +392,9 @@ impl Clean<Lifetime> for hir::GenericParam<'_> {
                     for bound in bounds {
                         s.push_str(&format!(" + {}", bound.name.ident()));
                     }
-                    Lifetime(s)
+                    Lifetime(Symbol::intern(&s))
                 } else {
-                    Lifetime(self.name.ident().to_string())
+                    Lifetime(self.name.ident().name)
                 }
             }
             _ => panic!(),
@@ -431,16 +418,18 @@ impl Clean<Constant> for hir::ConstArg {
 
 impl Clean<Lifetime> for ty::GenericParamDef {
     fn clean(&self, _cx: &DocContext<'_>) -> Lifetime {
-        Lifetime(self.name.to_string())
+        Lifetime(self.name)
     }
 }
 
 impl Clean<Option<Lifetime>> for ty::RegionKind {
-    fn clean(&self, cx: &DocContext<'_>) -> Option<Lifetime> {
+    fn clean(&self, _cx: &DocContext<'_>) -> Option<Lifetime> {
         match *self {
             ty::ReStatic => Some(Lifetime::statik()),
-            ty::ReLateBound(_, ty::BrNamed(_, name)) => Some(Lifetime(name.to_string())),
-            ty::ReEarlyBound(ref data) => Some(Lifetime(data.name.clean(cx))),
+            ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name) }) => {
+                Some(Lifetime(name))
+            }
+            ty::ReEarlyBound(ref data) => Some(Lifetime(data.name)),
 
             ty::ReLateBound(..)
             | ty::ReFree(..)
@@ -477,8 +466,9 @@ impl Clean<WherePredicate> for hir::WherePredicate<'_> {
 
 impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
     fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
-        match self.skip_binders() {
-            ty::PredicateAtom::Trait(pred, _) => Some(ty::Binder::bind(pred).clean(cx)),
+        let bound_predicate = self.bound_atom();
+        match bound_predicate.skip_binder() {
+            ty::PredicateAtom::Trait(pred, _) => Some(bound_predicate.rebind(pred).clean(cx)),
             ty::PredicateAtom::RegionOutlives(pred) => pred.clean(cx),
             ty::PredicateAtom::TypeOutlives(pred) => pred.clean(cx),
             ty::PredicateAtom::Projection(pred) => Some(pred.clean(cx)),
@@ -551,7 +541,7 @@ impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
             GenericBound::Outlives(_) => panic!("cleaning a trait got a lifetime"),
         };
         Type::QPath {
-            name: cx.tcx.associated_item(self.item_def_id).ident.name.clean(cx),
+            name: cx.tcx.associated_item(self.item_def_id).ident.name,
             self_type: box self.self_ty().clean(cx),
             trait_: box trait_,
         }
@@ -561,14 +551,12 @@ impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
 impl Clean<GenericParamDef> for ty::GenericParamDef {
     fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
         let (name, kind) = match self.kind {
-            ty::GenericParamDefKind::Lifetime => {
-                (self.name.to_string(), GenericParamDefKind::Lifetime)
-            }
+            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 };
                 (
-                    self.name.clean(cx),
+                    self.name,
                     GenericParamDefKind::Type {
                         did: self.def_id,
                         bounds: vec![], // These are filled in from the where-clauses.
@@ -578,7 +566,7 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
                 )
             }
             ty::GenericParamDefKind::Const { .. } => (
-                self.name.clean(cx),
+                self.name,
                 GenericParamDefKind::Const {
                     did: self.def_id,
                     ty: cx.tcx.type_of(self.def_id).clean(cx),
@@ -604,14 +592,14 @@ impl Clean<GenericParamDef> for hir::GenericParam<'_> {
                     for bound in bounds {
                         s.push_str(&format!(" + {}", bound.name.ident()));
                     }
-                    s
+                    Symbol::intern(&s)
                 } else {
-                    self.name.ident().to_string()
+                    self.name.ident().name
                 };
                 (name, GenericParamDefKind::Lifetime)
             }
             hir::GenericParamKind::Type { ref default, synthetic } => (
-                self.name.ident().name.clean(cx),
+                self.name.ident().name,
                 GenericParamDefKind::Type {
                     did: cx.tcx.hir().local_def_id(self.hir_id).to_def_id(),
                     bounds: self.bounds.clean(cx),
@@ -620,7 +608,7 @@ impl Clean<GenericParamDef> for hir::GenericParam<'_> {
                 },
             ),
             hir::GenericParamKind::Const { ref ty } => (
-                self.name.ident().name.clean(cx),
+                self.name.ident().name,
                 GenericParamDefKind::Const {
                     did: cx.tcx.hir().local_def_id(self.hir_id).to_def_id(),
                     ty: ty.clean(cx),
@@ -645,6 +633,18 @@ impl Clean<Generics> for hir::Generics<'_> {
                 _ => false,
             }
         }
+        /// This can happen for `async fn`, e.g. `async fn f<'_>(&'_ self)`.
+        ///
+        /// See [`lifetime_to_generic_param`] in [`rustc_ast_lowering`] for more information.
+        ///
+        /// [`lifetime_to_generic_param`]: rustc_ast_lowering::LoweringContext::lifetime_to_generic_param
+        fn is_elided_lifetime(param: &hir::GenericParam<'_>) -> bool {
+            match param.kind {
+                hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided } => true,
+                _ => false,
+            }
+        }
+
         let impl_trait_params = self
             .params
             .iter()
@@ -663,7 +663,7 @@ impl Clean<Generics> for hir::Generics<'_> {
             .collect::<Vec<_>>();
 
         let mut params = Vec::with_capacity(self.params.len());
-        for p in self.params.iter().filter(|p| !is_impl_trait(p)) {
+        for p in self.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) {
             let p = p.clean(cx);
             params.push(p);
         }
@@ -735,7 +735,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
             .collect::<Vec<GenericParamDef>>();
 
         // param index -> [(DefId of trait, associated type name, type)]
-        let mut impl_trait_proj = FxHashMap::<u32, Vec<(DefId, String, Ty<'tcx>)>>::default();
+        let mut impl_trait_proj = FxHashMap::<u32, Vec<(DefId, Symbol, Ty<'tcx>)>>::default();
 
         let where_predicates = preds
             .predicates
@@ -743,7 +743,8 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
             .flat_map(|(p, _)| {
                 let mut projection = None;
                 let param_idx = (|| {
-                    match p.skip_binders() {
+                    let bound_p = p.bound_atom();
+                    match bound_p.skip_binder() {
                         ty::PredicateAtom::Trait(pred, _constness) => {
                             if let ty::Param(param) = pred.self_ty().kind() {
                                 return Some(param.index);
@@ -756,7 +757,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
                         }
                         ty::PredicateAtom::Projection(p) => {
                             if let ty::Param(param) = p.projection_ty.self_ty().kind() {
-                                projection = Some(ty::Binder::bind(p));
+                                projection = Some(bound_p.rebind(p));
                                 return Some(param.index);
                             }
                         }
@@ -783,11 +784,10 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
                         if let Some(((_, trait_did, name), rhs)) =
                             proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs)))
                         {
-                            impl_trait_proj.entry(param_idx).or_default().push((
-                                trait_did,
-                                name.to_string(),
-                                rhs,
-                            ));
+                            impl_trait_proj
+                                .entry(param_idx)
+                                .or_default()
+                                .push((trait_did, name, rhs));
                         }
 
                         return None;
@@ -805,7 +805,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
             if let crate::core::ImplTraitParam::ParamIndex(idx) = param {
                 if let Some(proj) = impl_trait_proj.remove(&idx) {
                     for (trait_did, name, rhs) in proj {
-                        simplify::merge_bounds(cx, &mut bounds, trait_did, &name, &rhs.clean(cx));
+                        simplify::merge_bounds(cx, &mut bounds, trait_did, name, &rhs.clean(cx));
                     }
                 }
             } else {
@@ -831,7 +831,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
         where_predicates.retain(|pred| match *pred {
             WP::BoundPredicate { ty: Generic(ref g), ref bounds } => {
                 if bounds.iter().any(|b| b.is_sized_bound(cx)) {
-                    sized_params.insert(g.clone());
+                    sized_params.insert(*g);
                     false
                 } else {
                     true
@@ -847,7 +847,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
                 && !sized_params.contains(&tp.name)
             {
                 where_predicates.push(WP::BoundPredicate {
-                    ty: Type::Generic(tp.name.clone()),
+                    ty: Type::Generic(tp.name),
                     bounds: vec![GenericBound::maybe_sized(cx)],
                 })
             }
@@ -908,7 +908,7 @@ fn clean_fn_or_proc_macro(
                     }
                 }
             }
-            ProcMacroItem(ProcMacro { kind, helpers: helpers.clean(cx) })
+            ProcMacroItem(ProcMacro { kind, helpers })
         }
         None => {
             let mut func = (sig, generics, body_id).clean(cx);
@@ -941,9 +941,9 @@ impl<'a> Clean<Arguments> for (&'a [hir::Ty<'a>], &'a [Ident]) {
                 .iter()
                 .enumerate()
                 .map(|(i, ty)| {
-                    let mut name = self.1.get(i).map(|ident| ident.to_string()).unwrap_or_default();
+                    let mut name = self.1.get(i).map(|ident| ident.name).unwrap_or(kw::Empty);
                     if name.is_empty() {
-                        name = "_".to_string();
+                        name = kw::Underscore;
                     }
                     Argument { name, type_: ty.clean(cx) }
                 })
@@ -1000,7 +1000,7 @@ impl<'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
                     .iter()
                     .map(|t| Argument {
                         type_: t.clean(cx),
-                        name: names.next().map_or_else(|| String::new(), |name| name.to_string()),
+                        name: names.next().map(|i| i.name).unwrap_or(kw::Empty),
                     })
                     .collect(),
             },
@@ -1096,7 +1096,7 @@ impl Clean<Item> for hir::TraitItem<'_> {
                     AssocTypeItem(bounds.clean(cx), default.clean(cx))
                 }
             };
-            Item::from_def_id_and_parts(local_did, Some(self.ident.name.clean(cx)), inner, cx)
+            Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx)
         })
     }
 }
@@ -1124,7 +1124,7 @@ impl Clean<Item> for hir::ImplItem<'_> {
                     TypedefItem(Typedef { type_, generics: Generics::default(), item_type }, true)
                 }
             };
-            Item::from_def_id_and_parts(local_did, Some(self.ident.name.clean(cx)), inner, cx)
+            Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx)
         })
     }
 }
@@ -1155,12 +1155,12 @@ impl Clean<Item> for ty::AssocItem {
                     };
                     let self_arg_ty = sig.input(0).skip_binder();
                     if self_arg_ty == self_ty {
-                        decl.inputs.values[0].type_ = Generic(String::from("Self"));
+                        decl.inputs.values[0].type_ = Generic(kw::SelfUpper);
                     } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
                         if ty == self_ty {
                             match decl.inputs.values[0].type_ {
                                 BorrowedRef { ref mut type_, .. } => {
-                                    **type_ = Generic(String::from("Self"))
+                                    **type_ = Generic(kw::SelfUpper)
                                 }
                                 _ => unreachable!(),
                             }
@@ -1215,7 +1215,7 @@ impl Clean<Item> for ty::AssocItem {
                 }
             }
             ty::AssocKind::Type => {
-                let my_name = self.ident.name.clean(cx);
+                let my_name = self.ident.name;
 
                 if let ty::TraitContainer(_) = self.container {
                     let bounds = cx.tcx.explicit_item_bounds(self.def_id);
@@ -1240,7 +1240,7 @@ impl Clean<Item> for ty::AssocItem {
                                 _ => return None,
                             }
                             match **self_type {
-                                Generic(ref s) if *s == "Self" => {}
+                                Generic(ref s) if *s == kw::SelfUpper => {}
                                 _ => return None,
                             }
                             Some(bounds)
@@ -1281,7 +1281,7 @@ impl Clean<Item> for ty::AssocItem {
             }
         };
 
-        Item::from_def_id_and_parts(self.def_id, Some(self.ident.name.clean(cx)), kind, cx)
+        Item::from_def_id_and_parts(self.def_id, Some(self.ident.name), kind, cx)
     }
 }
 
@@ -1413,7 +1413,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &DocContext<'_>) -> Type {
                 segments: trait_segments.clean(cx),
             };
             Type::QPath {
-                name: p.segments.last().expect("segments were empty").ident.name.clean(cx),
+                name: p.segments.last().expect("segments were empty").ident.name,
                 self_type: box qself.clean(cx),
                 trait_: box resolve_type(cx, trait_path, hir_id),
             }
@@ -1427,7 +1427,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &DocContext<'_>) -> Type {
             };
             let trait_path = hir::Path { span, res, segments: &[] };
             Type::QPath {
-                name: segment.ident.name.clean(cx),
+                name: segment.ident.name,
                 self_type: box qself.clean(cx),
                 trait_: box resolve_type(cx, trait_path.clean(cx), hir_id),
             }
@@ -1444,7 +1444,16 @@ impl Clean<Type> for hir::Ty<'_> {
             TyKind::Never => Never,
             TyKind::Ptr(ref m) => RawPointer(m.mutbl, box m.ty.clean(cx)),
             TyKind::Rptr(ref l, ref m) => {
-                let lifetime = if l.is_elided() { None } else { Some(l.clean(cx)) };
+                // There are two times a `Fresh` lifetime can be created:
+                // 1. For `&'_ x`, written by the user. This corresponds to `lower_lifetime` in `rustc_ast_lowering`.
+                // 2. For `&x` as a parameter to an `async fn`. This corresponds to `elided_ref_lifetime in `rustc_ast_lowering`.
+                //    See #59286 for more information.
+                // Ideally we would only hide the `'_` for case 2., but I don't know a way to distinguish it.
+                // Turning `fn f(&'_ self)` into `fn f(&self)` isn't the worst thing in the world, though;
+                // there's no case where it could cause the function to fail to compile.
+                let elided =
+                    l.is_elided() || matches!(l.name, LifetimeName::Param(ParamName::Fresh(_)));
+                let lifetime = if elided { None } else { Some(l.clean(cx)) };
                 BorrowedRef { lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx) }
             }
             TyKind::Slice(ref ty) => Slice(box ty.clean(cx)),
@@ -1630,7 +1639,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                 let mut bindings = vec![];
                 for pb in obj.projection_bounds() {
                     bindings.push(TypeBinding {
-                        name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx),
+                        name: cx.tcx.associated_item(pb.item_def_id()).ident.name,
                         kind: TypeBindingKind::Equality { ty: pb.skip_binder().ty.clean(cx) },
                     });
                 }
@@ -1649,7 +1658,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                 if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&p.index.into()) {
                     ImplTrait(bounds)
                 } else {
-                    Generic(p.name.to_string())
+                    Generic(p.name)
                 }
             }
 
@@ -1670,12 +1679,10 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                     .filter_map(|bound| {
                         // Note: The substs of opaque types can contain unbound variables,
                         // meaning that we have to use `ignore_quantifiers_with_unbound_vars` here.
-                        let trait_ref = match bound
-                            .bound_atom_with_opt_escaping(cx.tcx)
-                            .skip_binder()
-                        {
+                        let bound_predicate = bound.bound_atom_with_opt_escaping(cx.tcx);
+                        let trait_ref = match bound_predicate.skip_binder() {
                             ty::PredicateAtom::Trait(tr, _constness) => {
-                                ty::Binder::bind(tr.trait_ref)
+                                bound_predicate.rebind(tr.trait_ref)
                             }
                             ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => {
                                 if let Some(r) = reg.clean(cx) {
@@ -1707,8 +1714,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                                                 .tcx
                                                 .associated_item(proj.projection_ty.item_def_id)
                                                 .ident
-                                                .name
-                                                .clean(cx),
+                                                .name,
                                             kind: TypeBindingKind::Equality {
                                                 ty: proj.ty.clean(cx),
                                             },
@@ -1771,7 +1777,7 @@ impl Clean<Item> for ty::FieldDef {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         let what_rustc_thinks = Item::from_def_id_and_parts(
             self.did,
-            Some(self.ident.name.clean(cx)),
+            Some(self.ident.name),
             StructFieldItem(cx.tcx.type_of(self.did).clean(cx)),
             cx,
         );
@@ -1787,25 +1793,28 @@ impl Clean<Visibility> for hir::Visibility<'_> {
             hir::VisibilityKind::Inherited => Visibility::Inherited,
             hir::VisibilityKind::Crate(_) => {
                 let krate = DefId::local(CRATE_DEF_INDEX);
-                Visibility::Restricted(krate, cx.tcx.def_path(krate))
+                Visibility::Restricted(krate)
             }
             hir::VisibilityKind::Restricted { ref path, .. } => {
                 let path = path.clean(cx);
                 let did = register_res(cx, path.res);
-                Visibility::Restricted(did, cx.tcx.def_path(did))
+                Visibility::Restricted(did)
             }
         }
     }
 }
 
 impl Clean<Visibility> for ty::Visibility {
-    fn clean(&self, cx: &DocContext<'_>) -> Visibility {
+    fn clean(&self, _cx: &DocContext<'_>) -> Visibility {
         match *self {
             ty::Visibility::Public => Visibility::Public,
+            // NOTE: this is not quite right: `ty` uses `Invisible` to mean 'private',
+            // while rustdoc really does mean inherited. That means that for enum variants, such as
+            // `pub enum E { V }`, `V` will be marked as `Public` by `ty`, but as `Inherited` by rustdoc.
+            // This is the main reason `impl Clean for hir::Visibility` still exists; various parts of clean
+            // override `tcx.visibility` explicitly to make sure this distinction is captured.
             ty::Visibility::Invisible => Visibility::Inherited,
-            ty::Visibility::Restricted(module) => {
-                Visibility::Restricted(module, cx.tcx.def_path(module))
-            }
+            ty::Visibility::Restricted(module) => Visibility::Restricted(module),
         }
     }
 }
@@ -1847,7 +1856,7 @@ impl Clean<Item> for ty::VariantDef {
                     .fields
                     .iter()
                     .map(|field| {
-                        let name = Some(field.ident.name.clean(cx));
+                        let name = Some(field.ident.name);
                         let kind = StructFieldItem(cx.tcx.type_of(field.did).clean(cx));
                         let what_rustc_thinks =
                             Item::from_def_id_and_parts(field.did, name, kind, cx);
@@ -1859,7 +1868,7 @@ impl Clean<Item> for ty::VariantDef {
         };
         let what_rustc_thinks = Item::from_def_id_and_parts(
             self.def_id,
-            Some(self.ident.name.clean(cx)),
+            Some(self.ident.name),
             VariantItem(Variant { kind }),
             cx,
         );
@@ -1881,29 +1890,8 @@ impl Clean<VariantKind> for hir::VariantData<'_> {
 }
 
 impl Clean<Span> for rustc_span::Span {
-    fn clean(&self, cx: &DocContext<'_>) -> Span {
-        if self.is_dummy() {
-            return Span::empty();
-        }
-
-        // Get the macro invocation instead of the definition,
-        // in case the span is result of a macro expansion.
-        // (See rust-lang/rust#39726)
-        let span = self.source_callsite();
-
-        let sm = cx.sess().source_map();
-        let filename = sm.span_to_filename(span);
-        let lo = sm.lookup_char_pos(span.lo());
-        let hi = sm.lookup_char_pos(span.hi());
-        Span {
-            filename,
-            cnum: lo.file.cnum,
-            loline: lo.line,
-            locol: lo.col.to_usize(),
-            hiline: hi.line,
-            hicol: hi.col.to_usize(),
-            original: span,
-        }
+    fn clean(&self, _cx: &DocContext<'_>) -> Span {
+        Span::from_rustc_span(*self)
     }
 }
 
@@ -1947,7 +1935,7 @@ impl Clean<GenericArgs> for hir::GenericArgs<'_> {
 
 impl Clean<PathSegment> for hir::PathSegment<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> PathSegment {
-        PathSegment { name: self.ident.name.clean(cx), args: self.generic_args().clean(cx) }
+        PathSegment { name: self.ident.name, args: self.generic_args().clean(cx) }
     }
 }
 
@@ -2054,7 +2042,7 @@ impl Clean<Vec<Item>> for (&hir::Item<'_>, Option<Symbol>) {
                 _ => unreachable!("not yet converted"),
             };
 
-            vec![Item::from_def_id_and_parts(def_id, Some(name.clean(cx)), kind, cx)]
+            vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)]
         })
     }
 }
@@ -2098,9 +2086,9 @@ fn clean_impl(impl_: &hir::Item<'_>, cx: &DocContext<'_>) -> Vec<Item> {
         build_deref_target_impls(cx, &items, &mut ret);
     }
 
-    let provided: FxHashSet<String> = trait_
+    let provided: FxHashSet<Symbol> = trait_
         .def_id()
-        .map(|did| cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.to_string()).collect())
+        .map(|did| cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.name).collect())
         .unwrap_or_default();
 
     let for_ = for_.clean(cx);
@@ -2165,7 +2153,6 @@ fn clean_extern_crate(
             return items;
         }
     }
-    let path = orig_name.map(|x| x.to_string());
     // FIXME: using `from_def_id_and_kind` breaks `rustdoc/masked` for some reason
     vec![Item {
         name: None,
@@ -2173,10 +2160,7 @@ fn clean_extern_crate(
         source: krate.span.clean(cx),
         def_id: crate_def_id,
         visibility: krate.vis.clean(cx),
-        stability: None,
-        const_stability: None,
-        deprecation: None,
-        kind: ExternCrateItem(name.clean(cx), path),
+        kind: box ExternCrateItem(name, orig_name),
     }]
 }
 
@@ -2189,11 +2173,26 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
             return Vec::new();
         }
 
+        let (doc_meta_item, please_inline) = self.attrs.lists(sym::doc).get_word_attr(sym::inline);
+        let pub_underscore = self.vis.node.is_pub() && self.name == kw::Underscore;
+
+        if pub_underscore && please_inline {
+            rustc_errors::struct_span_err!(
+                cx.tcx.sess,
+                doc_meta_item.unwrap().span(),
+                E0780,
+                "anonymous imports cannot be inlined"
+            )
+            .span_label(self.span, "anonymous import")
+            .emit();
+        }
+
         // We consider inlining the documentation of `pub use` statements, but we
         // forcefully don't inline if this is not public or if the
         // #[doc(no_inline)] attribute is present.
         // Don't inline doc(hidden) imports so they can be stripped at a later stage.
         let mut denied = !self.vis.node.is_pub()
+            || pub_underscore
             || self.attrs.iter().any(|a| {
                 a.has_name(sym::doc)
                     && match a.meta_item_list() {
@@ -2206,7 +2205,6 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
             });
         // Also check whether imports were asked to be inlined, in case we're trying to re-export a
         // crate in Rust 2018+
-        let please_inline = self.attrs.lists(sym::doc).has_word(sym::inline);
         let path = self.path.clean(cx);
         let inner = if self.glob {
             if !denied {
@@ -2244,11 +2242,8 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
                         source: self.span.clean(cx),
                         def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
                         visibility: self.vis.clean(cx),
-                        stability: None,
-                        const_stability: None,
-                        deprecation: None,
-                        kind: ImportItem(Import::new_simple(
-                            self.name.clean(cx),
+                        kind: box ImportItem(Import::new_simple(
+                            self.name,
                             resolve_use_source(cx, path),
                             false,
                         )),
@@ -2256,7 +2251,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
                     return items;
                 }
             }
-            Import::new_simple(name.clean(cx), resolve_use_source(cx, path), true)
+            Import::new_simple(name, resolve_use_source(cx, path), true)
         };
 
         vec![Item {
@@ -2265,10 +2260,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
             source: self.span.clean(cx),
             def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
             visibility: self.vis.clean(cx),
-            stability: None,
-            const_stability: None,
-            deprecation: None,
-            kind: ImportItem(inner),
+            kind: box ImportItem(inner),
         }]
     }
 }
@@ -2333,18 +2325,19 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
             )
         } else {
             let vis = item.vis.clean(cx);
+            let def_id = cx.tcx.hir().local_def_id(item.hir_id).to_def_id();
 
             if matchers.len() <= 1 {
                 format!(
                     "{}macro {}{} {{\n    ...\n}}",
-                    vis.print_with_space(),
+                    vis.print_with_space(cx.tcx, def_id),
                     name,
                     matchers.iter().map(|span| span.to_src(cx)).collect::<String>(),
                 )
             } else {
                 format!(
                     "{}macro {} {{\n{}}}",
-                    vis.print_with_space(),
+                    vis.print_with_space(cx.tcx, def_id),
                     name,
                     matchers
                         .iter()
@@ -2363,19 +2356,9 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
     }
 }
 
-impl Clean<Deprecation> for attr::Deprecation {
-    fn clean(&self, _: &DocContext<'_>) -> Deprecation {
-        Deprecation {
-            since: self.since.map(|s| s.to_string()).filter(|s| !s.is_empty()),
-            note: self.note.map(|n| n.to_string()).filter(|n| !n.is_empty()),
-            is_since_rustc_version: self.is_since_rustc_version,
-        }
-    }
-}
-
 impl Clean<TypeBinding> for hir::TypeBinding<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> TypeBinding {
-        TypeBinding { name: self.ident.name.clean(cx), kind: self.kind.clean(cx) }
+        TypeBinding { name: self.ident.name, kind: self.kind.clean(cx) }
     }
 }
 
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 121c9d2bc4c..16aaa9cfd20 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -15,6 +15,7 @@ use std::collections::BTreeMap;
 
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty;
+use rustc_span::Symbol;
 
 use crate::clean;
 use crate::clean::GenericArgs as PP;
@@ -78,7 +79,7 @@ crate fn merge_bounds(
     cx: &clean::DocContext<'_>,
     bounds: &mut Vec<clean::GenericBound>,
     trait_did: DefId,
-    name: &str,
+    name: Symbol,
     rhs: &clean::Type,
 ) -> bool {
     !bounds.iter_mut().any(|b| {
@@ -100,7 +101,7 @@ crate fn merge_bounds(
         match last.args {
             PP::AngleBracketed { ref mut bindings, .. } => {
                 bindings.push(clean::TypeBinding {
-                    name: name.to_string(),
+                    name,
                     kind: clean::TypeBindingKind::Equality { ty: rhs.clone() },
                 });
             }
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index d4796b7ed66..0d33bc9afd5 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -12,20 +12,21 @@ use rustc_ast::attr;
 use rustc_ast::util::comments::beautify_doc_string;
 use rustc_ast::{self as ast, AttrStyle};
 use rustc_ast::{FloatTy, IntTy, UintTy};
-use rustc_attr::{ConstStability, Stability, StabilityLevel};
+use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_feature::UnstableFeatures;
 use rustc_hir as hir;
 use rustc_hir::def::Res;
-use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::Mutability;
 use rustc_index::vec::IndexVec;
-use rustc_middle::ty::{AssocKind, TyCtxt};
+use rustc_middle::ty::TyCtxt;
+use rustc_session::Session;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::DUMMY_SP;
 use rustc_span::symbol::{kw, sym, Ident, Symbol, SymbolStr};
-use rustc_span::{self, FileName};
+use rustc_span::{self, FileName, Loc};
 use rustc_target::abi::VariantIdx;
 use rustc_target::spec::abi::Abi;
 use smallvec::{smallvec, SmallVec};
@@ -50,7 +51,7 @@ thread_local!(crate static MAX_DEF_ID: RefCell<FxHashMap<CrateNum, DefId>> = Def
 
 #[derive(Clone, Debug)]
 crate struct Crate {
-    crate name: String,
+    crate name: Symbol,
     crate version: Option<String>,
     crate src: FileName,
     crate module: Option<Item>,
@@ -65,11 +66,11 @@ crate struct Crate {
 
 #[derive(Clone, Debug)]
 crate struct ExternalCrate {
-    crate name: String,
+    crate name: Symbol,
     crate src: FileName,
     crate attrs: Attributes,
     crate primitives: Vec<(DefId, PrimitiveType)>,
-    crate keywords: Vec<(DefId, String)>,
+    crate keywords: Vec<(DefId, Symbol)>,
 }
 
 /// Anything with a source location and set of attributes and, optionally, a
@@ -80,16 +81,17 @@ crate struct Item {
     /// Stringified span
     crate source: Span,
     /// Not everything has a name. E.g., impls
-    crate name: Option<String>,
+    crate name: Option<Symbol>,
     crate attrs: Attributes,
     crate visibility: Visibility,
-    crate kind: ItemKind,
+    crate kind: Box<ItemKind>,
     crate def_id: DefId,
-    crate stability: Option<Stability>,
-    crate deprecation: Option<Deprecation>,
-    crate const_stability: Option<ConstStability>,
 }
 
+// `Item` is used a lot. Make sure it doesn't unintentionally get bigger.
+#[cfg(target_arch = "x86_64")]
+rustc_data_structures::static_assert_size!(Item, 136);
+
 impl fmt::Debug for Item {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         let def_id: &dyn fmt::Debug = if self.is_fake() { &"**FAKE**" } else { &self.def_id };
@@ -101,13 +103,23 @@ impl fmt::Debug for Item {
             .field("kind", &self.kind)
             .field("visibility", &self.visibility)
             .field("def_id", def_id)
-            .field("stability", &self.stability)
-            .field("deprecation", &self.deprecation)
             .finish()
     }
 }
 
 impl Item {
+    crate fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx Stability> {
+        if self.is_fake() { None } else { tcx.lookup_stability(self.def_id) }
+    }
+
+    crate fn const_stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ConstStability> {
+        if self.is_fake() { None } else { tcx.lookup_const_stability(self.def_id) }
+    }
+
+    crate fn deprecation(&self, tcx: TyCtxt<'_>) -> Option<Deprecation> {
+        if self.is_fake() { None } else { tcx.lookup_deprecation(self.def_id) }
+    }
+
     /// Finds the `doc` attribute as a NameValue and returns the corresponding
     /// value found.
     crate fn doc_value(&self) -> Option<&str> {
@@ -122,17 +134,12 @@ impl Item {
         kind: ItemKind,
         cx: &DocContext<'_>,
     ) -> Item {
-        Item::from_def_id_and_parts(
-            cx.tcx.hir().local_def_id(hir_id).to_def_id(),
-            name.clean(cx),
-            kind,
-            cx,
-        )
+        Item::from_def_id_and_parts(cx.tcx.hir().local_def_id(hir_id).to_def_id(), name, kind, cx)
     }
 
     pub fn from_def_id_and_parts(
         def_id: DefId,
-        name: Option<String>,
+        name: Option<Symbol>,
         kind: ItemKind,
         cx: &DocContext<'_>,
     ) -> Item {
@@ -149,14 +156,11 @@ impl Item {
 
         Item {
             def_id,
-            kind,
+            kind: box kind,
             name,
             source: source.clean(cx),
             attrs: cx.tcx.get_attrs(def_id).clean(cx),
             visibility: cx.tcx.visibility(def_id).clean(cx),
-            stability: cx.tcx.lookup_stability(def_id).cloned(),
-            deprecation: cx.tcx.lookup_deprecation(def_id).clean(cx),
-            const_stability: cx.tcx.lookup_const_stability(def_id).cloned(),
         }
     }
 
@@ -171,7 +175,7 @@ impl Item {
     }
 
     crate fn is_crate(&self) -> bool {
-        match self.kind {
+        match *self.kind {
             StrippedItem(box ModuleItem(Module { is_crate: true, .. }))
             | ModuleItem(Module { is_crate: true, .. }) => true,
             _ => false,
@@ -223,14 +227,14 @@ impl Item {
         self.type_() == ItemType::Keyword
     }
     crate fn is_stripped(&self) -> bool {
-        match self.kind {
+        match *self.kind {
             StrippedItem(..) => true,
             ImportItem(ref i) => !i.should_be_displayed,
             _ => false,
         }
     }
     crate fn has_stripped_fields(&self) -> Option<bool> {
-        match self.kind {
+        match *self.kind {
             StructItem(ref _struct) => Some(_struct.fields_stripped),
             UnionItem(ref union) => Some(union.fields_stripped),
             VariantItem(Variant { kind: VariantKind::Struct(ref vstruct) }) => {
@@ -240,8 +244,8 @@ impl Item {
         }
     }
 
-    crate fn stability_class(&self) -> Option<String> {
-        self.stability.as_ref().and_then(|ref s| {
+    crate fn stability_class(&self, tcx: TyCtxt<'_>) -> Option<String> {
+        self.stability(tcx).as_ref().and_then(|ref s| {
             let mut classes = Vec::with_capacity(2);
 
             if s.level.is_unstable() {
@@ -249,7 +253,7 @@ impl Item {
             }
 
             // FIXME: what about non-staged API items that are deprecated?
-            if self.deprecation.is_some() {
+            if self.deprecation(tcx).is_some() {
                 classes.push("deprecated");
             }
 
@@ -257,15 +261,15 @@ impl Item {
         })
     }
 
-    crate fn stable_since(&self) -> Option<SymbolStr> {
-        match self.stability?.level {
+    crate fn stable_since(&self, tcx: TyCtxt<'_>) -> Option<SymbolStr> {
+        match self.stability(tcx)?.level {
             StabilityLevel::Stable { since, .. } => Some(since.as_str()),
             StabilityLevel::Unstable { .. } => None,
         }
     }
 
-    crate fn const_stable_since(&self) -> Option<SymbolStr> {
-        match self.const_stability?.level {
+    crate fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option<SymbolStr> {
+        match self.const_stability(tcx)?.level {
             StabilityLevel::Stable { since, .. } => Some(since.as_str()),
             StabilityLevel::Unstable { .. } => None,
         }
@@ -281,7 +285,7 @@ impl Item {
     }
 
     crate fn is_default(&self) -> bool {
-        match self.kind {
+        match *self.kind {
             ItemKind::MethodItem(_, Some(defaultness)) => {
                 defaultness.has_value() && !defaultness.is_final()
             }
@@ -299,7 +303,7 @@ impl Item {
 
 #[derive(Clone, Debug)]
 crate enum ItemKind {
-    ExternCrateItem(String, Option<String>),
+    ExternCrateItem(Symbol, Option<Symbol>),
     ImportItem(Import),
     StructItem(Struct),
     UnionItem(Union),
@@ -333,7 +337,7 @@ crate enum ItemKind {
     AssocTypeItem(Vec<GenericBound>, Option<Type>),
     /// An item that has been stripped by a rustdoc pass
     StrippedItem(Box<ItemKind>),
-    KeywordItem(String),
+    KeywordItem(Symbol),
 }
 
 impl ItemKind {
@@ -379,15 +383,6 @@ impl ItemKind {
             _ => false,
         }
     }
-
-    crate fn as_assoc_kind(&self) -> Option<AssocKind> {
-        match *self {
-            ItemKind::AssocConstItem(..) => Some(AssocKind::Const),
-            ItemKind::AssocTypeItem(..) => Some(AssocKind::Type),
-            ItemKind::TyMethodItem(..) | ItemKind::MethodItem(..) => Some(AssocKind::Fn),
-            _ => None,
-        }
-    }
 }
 
 #[derive(Clone, Debug)]
@@ -444,12 +439,22 @@ impl AttributesExt for [ast::Attribute] {
 crate trait NestedAttributesExt {
     /// Returns `true` if the attribute list contains a specific `Word`
     fn has_word(self, word: Symbol) -> bool;
+    fn get_word_attr(self, word: Symbol) -> (Option<ast::NestedMetaItem>, bool);
 }
 
-impl<I: IntoIterator<Item = ast::NestedMetaItem>> NestedAttributesExt for I {
+impl<I: Iterator<Item = ast::NestedMetaItem> + IntoIterator<Item = ast::NestedMetaItem>>
+    NestedAttributesExt for I
+{
     fn has_word(self, word: Symbol) -> bool {
         self.into_iter().any(|attr| attr.is_word() && attr.has_name(word))
     }
+
+    fn get_word_attr(mut self, word: Symbol) -> (Option<ast::NestedMetaItem>, bool) {
+        match self.find(|attr| attr.is_word() && attr.has_name(word)) {
+            Some(a) => (Some(a), true),
+            None => (None, false),
+        }
+    }
 }
 
 /// A portion of documentation, extracted from a `#[doc]` attribute.
@@ -630,7 +635,7 @@ impl Attributes {
         let clean_attr = |(attr, parent_module): (&ast::Attribute, _)| {
             if let Some(value) = attr.doc_str() {
                 trace!("got doc_str={:?}", value);
-                let value = beautify_doc_string(value);
+                let value = beautify_doc_string(value).to_string();
                 let kind = if attr.is_doc_comment() {
                     DocFragmentKind::SugaredDoc
                 } else {
@@ -890,21 +895,19 @@ impl GenericBound {
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
-crate struct Lifetime(pub String);
+crate struct Lifetime(pub Symbol);
 
 impl Lifetime {
-    crate fn get_ref<'a>(&'a self) -> &'a str {
-        let Lifetime(ref s) = *self;
-        let s: &'a str = s;
-        s
+    crate fn get_ref(&self) -> SymbolStr {
+        self.0.as_str()
     }
 
     crate fn statik() -> Lifetime {
-        Lifetime("'static".to_string())
+        Lifetime(kw::StaticLifetime)
     }
 
     crate fn elided() -> Lifetime {
-        Lifetime("'_".to_string())
+        Lifetime(kw::UnderscoreLifetime)
     }
 }
 
@@ -962,7 +965,7 @@ impl GenericParamDefKind {
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate struct GenericParamDef {
-    crate name: String,
+    crate name: Symbol,
     crate kind: GenericParamDefKind,
 }
 
@@ -1050,7 +1053,7 @@ crate struct Arguments {
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate struct Argument {
     crate type_: Type,
-    crate name: String,
+    crate name: Symbol,
 }
 
 #[derive(Clone, PartialEq, Debug)]
@@ -1062,7 +1065,7 @@ crate enum SelfTy {
 
 impl Argument {
     crate fn to_self(&self) -> Option<SelfTy> {
-        if self.name != "self" {
+        if self.name != kw::SelfLower {
             return None;
         }
         if self.type_.is_self_type() {
@@ -1130,7 +1133,7 @@ crate enum Type {
     },
     /// For parameterized types, so the consumer of the JSON don't go
     /// looking for types which don't exist anywhere.
-    Generic(String),
+    Generic(Symbol),
     /// Primitives are the fixed-size numeric types (plus int/usize/float), char,
     /// arrays, slices, and tuples.
     Primitive(PrimitiveType),
@@ -1149,7 +1152,7 @@ crate enum Type {
 
     // `<Type as Trait>::Name`
     QPath {
-        name: String,
+        name: Symbol,
         self_type: Box<Type>,
         trait_: Box<Type>,
     },
@@ -1162,6 +1165,8 @@ crate enum Type {
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
+/// N.B. this has to be different from `hir::PrimTy` because it also includes types that aren't
+/// paths, like `Unit`.
 crate enum PrimitiveType {
     Isize,
     I8,
@@ -1248,7 +1253,7 @@ impl Type {
 
     crate fn is_self_type(&self) -> bool {
         match *self {
-            Generic(ref name) => name == "Self",
+            Generic(name) => name == kw::SelfUpper,
             _ => false,
         }
     }
@@ -1293,16 +1298,16 @@ impl Type {
         }
     }
 
-    crate fn projection(&self) -> Option<(&Type, DefId, &str)> {
+    crate fn projection(&self) -> Option<(&Type, DefId, Symbol)> {
         let (self_, trait_, name) = match self {
-            QPath { ref self_type, ref trait_, ref name } => (self_type, trait_, name),
+            QPath { ref self_type, ref trait_, name } => (self_type, trait_, name),
             _ => return None,
         };
         let trait_did = match **trait_ {
             ResolvedPath { did, .. } => did,
             _ => return None,
         };
-        Some((&self_, trait_did, name))
+        Some((&self_, trait_did, *name))
     }
 }
 
@@ -1501,6 +1506,37 @@ impl PrimitiveType {
     crate fn to_url_str(&self) -> &'static str {
         self.as_str()
     }
+
+    crate fn as_sym(&self) -> Symbol {
+        use PrimitiveType::*;
+        match self {
+            Isize => sym::isize,
+            I8 => sym::i8,
+            I16 => sym::i16,
+            I32 => sym::i32,
+            I64 => sym::i64,
+            I128 => sym::i128,
+            Usize => sym::usize,
+            U8 => sym::u8,
+            U16 => sym::u16,
+            U32 => sym::u32,
+            U64 => sym::u64,
+            U128 => sym::u128,
+            F32 => sym::f32,
+            F64 => sym::f64,
+            Str => sym::str,
+            Bool => sym::bool,
+            Char => sym::char,
+            Array => sym::array,
+            Slice => sym::slice,
+            Tuple => sym::tuple,
+            Unit => sym::unit,
+            RawPointer => sym::pointer,
+            Reference => sym::reference,
+            Fn => kw::Fn,
+            Never => sym::never,
+        }
+    }
 }
 
 impl From<ast::IntTy> for PrimitiveType {
@@ -1551,11 +1587,11 @@ impl From<hir::PrimTy> for PrimitiveType {
     }
 }
 
-#[derive(Clone, Debug)]
+#[derive(Copy, Clone, Debug)]
 crate enum Visibility {
     Public,
     Inherited,
-    Restricted(DefId, rustc_hir::definitions::DefPath),
+    Restricted(DefId),
 }
 
 impl Visibility {
@@ -1609,32 +1645,41 @@ crate enum VariantKind {
     Struct(VariantStruct),
 }
 
+/// Small wrapper around `rustc_span::Span` that adds helper methods and enforces calling `source_callsite`.
 #[derive(Clone, Debug)]
-crate struct Span {
-    crate filename: FileName,
-    crate cnum: CrateNum,
-    crate loline: usize,
-    crate locol: usize,
-    crate hiline: usize,
-    crate hicol: usize,
-    crate original: rustc_span::Span,
-}
+crate struct Span(rustc_span::Span);
 
 impl Span {
-    crate fn empty() -> Span {
-        Span {
-            filename: FileName::Anon(0),
-            cnum: LOCAL_CRATE,
-            loline: 0,
-            locol: 0,
-            hiline: 0,
-            hicol: 0,
-            original: rustc_span::DUMMY_SP,
-        }
+    crate fn from_rustc_span(sp: rustc_span::Span) -> Self {
+        // Get the macro invocation instead of the definition,
+        // in case the span is result of a macro expansion.
+        // (See rust-lang/rust#39726)
+        Self(sp.source_callsite())
+    }
+
+    crate fn dummy() -> Self {
+        Self(rustc_span::DUMMY_SP)
     }
 
     crate fn span(&self) -> rustc_span::Span {
-        self.original
+        self.0
+    }
+
+    crate fn filename(&self, sess: &Session) -> FileName {
+        sess.source_map().span_to_filename(self.0)
+    }
+
+    crate fn lo(&self, sess: &Session) -> Loc {
+        sess.source_map().lookup_char_pos(self.0.lo())
+    }
+
+    crate fn hi(&self, sess: &Session) -> Loc {
+        sess.source_map().lookup_char_pos(self.0.hi())
+    }
+
+    crate fn cnum(&self, sess: &Session) -> CrateNum {
+        // FIXME: is there a time when the lo and hi crate would be different?
+        self.lo(sess).file.cnum
     }
 }
 
@@ -1646,13 +1691,17 @@ crate struct Path {
 }
 
 impl Path {
-    crate fn last_name(&self) -> &str {
+    crate fn last(&self) -> Symbol {
+        self.segments.last().expect("segments were empty").name
+    }
+
+    crate fn last_name(&self) -> SymbolStr {
         self.segments.last().expect("segments were empty").name.as_str()
     }
 
     crate fn whole_name(&self) -> String {
         String::from(if self.global { "::" } else { "" })
-            + &self.segments.iter().map(|s| s.name.clone()).collect::<Vec<_>>().join("::")
+            + &self.segments.iter().map(|s| s.name.to_string()).collect::<Vec<_>>().join("::")
     }
 }
 
@@ -1671,7 +1720,7 @@ crate enum GenericArgs {
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate struct PathSegment {
-    crate name: String,
+    crate name: Symbol,
     crate args: GenericArgs,
 }
 
@@ -1731,7 +1780,7 @@ crate enum ImplPolarity {
 crate struct Impl {
     crate unsafety: hir::Unsafety,
     crate generics: Generics,
-    crate provided_trait_methods: FxHashSet<String>,
+    crate provided_trait_methods: FxHashSet<Symbol>,
     crate trait_: Option<Type>,
     crate for_: Type,
     crate items: Vec<Item>,
@@ -1748,7 +1797,7 @@ crate struct Import {
 }
 
 impl Import {
-    crate fn new_simple(name: String, source: ImportSource, should_be_displayed: bool) -> Self {
+    crate fn new_simple(name: Symbol, source: ImportSource, should_be_displayed: bool) -> Self {
         Self { kind: ImportKind::Simple(name), source, should_be_displayed }
     }
 
@@ -1760,7 +1809,7 @@ impl Import {
 #[derive(Clone, Debug)]
 crate enum ImportKind {
     // use source as str;
-    Simple(String),
+    Simple(Symbol),
     // use source::*;
     Glob,
 }
@@ -1774,27 +1823,20 @@ crate struct ImportSource {
 #[derive(Clone, Debug)]
 crate struct Macro {
     crate source: String,
-    crate imported_from: Option<String>,
+    crate imported_from: Option<Symbol>,
 }
 
 #[derive(Clone, Debug)]
 crate struct ProcMacro {
     crate kind: MacroKind,
-    crate helpers: Vec<String>,
-}
-
-#[derive(Clone, Debug)]
-crate struct Deprecation {
-    crate since: Option<String>,
-    crate note: Option<String>,
-    crate is_since_rustc_version: bool,
+    crate helpers: Vec<Symbol>,
 }
 
 /// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
 /// `A: Send + Sync` in `Foo<A: Send + Sync>`).
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate struct TypeBinding {
-    crate name: String,
+    crate name: Symbol,
     crate kind: TypeBindingKind,
 }
 
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 1b22d26f49b..d4482d6fa90 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -8,14 +8,13 @@ use crate::clean::{
 };
 use crate::core::DocContext;
 
-use itertools::Itertools;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_middle::mir::interpret::ConstValue;
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
-use rustc_middle::ty::{self, DefIdTree, Ty};
+use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt};
 use rustc_span::symbol::{kw, sym, Symbol};
 use std::mem;
 
@@ -43,7 +42,7 @@ crate fn krate(mut cx: &mut DocContext<'_>) -> Crate {
     let mut module = module.clean(cx);
     let mut masked_crates = FxHashSet::default();
 
-    match module.kind {
+    match *module.kind {
         ItemKind::ModuleItem(ref module) => {
             for it in &module.items {
                 // `compiler_builtins` should be masked too, but we can't apply
@@ -61,20 +60,20 @@ crate fn krate(mut cx: &mut DocContext<'_>) -> Crate {
 
     let ExternalCrate { name, src, primitives, keywords, .. } = LOCAL_CRATE.clean(cx);
     {
-        let m = match module.kind {
+        let m = match *module.kind {
             ItemKind::ModuleItem(ref mut m) => m,
             _ => unreachable!(),
         };
         m.items.extend(primitives.iter().map(|&(def_id, prim)| {
             Item::from_def_id_and_parts(
                 def_id,
-                Some(prim.to_url_str().to_owned()),
+                Some(prim.as_sym()),
                 ItemKind::PrimitiveItem(prim),
                 cx,
             )
         }));
         m.items.extend(keywords.into_iter().map(|(def_id, kw)| {
-            Item::from_def_id_and_parts(def_id, Some(kw.clone()), ItemKind::KeywordItem(kw), cx)
+            Item::from_def_id_and_parts(def_id, Some(kw), ItemKind::KeywordItem(kw), cx)
         }));
     }
 
@@ -104,7 +103,9 @@ fn external_generic_args(
         .iter()
         .filter_map(|kind| match kind.unpack() {
             GenericArgKind::Lifetime(lt) => match lt {
-                ty::ReLateBound(_, ty::BrAnon(_)) => Some(GenericArg::Lifetime(Lifetime::elided())),
+                ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrAnon(_) }) => {
+                    Some(GenericArg::Lifetime(Lifetime::elided()))
+                }
                 _ => lt.clean(cx).map(GenericArg::Lifetime),
             },
             GenericArgKind::Type(_) if skip_self => {
@@ -153,7 +154,7 @@ pub(super) fn external_path(
         global: false,
         res: Res::Err,
         segments: vec![PathSegment {
-            name: name.to_string(),
+            name,
             args: external_generic_args(cx, trait_did, has_self, bindings, substs),
         }],
     }
@@ -170,13 +171,13 @@ crate fn get_real_types(
     cx: &DocContext<'_>,
     recurse: i32,
 ) -> FxHashSet<(Type, TypeKind)> {
-    let arg_s = arg.print().to_string();
     let mut res = FxHashSet::default();
     if recurse >= 10 {
         // FIXME: remove this whole recurse thing when the recursion bug is fixed
         return res;
     }
     if arg.is_full_generic() {
+        let arg_s = Symbol::intern(&arg.print().to_string());
         if let Some(where_pred) = generics.where_predicates.iter().find(|g| match g {
             &WherePredicate::BoundPredicate { ref ty, .. } => ty.def_id() == arg.def_id(),
             _ => false,
@@ -305,7 +306,7 @@ crate fn strip_path(path: &Path) -> Path {
         .segments
         .iter()
         .map(|s| PathSegment {
-            name: s.name.clone(),
+            name: s.name,
             args: GenericArgs::AngleBracketed { args: vec![], bindings: vec![] },
         })
         .collect();
@@ -336,7 +337,7 @@ crate fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut
     let tcx = cx.tcx;
 
     for item in items {
-        let target = match item.kind {
+        let target = match *item.kind {
             ItemKind::TypedefItem(ref t, true) => &t.type_,
             _ => continue,
         };
@@ -375,13 +376,13 @@ impl ToSource for rustc_span::Span {
     }
 }
 
-crate fn name_from_pat(p: &hir::Pat<'_>) -> String {
+crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
     use rustc_hir::*;
     debug!("trying to get a name from pattern: {:?}", p);
 
-    match p.kind {
-        PatKind::Wild => "_".to_string(),
-        PatKind::Binding(_, _, ident, _) => ident.to_string(),
+    Symbol::intern(&match p.kind {
+        PatKind::Wild => return kw::Underscore,
+        PatKind::Binding(_, _, ident, _) => return ident.name,
         PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p),
         PatKind::Struct(ref name, ref fields, etc) => format!(
             "{} {{ {}{} }}",
@@ -393,32 +394,37 @@ crate fn name_from_pat(p: &hir::Pat<'_>) -> String {
                 .join(", "),
             if etc { ", .." } else { "" }
         ),
-        PatKind::Or(ref pats) => {
-            pats.iter().map(|p| name_from_pat(&**p)).collect::<Vec<String>>().join(" | ")
-        }
+        PatKind::Or(ref pats) => pats
+            .iter()
+            .map(|p| name_from_pat(&**p).to_string())
+            .collect::<Vec<String>>()
+            .join(" | "),
         PatKind::Tuple(ref elts, _) => format!(
             "({})",
-            elts.iter().map(|p| name_from_pat(&**p)).collect::<Vec<String>>().join(", ")
+            elts.iter()
+                .map(|p| name_from_pat(&**p).to_string())
+                .collect::<Vec<String>>()
+                .join(", ")
         ),
-        PatKind::Box(ref p) => name_from_pat(&**p),
-        PatKind::Ref(ref p, _) => name_from_pat(&**p),
+        PatKind::Box(ref p) => return name_from_pat(&**p),
+        PatKind::Ref(ref p, _) => return name_from_pat(&**p),
         PatKind::Lit(..) => {
             warn!(
                 "tried to get argument name from PatKind::Lit, which is silly in function arguments"
             );
-            "()".to_string()
+            return Symbol::intern("()");
         }
         PatKind::Range(..) => panic!(
             "tried to get argument name from PatKind::Range, \
              which is not allowed in function arguments"
         ),
         PatKind::Slice(ref begin, ref mid, ref end) => {
-            let begin = begin.iter().map(|p| name_from_pat(&**p));
+            let begin = begin.iter().map(|p| name_from_pat(&**p).to_string());
             let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(&**p))).into_iter();
-            let end = end.iter().map(|p| name_from_pat(&**p));
+            let end = end.iter().map(|p| name_from_pat(&**p).to_string());
             format!("[{}]", begin.chain(mid).chain(end).collect::<Vec<_>>().join(", "))
         }
-    }
+    })
 }
 
 crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
@@ -534,10 +540,10 @@ crate fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type {
     let is_generic = match path.res {
         Res::PrimTy(p) => return Primitive(PrimitiveType::from(p)),
         Res::SelfTy(..) if path.segments.len() == 1 => {
-            return Generic(kw::SelfUpper.to_string());
+            return Generic(kw::SelfUpper);
         }
         Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => {
-            return Generic(format!("{:#}", path.print()));
+            return Generic(Symbol::intern(&format!("{:#}", path.print())));
         }
         Res::SelfTy(..) | Res::Def(DefKind::TyParam | DefKind::AssocTy, _) => true,
         _ => false,
@@ -551,10 +557,13 @@ crate fn get_auto_trait_and_blanket_impls(
     ty: Ty<'tcx>,
     param_env_def_id: DefId,
 ) -> impl Iterator<Item = Item> {
-    AutoTraitFinder::new(cx)
-        .get_auto_trait_impls(ty, param_env_def_id)
-        .into_iter()
-        .chain(BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id))
+    let auto_impls = cx.sess().time("get_auto_trait_impls", || {
+        AutoTraitFinder::new(cx).get_auto_trait_impls(ty, param_env_def_id)
+    });
+    let blanket_impls = cx.sess().time("get_blanket_impls", || {
+        BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id)
+    });
+    auto_impls.into_iter().chain(blanket_impls)
 }
 
 crate fn register_res(cx: &DocContext<'_>, res: Res) -> DefId {
@@ -614,3 +623,24 @@ where
     *cx.impl_trait_bounds.borrow_mut() = old_bounds;
     r
 }
+
+/// Find the nearest parent module of a [`DefId`].
+///
+/// **Panics if the item it belongs to [is fake][Item::is_fake].**
+crate fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
+    if def_id.is_top_level_module() {
+        // The crate root has no parent. Use it as the root instead.
+        Some(def_id)
+    } else {
+        let mut current = def_id;
+        // The immediate parent might not always be a module.
+        // Find the first parent which is.
+        while let Some(parent) = tcx.parent(current) {
+            if tcx.def_kind(parent) == DefKind::Mod {
+                return Some(parent);
+            }
+            current = parent;
+        }
+        None
+    }
+}
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index e60970af0d3..2d58614b139 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -397,12 +397,9 @@ impl Options {
             matches
                 .opt_strs("default-setting")
                 .iter()
-                .map(|s| {
-                    let mut kv = s.splitn(2, '=');
-                    // never panics because `splitn` always returns at least one element
-                    let k = kv.next().unwrap().to_string();
-                    let v = kv.next().unwrap_or("true").to_string();
-                    (k, v)
+                .map(|s| match s.split_once('=') {
+                    None => (s.clone(), "true".to_string()),
+                    Some((k, v)) => (k.to_string(), v.to_string()),
                 })
                 .collect(),
         ];
@@ -707,11 +704,9 @@ fn parse_extern_html_roots(
 ) -> Result<BTreeMap<String, String>, &'static str> {
     let mut externs = BTreeMap::new();
     for arg in &matches.opt_strs("extern-html-root-url") {
-        let mut parts = arg.splitn(2, '=');
-        let name = parts.next().ok_or("--extern-html-root-url must not be empty")?;
-        let url = parts.next().ok_or("--extern-html-root-url must be of the form name=url")?;
+        let (name, url) =
+            arg.split_once('=').ok_or("--extern-html-root-url must be of the form name=url")?;
         externs.insert(name.to_string(), url.to_string());
     }
-
     Ok(externs)
 }
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index b2eeaf584bf..7e85342ac7d 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -11,7 +11,7 @@ use rustc_hir::{
     intravisit::{self, NestedVisitorMap, Visitor},
     Path,
 };
-use rustc_interface::interface;
+use rustc_interface::{interface, Queries};
 use rustc_middle::hir::map::Map;
 use rustc_middle::middle::privacy::AccessLevels;
 use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
@@ -273,12 +273,9 @@ where
     (lint_opts, lint_caps)
 }
 
-crate fn run_core(
-    options: RustdocOptions,
-) -> (clean::Crate, RenderInfo, RenderOptions, Lrc<Session>) {
-    // Parse, resolve, and typecheck the given crate.
-
-    let RustdocOptions {
+/// Parse, resolve, and typecheck the given crate.
+crate fn create_config(
+    RustdocOptions {
         input,
         crate_name,
         proc_macro_crate,
@@ -294,21 +291,10 @@ crate fn run_core(
         lint_opts,
         describe_lints,
         lint_cap,
-        default_passes,
-        manual_passes,
         display_warnings,
-        render_options,
-        output_format,
         ..
-    } = options;
-
-    let extern_names: Vec<String> = externs
-        .iter()
-        .filter(|(_, entry)| entry.add_prelude)
-        .map(|(name, _)| name)
-        .cloned()
-        .collect();
-
+    }: RustdocOptions,
+) -> rustc_interface::Config {
     // Add the doc cfg into the doc build.
     cfgs.push("doc".to_string());
 
@@ -374,7 +360,7 @@ crate fn run_core(
         ..Options::default()
     };
 
-    let config = interface::Config {
+    interface::Config {
         opts: sessopts,
         crate_cfg: interface::parse_cfgspecs(cfgs),
         input,
@@ -417,68 +403,50 @@ crate fn run_core(
         }),
         make_codegen_backend: None,
         registry: rustc_driver::diagnostics_registry(),
-    };
-
-    interface::create_compiler_and_run(config, |compiler| {
-        compiler.enter(|queries| {
-            let sess = compiler.session();
-
-            // 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 = {
-                let parts = abort_on_err(queries.expansion(), sess).peek();
-                let resolver = parts.1.borrow();
-
-                // 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);
-                            resolver
-                                .resolve_str_path_error(
-                                    DUMMY_SP,
-                                    extern_name,
-                                    TypeNS,
-                                    LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(),
-                                )
-                                .unwrap_or_else(|()| {
-                                    panic!("Unable to resolve external crate {}", extern_name)
-                                });
-                        }
-                    });
-                });
+    }
+}
 
-                // Now we're good to clone the resolver because everything should be loaded
-                resolver.clone()
-            };
+crate fn create_resolver<'a>(
+    externs: config::Externs,
+    queries: &Queries<'a>,
+    sess: &Session,
+) -> Rc<RefCell<interface::BoxedResolver>> {
+    let extern_names: Vec<String> = externs
+        .iter()
+        .filter(|(_, entry)| entry.add_prelude)
+        .map(|(name, _)| name)
+        .cloned()
+        .collect();
 
-            if sess.has_errors() {
-                sess.fatal("Compilation failed, aborting rustdoc");
+    let parts = abort_on_err(queries.expansion(), sess).peek();
+    let resolver = parts.1.borrow();
+
+    // 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);
+                resolver
+                    .resolve_str_path_error(
+                        DUMMY_SP,
+                        extern_name,
+                        TypeNS,
+                        LocalDefId { local_def_index: CRATE_DEF_INDEX }.to_def_id(),
+                    )
+                    .unwrap_or_else(|()| {
+                        panic!("Unable to resolve external crate {}", extern_name)
+                    });
             }
+        });
+    });
 
-            let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take();
-
-            let (krate, render_info, opts) = sess.time("run_global_ctxt", || {
-                global_ctxt.enter(|tcx| {
-                    run_global_ctxt(
-                        tcx,
-                        resolver,
-                        default_passes,
-                        manual_passes,
-                        render_options,
-                        output_format,
-                    )
-                })
-            });
-            (krate, render_info, opts, Lrc::clone(sess))
-        })
-    })
+    // Now we're good to clone the resolver because everything should be loaded
+    resolver.clone()
 }
 
-fn run_global_ctxt(
+crate fn run_global_ctxt(
     tcx: TyCtxt<'_>,
     resolver: Rc<RefCell<interface::BoxedResolver>>,
     mut default_passes: passes::DefaultPassOption,
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 37fe13c32ce..02dd42ce0c1 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -247,9 +247,10 @@ fn run_test(
     edition: Edition,
     outdir: DirState,
     path: PathBuf,
+    test_id: &str,
 ) -> Result<(), TestFailure> {
     let (test, line_offset, supports_color) =
-        make_test(test, Some(cratename), as_test_harness, opts, edition);
+        make_test(test, Some(cratename), as_test_harness, opts, edition, Some(test_id));
 
     let output_file = outdir.path().join("rust_out");
 
@@ -387,6 +388,7 @@ crate fn make_test(
     dont_insert_main: bool,
     opts: &TestOptions,
     edition: Edition,
+    test_id: Option<&str>,
 ) -> (String, usize, bool) {
     let (crate_attrs, everything_else, crates) = partition_source(s);
     let everything_else = everything_else.trim();
@@ -542,16 +544,41 @@ crate fn make_test(
         prog.push_str(everything_else);
     } else {
         let returns_result = everything_else.trim_end().ends_with("(())");
+        // Give each doctest main function a unique name.
+        // This is for example needed for the tooling around `-Z instrument-coverage`.
+        let inner_fn_name = if let Some(test_id) = test_id {
+            format!("_doctest_main_{}", test_id)
+        } else {
+            "_inner".into()
+        };
+        let inner_attr = if test_id.is_some() { "#[allow(non_snake_case)] " } else { "" };
         let (main_pre, main_post) = if returns_result {
             (
-                "fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {",
-                "}\n_inner().unwrap() }",
+                format!(
+                    "fn main() {{ {}fn {}() -> Result<(), impl core::fmt::Debug> {{\n",
+                    inner_attr, inner_fn_name
+                ),
+                format!("\n}} {}().unwrap() }}", inner_fn_name),
+            )
+        } else if test_id.is_some() {
+            (
+                format!("fn main() {{ {}fn {}() {{\n", inner_attr, inner_fn_name),
+                format!("\n}} {}() }}", inner_fn_name),
             )
         } else {
-            ("fn main() {\n", "\n}")
+            ("fn main() {\n".into(), "\n}".into())
         };
-        prog.extend([main_pre, everything_else, main_post].iter().cloned());
+        // Note on newlines: We insert a line/newline *before*, and *after*
+        // the doctest and adjust the `line_offset` accordingly.
+        // In the case of `-Z instrument-coverage`, this means that the generated
+        // inner `main` function spans from the doctest opening codeblock to the
+        // closing one. For example
+        // /// ``` <- start of the inner main
+        // /// <- code under doctest
+        // /// ``` <- end of the inner main
         line_offset += 1;
+
+        prog.extend([&main_pre, everything_else, &main_post].iter().cloned());
     }
 
     debug!("final doctest:\n{}", prog);
@@ -749,28 +776,24 @@ impl Tester for Collector {
             _ => PathBuf::from(r"doctest.rs"),
         };
 
+        // For example `module/file.rs` would become `module_file_rs`
+        let file = filename
+            .to_string()
+            .chars()
+            .map(|c| if c.is_ascii_alphanumeric() { c } else { '_' })
+            .collect::<String>();
+        let test_id = format!(
+            "{file}_{line}_{number}",
+            file = file,
+            line = line,
+            number = {
+                // Increases the current test number, if this file already
+                // exists or it creates a new entry with a test number of 0.
+                self.visited_tests.entry((file.clone(), line)).and_modify(|v| *v += 1).or_insert(0)
+            },
+        );
         let outdir = if let Some(mut path) = options.persist_doctests.clone() {
-            // For example `module/file.rs` would become `module_file_rs`
-            let folder_name = filename
-                .to_string()
-                .chars()
-                .map(|c| if c == '\\' || c == '/' || c == '.' { '_' } else { c })
-                .collect::<String>();
-
-            path.push(format!(
-                "{krate}_{file}_{line}_{number}",
-                krate = cratename,
-                file = folder_name,
-                line = line,
-                number = {
-                    // Increases the current test number, if this file already
-                    // exists or it creates a new entry with a test number of 0.
-                    self.visited_tests
-                        .entry((folder_name.clone(), line))
-                        .and_modify(|v| *v += 1)
-                        .or_insert(0)
-                },
-            ));
+            path.push(&test_id);
 
             std::fs::create_dir_all(&path)
                 .expect("Couldn't create directory for doctest executables");
@@ -817,6 +840,7 @@ impl Tester for Collector {
                     edition,
                     outdir,
                     path,
+                    &test_id,
                 );
 
                 if let Err(err) = res {
diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs
index a024e9c72a4..465b2b1d69b 100644
--- a/src/librustdoc/doctest/tests.rs
+++ b/src/librustdoc/doctest/tests.rs
@@ -11,7 +11,7 @@ fn main() {
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -26,7 +26,7 @@ fn main() {
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -44,7 +44,7 @@ use asdf::qwop;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 3));
 }
 
@@ -61,7 +61,7 @@ use asdf::qwop;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -79,7 +79,7 @@ use std::*;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, Some("std"), false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, Some("std"), false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -98,7 +98,7 @@ use asdf::qwop;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -115,7 +115,7 @@ use asdf::qwop;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -134,7 +134,7 @@ use asdf::qwop;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 3));
 
     // Adding more will also bump the returned line offset.
@@ -147,7 +147,7 @@ use asdf::qwop;
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 4));
 }
 
@@ -164,7 +164,7 @@ fn main() {
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -180,7 +180,7 @@ fn main() {
     assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 1));
 }
 
@@ -196,7 +196,7 @@ fn main() {
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 2));
 }
 
@@ -210,7 +210,7 @@ assert_eq!(2+2, 4);";
 //Ceci n'est pas une `fn main`
 assert_eq!(2+2, 4);"
         .to_string();
-    let (output, len, _) = make_test(input, None, true, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, None, true, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 1));
 }
 
@@ -224,7 +224,7 @@ fn make_test_display_warnings() {
 assert_eq!(2+2, 4);
 }"
     .to_string();
-    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 1));
 }
 
@@ -242,7 +242,7 @@ assert_eq!(2+2, 4);
 }"
     .to_string();
 
-    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 2));
 
     let input = "extern crate hella_qwop;
@@ -256,7 +256,7 @@ assert_eq!(asdf::foo, 4);
 }"
     .to_string();
 
-    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 3));
 }
 
@@ -274,6 +274,41 @@ test_wrapper! {
 }"
     .to_string();
 
-    let (output, len, _) = make_test(input, Some("my_crate"), false, &opts, DEFAULT_EDITION);
+    let (output, len, _) = make_test(input, Some("my_crate"), false, &opts, DEFAULT_EDITION, None);
     assert_eq!((output, len), (expected, 1));
 }
+
+#[test]
+fn make_test_returns_result() {
+    // creates an inner function and unwraps it
+    let opts = TestOptions::default();
+    let input = "use std::io;
+let mut input = String::new();
+io::stdin().read_line(&mut input)?;
+Ok::<(), io:Error>(())";
+    let expected = "#![allow(unused)]
+fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {
+use std::io;
+let mut input = String::new();
+io::stdin().read_line(&mut input)?;
+Ok::<(), io:Error>(())
+} _inner().unwrap() }"
+        .to_string();
+    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
+    assert_eq!((output, len), (expected, 2));
+}
+
+#[test]
+fn make_test_named_wrapper() {
+    // creates an inner function with a specific name
+    let opts = TestOptions::default();
+    let input = "assert_eq!(2+2, 4);";
+    let expected = "#![allow(unused)]
+fn main() { #[allow(non_snake_case)] fn _doctest_main__some_unique_name() {
+assert_eq!(2+2, 4);
+} _doctest_main__some_unique_name() }"
+        .to_string();
+    let (output, len, _) =
+        make_test(input, None, false, &opts, DEFAULT_EDITION, Some("_some_unique_name"));
+    assert_eq!((output, len), (expected, 2));
+}
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index ee9a6981857..bc9f1cf8806 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -9,7 +9,6 @@ use rustc_hir as hir;
 
 crate struct Module<'hir> {
     crate name: Option<Symbol>,
-    crate attrs: &'hir [ast::Attribute],
     crate where_outer: Span,
     crate where_inner: Span,
     crate imports: Vec<Import<'hir>>,
@@ -23,13 +22,12 @@ crate struct Module<'hir> {
 }
 
 impl Module<'hir> {
-    crate fn new(name: Option<Symbol>, attrs: &'hir [ast::Attribute]) -> Module<'hir> {
+    crate fn new(name: Option<Symbol>) -> Module<'hir> {
         Module {
             name,
             id: hir::CRATE_HIR_ID,
             where_outer: rustc_span::DUMMY_SP,
             where_inner: rustc_span::DUMMY_SP,
-            attrs,
             imports: Vec::new(),
             mods: Vec::new(),
             items: Vec::new(),
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 285fabdc372..c39cc3ca397 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -3,12 +3,12 @@ use crate::clean::*;
 crate struct StripItem(pub Item);
 
 impl StripItem {
-    crate fn strip(self) -> Option<Item> {
+    crate fn strip(self) -> Item {
         match self.0 {
-            Item { kind: StrippedItem(..), .. } => Some(self.0),
+            Item { kind: box StrippedItem(..), .. } => self.0,
             mut i => {
-                i.kind = StrippedItem(box i.kind);
-                Some(i)
+                i.kind = box StrippedItem(i.kind);
+                i
             }
         }
     }
@@ -72,9 +72,9 @@ crate trait DocFolder: Sized {
 
     /// don't override!
     fn fold_item_recur(&mut self, mut item: Item) -> Item {
-        item.kind = match item.kind {
+        item.kind = box match *item.kind {
             StrippedItem(box i) => StrippedItem(box self.fold_inner_recur(i)),
-            _ => self.fold_inner_recur(item.kind),
+            _ => self.fold_inner_recur(*item.kind),
         };
         item
     }
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index e82bc540e95..899d61d8e43 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -8,6 +8,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
 use rustc_middle::middle::privacy::AccessLevels;
 use rustc_span::source_map::FileName;
+use rustc_span::Symbol;
 
 use crate::clean::{self, GetDefId};
 use crate::config::RenderInfo;
@@ -74,7 +75,7 @@ crate struct Cache {
     crate implementors: FxHashMap<DefId, Vec<Impl>>,
 
     /// Cache of where external crate documentation can be found.
-    crate extern_locations: FxHashMap<CrateNum, (String, PathBuf, ExternalLocation)>,
+    crate extern_locations: FxHashMap<CrateNum, (Symbol, PathBuf, ExternalLocation)>,
 
     /// Cache of where documentation for primitives can be found.
     crate primitive_locations: FxHashMap<clean::PrimitiveType, DefId>,
@@ -173,10 +174,10 @@ impl Cache {
                 },
                 _ => PathBuf::new(),
             };
-            let extern_url = extern_html_root_urls.get(&e.name).map(|u| &**u);
+            let extern_url = extern_html_root_urls.get(&*e.name.as_str()).map(|u| &**u);
             cache
                 .extern_locations
-                .insert(n, (e.name.clone(), src_root, extern_location(e, extern_url, &dst)));
+                .insert(n, (e.name, src_root, extern_location(e, extern_url, &dst)));
 
             let did = DefId { krate: n, index: CRATE_DEF_INDEX };
             cache.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module));
@@ -195,7 +196,7 @@ impl Cache {
             cache.primitive_locations.insert(prim, def_id);
         }
 
-        cache.stack.push(krate.name.clone());
+        cache.stack.push(krate.name.to_string());
         krate = cache.fold_crate(krate);
 
         for (trait_did, dids, impl_) in cache.orphan_trait_impls.drain(..) {
@@ -218,7 +219,7 @@ impl DocFolder for Cache {
 
         // If this is a stripped module,
         // we don't want it or its children in the search index.
-        let orig_stripped_mod = match item.kind {
+        let orig_stripped_mod = match *item.kind {
             clean::StrippedItem(box clean::ModuleItem(..)) => {
                 mem::replace(&mut self.stripped_mod, true)
             }
@@ -227,7 +228,7 @@ impl DocFolder for Cache {
 
         // If the impl is from a masked crate or references something from a
         // masked crate then remove it completely.
-        if let clean::ImplItem(ref i) = item.kind {
+        if let clean::ImplItem(ref i) = *item.kind {
             if self.masked_crates.contains(&item.def_id.krate)
                 || i.trait_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate))
                 || i.for_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate))
@@ -238,12 +239,12 @@ impl DocFolder for Cache {
 
         // Propagate a trait method's documentation to all implementors of the
         // trait.
-        if let clean::TraitItem(ref t) = item.kind {
+        if let clean::TraitItem(ref t) = *item.kind {
             self.traits.entry(item.def_id).or_insert_with(|| t.clone());
         }
 
         // Collect all the implementors of traits.
-        if let clean::ImplItem(ref i) = item.kind {
+        if let clean::ImplItem(ref i) = *item.kind {
             if let Some(did) = i.trait_.def_id() {
                 if i.blanket_impl.is_none() {
                     self.implementors
@@ -256,7 +257,7 @@ impl DocFolder for Cache {
 
         // Index this method for searching later on.
         if let Some(ref s) = item.name {
-            let (parent, is_inherent_impl_item) = match item.kind {
+            let (parent, is_inherent_impl_item) = match *item.kind {
                 clean::StrippedItem(..) => ((None, None), false),
                 clean::AssocConstItem(..) | clean::TypedefItem(_, true)
                     if self.parent_is_trait_impl =>
@@ -340,14 +341,14 @@ impl DocFolder for Cache {
 
         // Keep track of the fully qualified path for this item.
         let pushed = match item.name {
-            Some(ref n) if !n.is_empty() => {
+            Some(n) if !n.is_empty() => {
                 self.stack.push(n.to_string());
                 true
             }
             _ => false,
         };
 
-        match item.kind {
+        match *item.kind {
             clean::StructItem(..)
             | clean::EnumItem(..)
             | clean::TypedefItem(..)
@@ -386,7 +387,7 @@ impl DocFolder for Cache {
 
         // Maintain the parent stack
         let orig_parent_is_trait_impl = self.parent_is_trait_impl;
-        let parent_pushed = match item.kind {
+        let parent_pushed = match *item.kind {
             clean::TraitItem(..)
             | clean::EnumItem(..)
             | clean::ForeignTypeItem
@@ -424,38 +425,33 @@ impl DocFolder for Cache {
         // Once we've recursively found all the generics, hoard off all the
         // implementations elsewhere.
         let item = self.fold_item_recur(item);
-        let ret = if let clean::Item { kind: clean::ImplItem(_), .. } = item {
+        let ret = if let clean::Item { kind: box clean::ImplItem(ref i), .. } = item {
             // Figure out the id of this impl. This may map to a
             // primitive rather than always to a struct/enum.
             // Note: matching twice to restrict the lifetime of the `i` borrow.
             let mut dids = FxHashSet::default();
-            if let clean::Item { kind: clean::ImplItem(ref i), .. } = item {
-                match i.for_ {
-                    clean::ResolvedPath { did, .. }
-                    | clean::BorrowedRef { type_: box clean::ResolvedPath { did, .. }, .. } => {
-                        dids.insert(did);
-                    }
-                    ref t => {
-                        let did = t
-                            .primitive_type()
-                            .and_then(|t| self.primitive_locations.get(&t).cloned());
+            match i.for_ {
+                clean::ResolvedPath { did, .. }
+                | clean::BorrowedRef { type_: box clean::ResolvedPath { did, .. }, .. } => {
+                    dids.insert(did);
+                }
+                ref t => {
+                    let did =
+                        t.primitive_type().and_then(|t| self.primitive_locations.get(&t).cloned());
 
-                        if let Some(did) = did {
-                            dids.insert(did);
-                        }
+                    if let Some(did) = did {
+                        dids.insert(did);
                     }
                 }
+            }
 
-                if let Some(generics) = i.trait_.as_ref().and_then(|t| t.generics()) {
-                    for bound in generics {
-                        if let Some(did) = bound.def_id() {
-                            dids.insert(did);
-                        }
+            if let Some(generics) = i.trait_.as_ref().and_then(|t| t.generics()) {
+                for bound in generics {
+                    if let Some(did) = bound.def_id() {
+                        dids.insert(did);
                     }
                 }
-            } else {
-                unreachable!()
-            };
+            }
             let impl_item = Impl { impl_item: item };
             if impl_item.trait_did().map_or(true, |d| self.traits.contains_key(&d)) {
                 for did in dids {
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index af512e37460..ad51adf2fe3 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -60,7 +60,7 @@ impl Serialize for ItemType {
 
 impl<'a> From<&'a clean::Item> for ItemType {
     fn from(item: &'a clean::Item) -> ItemType {
-        let kind = match item.kind {
+        let kind = match *item.kind {
             clean::StrippedItem(box ref item) => item,
             ref kind => kind,
         };
diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs
index 55fd4948f45..58b9f5fbf0f 100644
--- a/src/librustdoc/formats/mod.rs
+++ b/src/librustdoc/formats/mod.rs
@@ -32,7 +32,7 @@ crate struct Impl {
 
 impl Impl {
     crate fn inner_impl(&self) -> &clean::Impl {
-        match self.impl_item.kind {
+        match *self.impl_item.kind {
             clean::ImplItem(ref impl_) => impl_,
             _ => panic!("non-impl item found in impl"),
         }
diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs
index d0fdc69cc19..e84a9853d9b 100644
--- a/src/librustdoc/formats/renderer.rs
+++ b/src/librustdoc/formats/renderer.rs
@@ -1,5 +1,6 @@
 use std::sync::Arc;
 
+use rustc_middle::ty;
 use rustc_span::edition::Edition;
 
 use crate::clean;
@@ -10,7 +11,7 @@ use crate::formats::cache::{Cache, CACHE_KEY};
 /// Allows for different backends to rustdoc to be used with the `run_format()` function. Each
 /// backend renderer has hooks for initialization, documenting an item, entering and exiting a
 /// module, and cleanup/finalizing output.
-crate trait FormatRenderer: Clone {
+crate trait FormatRenderer<'tcx>: Clone {
     /// Sets up any state required for the renderer. When this is called the cache has already been
     /// populated.
     fn init(
@@ -19,6 +20,7 @@ crate trait FormatRenderer: Clone {
         render_info: RenderInfo,
         edition: Edition,
         cache: &mut Cache,
+        tcx: ty::TyCtxt<'tcx>,
     ) -> Result<(Self, clean::Crate), Error>;
 
     /// Renders a single non-module item. This means no recursive sub-item rendering is required.
@@ -43,12 +45,13 @@ crate trait FormatRenderer: Clone {
 }
 
 /// Main method for rendering a crate.
-crate fn run_format<T: FormatRenderer>(
+crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
     krate: clean::Crate,
     options: RenderOptions,
     render_info: RenderInfo,
     diag: &rustc_errors::Handler,
     edition: Edition,
+    tcx: ty::TyCtxt<'tcx>,
 ) -> Result<(), Error> {
     let (krate, mut cache) = Cache::from_krate(
         render_info.clone(),
@@ -59,7 +62,7 @@ crate fn run_format<T: FormatRenderer>(
     );
 
     let (mut format_renderer, mut krate) =
-        T::init(krate, options, render_info, edition, &mut cache)?;
+        T::init(krate, options, render_info, edition, &mut cache, tcx)?;
 
     let cache = Arc::new(cache);
     // Freeze the cache now that the index has been built. Put an Arc into TLS for future
@@ -71,7 +74,7 @@ crate fn run_format<T: FormatRenderer>(
         None => return Ok(()),
     };
 
-    item.name = Some(krate.name.clone());
+    item.name = Some(krate.name);
 
     // Render the crate documentation
     let mut work = vec![(format_renderer.clone(), item)];
@@ -86,7 +89,7 @@ crate fn run_format<T: FormatRenderer>(
             }
 
             cx.mod_item_in(&item, &name, &cache)?;
-            let module = match item.kind {
+            let module = match *item.kind {
                 clean::StrippedItem(box clean::ModuleItem(m)) | clean::ModuleItem(m) => m,
                 _ => unreachable!(),
             };
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 536c2e08fde..9b2fb8582f5 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -11,10 +11,11 @@ use std::fmt;
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
 use rustc_target::spec::abi::Abi;
 
-use crate::clean::{self, PrimitiveType};
+use crate::clean::{self, utils::find_nearest_parent_module, PrimitiveType};
 use crate::formats::cache::cache;
 use crate::formats::item_type::ItemType;
 use crate::html::escape::Escape;
@@ -172,7 +173,7 @@ impl clean::GenericParamDef {
         display_fn(move |f| match self.kind {
             clean::GenericParamDefKind::Lifetime => write!(f, "{}", self.name),
             clean::GenericParamDefKind::Type { ref bounds, ref default, .. } => {
-                f.write_str(&self.name)?;
+                f.write_str(&*self.name.as_str())?;
 
                 if !bounds.is_empty() {
                     if f.alternate() {
@@ -193,13 +194,10 @@ impl clean::GenericParamDef {
                 Ok(())
             }
             clean::GenericParamDefKind::Const { ref ty, .. } => {
-                f.write_str("const ")?;
-                f.write_str(&self.name)?;
-
                 if f.alternate() {
-                    write!(f, ": {:#}", ty.print())
+                    write!(f, "const {}: {:#}", self.name, ty.print())
                 } else {
-                    write!(f, ":&nbsp;{}", ty.print())
+                    write!(f, "const {}:&nbsp;{}", self.name, ty.print())
                 }
             }
         })
@@ -311,7 +309,7 @@ impl<'a> fmt::Display for WhereClause<'a> {
 }
 
 impl clean::Lifetime {
-    crate fn print(&self) -> &str {
+    crate fn print(&self) -> impl fmt::Display + '_ {
         self.get_ref()
     }
 }
@@ -448,11 +446,10 @@ impl clean::GenericArgs {
 impl clean::PathSegment {
     crate fn print(&self) -> impl fmt::Display + '_ {
         display_fn(move |f| {
-            f.write_str(&self.name)?;
             if f.alternate() {
-                write!(f, "{:#}", self.args.print())
+                write!(f, "{}{:#}", self.name, self.args.print())
             } else {
-                write!(f, "{}", self.args.print())
+                write!(f, "{}{}", self.name, self.args.print())
             }
         })
     }
@@ -547,7 +544,7 @@ fn resolved_path(
                 last.name.to_string()
             }
         } else {
-            anchor(did, &last.name).to_string()
+            anchor(did, &*last.name.as_str()).to_string()
         };
         write!(w, "{}{}", path, last.args.print())?;
     }
@@ -638,7 +635,7 @@ crate fn anchor(did: DefId, text: &str) -> impl fmt::Display + '_ {
 
 fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) -> fmt::Result {
     match *t {
-        clean::Generic(ref name) => f.write_str(name),
+        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 ")?;
@@ -1088,32 +1085,54 @@ impl Function<'_> {
 }
 
 impl clean::Visibility {
-    crate fn print_with_space(&self) -> impl fmt::Display + '_ {
+    crate fn print_with_space<'tcx>(
+        self,
+        tcx: TyCtxt<'tcx>,
+        item_did: DefId,
+    ) -> impl fmt::Display + 'tcx {
         use rustc_span::symbol::kw;
 
-        display_fn(move |f| match *self {
+        display_fn(move |f| match self {
             clean::Public => f.write_str("pub "),
             clean::Inherited => Ok(()),
-            // If this is `pub(crate)`, `path` will be empty.
-            clean::Visibility::Restricted(did, _) if did.index == CRATE_DEF_INDEX => {
-                write!(f, "pub(crate) ")
-            }
-            clean::Visibility::Restricted(did, ref path) => {
-                f.write_str("pub(")?;
-                debug!("path={:?}", path);
-                let first_name =
-                    path.data[0].data.get_opt_name().expect("modules are always named");
-                if path.data.len() != 1 || (first_name != kw::SelfLower && first_name != kw::Super)
+
+            clean::Visibility::Restricted(vis_did) => {
+                // FIXME(camelid): This may not work correctly if `item_did` is a module.
+                //                 However, rustdoc currently never displays a module's
+                //                 visibility, so it shouldn't matter.
+                let parent_module = find_nearest_parent_module(tcx, item_did);
+
+                if vis_did.index == CRATE_DEF_INDEX {
+                    write!(f, "pub(crate) ")
+                } else if parent_module == Some(vis_did) {
+                    // `pub(in foo)` where `foo` is the parent module
+                    // is the same as no visibility modifier
+                    Ok(())
+                } else if parent_module
+                    .map(|parent| find_nearest_parent_module(tcx, parent))
+                    .flatten()
+                    == Some(vis_did)
                 {
-                    f.write_str("in ")?;
-                }
-                // modified from `resolved_path()` to work with `DefPathData`
-                let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
-                for seg in &path.data[..path.data.len() - 1] {
-                    write!(f, "{}::", seg.data.get_opt_name().unwrap())?;
+                    write!(f, "pub(super) ")
+                } else {
+                    f.write_str("pub(")?;
+                    let path = tcx.def_path(vis_did);
+                    debug!("path={:?}", path);
+                    let first_name =
+                        path.data[0].data.get_opt_name().expect("modules are always named");
+                    if path.data.len() != 1
+                        || (first_name != kw::SelfLower && first_name != kw::Super)
+                    {
+                        f.write_str("in ")?;
+                    }
+                    // modified from `resolved_path()` to work with `DefPathData`
+                    let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
+                    for seg in &path.data[..path.data.len() - 1] {
+                        write!(f, "{}::", seg.data.get_opt_name().unwrap())?;
+                    }
+                    let path = anchor(vis_did, &last_name.as_str()).to_string();
+                    write!(f, "{}) ", path)
                 }
-                let path = anchor(did, &last_name.as_str()).to_string();
-                write!(f, "{}) ", path)
             }
         })
     }
@@ -1162,11 +1181,11 @@ impl PrintWithSpace for hir::Mutability {
 impl clean::Import {
     crate fn print(&self) -> impl fmt::Display + '_ {
         display_fn(move |f| match self.kind {
-            clean::ImportKind::Simple(ref name) => {
-                if *name == self.source.path.last_name() {
+            clean::ImportKind::Simple(name) => {
+                if name == self.source.path.last() {
                     write!(f, "use {};", self.source.print())
                 } else {
-                    write!(f, "use {} as {};", self.source.print(), *name)
+                    write!(f, "use {} as {};", self.source.print(), name)
                 }
             }
             clean::ImportKind::Glob => {
@@ -1190,7 +1209,7 @@ impl clean::ImportSource {
                 }
                 let name = self.path.last_name();
                 if let hir::def::Res::PrimTy(p) = self.path.res {
-                    primitive_link(f, PrimitiveType::from(p), name)?;
+                    primitive_link(f, PrimitiveType::from(p), &*name)?;
                 } else {
                     write!(f, "{}", name)?;
                 }
@@ -1203,7 +1222,7 @@ impl clean::ImportSource {
 impl clean::TypeBinding {
     crate fn print(&self) -> impl fmt::Display + '_ {
         display_fn(move |f| {
-            f.write_str(&self.name)?;
+            f.write_str(&*self.name.as_str())?;
             match self.kind {
                 clean::TypeBindingKind::Equality { ref ty } => {
                     if f.alternate() {
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 1cbfbf50dd7..d21998bb8cf 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -11,7 +11,8 @@ use std::fmt::{Display, Write};
 use std::iter::Peekable;
 
 use rustc_lexer::{LiteralKind, TokenKind};
-use rustc_span::symbol::Ident;
+use rustc_span::edition::Edition;
+use rustc_span::symbol::Symbol;
 use rustc_span::with_default_session_globals;
 
 /// Highlights `src`, returning the HTML output.
@@ -19,22 +20,27 @@ crate fn render_with_highlighting(
     src: String,
     class: Option<&str>,
     playground_button: Option<&str>,
-    tooltip: Option<(&str, &str)>,
+    tooltip: Option<(Option<Edition>, &str)>,
+    edition: Edition,
 ) -> String {
     debug!("highlighting: ================\n{}\n==============", src);
     let mut out = String::with_capacity(src.len());
-    if let Some((tooltip, class)) = tooltip {
+    if let Some((edition_info, class)) = tooltip {
         write!(
             out,
-            "<div class='information'><div class='tooltip {}'>ⓘ<span \
-                  class='tooltiptext'>{}</span></div></div>",
-            class, tooltip
+            "<div class='information'><div class='tooltip {}'{}>ⓘ</div></div>",
+            class,
+            if let Some(edition_info) = edition_info {
+                format!(" data-edition=\"{}\"", edition_info)
+            } else {
+                String::new()
+            },
         )
         .unwrap();
     }
 
     write_header(&mut out, class);
-    write_code(&mut out, &src);
+    write_code(&mut out, &src, edition);
     write_footer(&mut out, playground_button);
 
     out
@@ -45,10 +51,10 @@ fn write_header(out: &mut String, class: Option<&str>) {
         .unwrap()
 }
 
-fn write_code(out: &mut String, src: &str) {
+fn write_code(out: &mut String, src: &str, edition: Edition) {
     // This replace allows to fix how the code source with DOS backline characters is displayed.
     let src = src.replace("\r\n", "\n");
-    Classifier::new(&src).highlight(&mut |highlight| {
+    Classifier::new(&src, edition).highlight(&mut |highlight| {
         match highlight {
             Highlight::Token { text, class } => string(out, Escape(text), class),
             Highlight::EnterSpan { class } => enter_span(out, class),
@@ -139,12 +145,19 @@ struct Classifier<'a> {
     in_attribute: bool,
     in_macro: bool,
     in_macro_nonterminal: bool,
+    edition: Edition,
 }
 
 impl<'a> Classifier<'a> {
-    fn new(src: &str) -> Classifier<'_> {
+    fn new(src: &str, edition: Edition) -> Classifier<'_> {
         let tokens = TokenIter { src }.peekable();
-        Classifier { tokens, in_attribute: false, in_macro: false, in_macro_nonterminal: false }
+        Classifier {
+            tokens,
+            in_attribute: false,
+            in_macro: false,
+            in_macro_nonterminal: false,
+            edition,
+        }
     }
 
     /// Exhausts the `Classifier` writing the output into `sink`.
@@ -296,7 +309,7 @@ impl<'a> Classifier<'a> {
                 "Option" | "Result" => Class::PreludeTy,
                 "Some" | "None" | "Ok" | "Err" => Class::PreludeVal,
                 // Keywords are also included in the identifier set.
-                _ if Ident::from_str(text).is_reserved() => Class::KeyWord,
+                _ if Symbol::intern(text).is_reserved(|| self.edition) => Class::KeyWord,
                 _ if self.in_macro_nonterminal => {
                     self.in_macro_nonterminal = false;
                     Class::MacroNonTerminal
diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs
index f57f52d6f08..f97c8a7ab71 100644
--- a/src/librustdoc/html/highlight/tests.rs
+++ b/src/librustdoc/html/highlight/tests.rs
@@ -1,5 +1,6 @@
 use super::write_code;
 use expect_test::expect_file;
+use rustc_span::edition::Edition;
 
 const STYLE: &str = r#"
 <style>
@@ -18,7 +19,7 @@ fn test_html_highlighting() {
     let src = include_str!("fixtures/sample.rs");
     let html = {
         let mut out = String::new();
-        write_code(&mut out, src);
+        write_code(&mut out, src, Edition::Edition2018);
         format!("{}<pre><code>{}</code></pre>\n", STYLE, out)
     };
     expect_file!["fixtures/sample.html"].assert_eq(&html);
@@ -30,6 +31,6 @@ fn test_dos_backline() {
     println!(\"foo\");\r\n\
 }\r\n";
     let mut html = String::new();
-    write_code(&mut html, src);
+    write_code(&mut html, src, Edition::Edition2018);
     expect_file!["fixtures/dos_line.html"].assert_eq(&html);
 }
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index e8039942f4f..b5169b05997 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -98,7 +98,7 @@ crate fn render<T: Print, S: Print>(
                            placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
                            type=\"search\">\
                 </div>\
-                <span class=\"help-button\">?</span>
+                <button type=\"button\" class=\"help-button\">?</button>
                 <a id=\"settings-menu\" href=\"{root_path}settings.html\">\
                     <img src=\"{static_root_path}wheel{suffix}.svg\" \
                          width=\"18\" \
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index bdbb90837c7..20cf48915c3 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -139,9 +139,9 @@ fn map_line(s: &str) -> Line<'_> {
     let trimmed = s.trim();
     if trimmed.starts_with("##") {
         Line::Shown(Cow::Owned(s.replacen("##", "#", 1)))
-    } else if trimmed.starts_with("# ") {
+    } else if let Some(stripped) = trimmed.strip_prefix("# ") {
         // # text
-        Line::Hidden(&trimmed[2..])
+        Line::Hidden(&stripped)
     } else if trimmed == "#" {
         // We cannot handle '#text' because it could be #[attr].
         Line::Hidden("")
@@ -204,7 +204,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
                 CodeBlockKind::Fenced(ref lang) => {
                     LangString::parse_without_check(&lang, self.check_error_codes, false)
                 }
-                CodeBlockKind::Indented => LangString::all_false(),
+                CodeBlockKind::Indented => Default::default(),
             };
             if !parse_result.rust {
                 return Some(Event::Start(Tag::CodeBlock(kind)));
@@ -248,7 +248,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
                 .join("\n");
             let krate = krate.as_ref().map(|s| &**s);
             let (test, _, _) =
-                doctest::make_test(&test, krate, false, &Default::default(), edition);
+                doctest::make_test(&test, krate, false, &Default::default(), edition, None);
             let channel = if test.contains("#![feature(") { "&amp;version=nightly" } else { "" };
 
             let edition_string = format!("&amp;edition={}", edition);
@@ -284,60 +284,28 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
         });
 
         let tooltip = if ignore != Ignore::None {
-            Some(("This example is not tested".to_owned(), "ignore"))
+            Some((None, "ignore"))
         } else if compile_fail {
-            Some(("This example deliberately fails to compile".to_owned(), "compile_fail"))
+            Some((None, "compile_fail"))
         } else if should_panic {
-            Some(("This example panics".to_owned(), "should_panic"))
+            Some((None, "should_panic"))
         } else if explicit_edition {
-            Some((format!("This code runs with edition {}", edition), "edition"))
+            Some((Some(edition), "edition"))
         } else {
             None
         };
 
-        if let Some((s1, s2)) = tooltip {
-            s.push_str(&highlight::render_with_highlighting(
-                text,
-                Some(&format!(
-                    "rust-example-rendered{}",
-                    if ignore != Ignore::None {
-                        " ignore"
-                    } else if compile_fail {
-                        " compile_fail"
-                    } else if should_panic {
-                        " should_panic"
-                    } else if explicit_edition {
-                        " edition "
-                    } else {
-                        ""
-                    }
-                )),
-                playground_button.as_deref(),
-                Some((s1.as_str(), s2)),
-            ));
-            Some(Event::Html(s.into()))
-        } else {
-            s.push_str(&highlight::render_with_highlighting(
-                text,
-                Some(&format!(
-                    "rust-example-rendered{}",
-                    if ignore != Ignore::None {
-                        " ignore"
-                    } else if compile_fail {
-                        " compile_fail"
-                    } else if should_panic {
-                        " should_panic"
-                    } else if explicit_edition {
-                        " edition "
-                    } else {
-                        ""
-                    }
-                )),
-                playground_button.as_deref(),
-                None,
-            ));
-            Some(Event::Html(s.into()))
-        }
+        s.push_str(&highlight::render_with_highlighting(
+            text,
+            Some(&format!(
+                "rust-example-rendered{}",
+                if let Some((_, class)) = tooltip { format!(" {}", class) } else { String::new() }
+            )),
+            playground_button.as_deref(),
+            tooltip,
+            edition,
+        ));
+        Some(Event::Html(s.into()))
     }
 }
 
@@ -447,14 +415,14 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
 }
 
 /// Make headings links with anchor IDs and build up TOC.
-struct HeadingLinks<'a, 'b, 'ids, I: Iterator<Item = Event<'a>>> {
+struct HeadingLinks<'a, 'b, 'ids, I> {
     inner: I,
     toc: Option<&'b mut TocBuilder>,
     buf: VecDeque<Event<'a>>,
     id_map: &'ids mut IdMap,
 }
 
-impl<'a, 'b, 'ids, I: Iterator<Item = Event<'a>>> HeadingLinks<'a, 'b, 'ids, I> {
+impl<'a, 'b, 'ids, I> HeadingLinks<'a, 'b, 'ids, I> {
     fn new(iter: I, toc: Option<&'b mut TocBuilder>, ids: &'ids mut IdMap) -> Self {
         HeadingLinks { inner: iter, toc, buf: VecDeque::new(), id_map: ids }
     }
@@ -575,15 +543,16 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
 
 /// Moves all footnote definitions to the end and add back links to the
 /// references.
-struct Footnotes<'a, I: Iterator<Item = Event<'a>>> {
+struct Footnotes<'a, I> {
     inner: I,
     footnotes: FxHashMap<String, (Vec<Event<'a>>, u16)>,
 }
 
-impl<'a, I: Iterator<Item = Event<'a>>> Footnotes<'a, I> {
+impl<'a, I> Footnotes<'a, I> {
     fn new(iter: I) -> Self {
         Footnotes { inner: iter, footnotes: FxHashMap::default() }
     }
+
     fn get_entry(&mut self, key: &str) -> &mut (Vec<Event<'a>>, u16) {
         let new_id = self.footnotes.keys().count() + 1;
         let key = key.to_owned();
@@ -665,7 +634,7 @@ crate fn find_testable_code<T: doctest::Tester>(
                 let block_info = match kind {
                     CodeBlockKind::Fenced(ref lang) => {
                         if lang.is_empty() {
-                            LangString::all_false()
+                            Default::default()
                         } else {
                             LangString::parse(
                                 lang,
@@ -675,7 +644,7 @@ crate fn find_testable_code<T: doctest::Tester>(
                             )
                         }
                     }
-                    CodeBlockKind::Indented => LangString::all_false(),
+                    CodeBlockKind::Indented => Default::default(),
                 };
                 if !block_info.rust {
                     continue;
@@ -778,14 +747,14 @@ crate enum Ignore {
     Some(Vec<String>),
 }
 
-impl LangString {
-    fn all_false() -> LangString {
-        LangString {
+impl Default for LangString {
+    fn default() -> Self {
+        Self {
             original: String::new(),
             should_panic: false,
             no_run: false,
             ignore: Ignore::None,
-            rust: true, // NB This used to be `notrust = false`
+            rust: true,
             test_harness: false,
             compile_fail: false,
             error_codes: Vec::new(),
@@ -793,7 +762,9 @@ impl LangString {
             edition: None,
         }
     }
+}
 
+impl LangString {
     fn parse_without_check(
         string: &str,
         allow_error_code_check: ErrorCodes,
@@ -811,7 +782,7 @@ impl LangString {
         let allow_error_code_check = allow_error_code_check.as_bool();
         let mut seen_rust_tags = false;
         let mut seen_other_tags = false;
-        let mut data = LangString::all_false();
+        let mut data = LangString::default();
         let mut ignores = vec![];
 
         data.original = string.to_owned();
@@ -1055,7 +1026,7 @@ fn markdown_summary_with_limit(md: &str, length_limit: usize) -> (String, bool)
     fn push(s: &mut String, text_length: &mut usize, text: &str) {
         s.push_str(text);
         *text_length += text.len();
-    };
+    }
 
     'outer: for event in Parser::new_ext(md, summary_opts()) {
         match &event {
@@ -1233,7 +1204,7 @@ crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_, '_>) -> Vec<RustC
                 CodeBlockKind::Fenced(syntax) => {
                     let syntax = syntax.as_ref();
                     let lang_string = if syntax.is_empty() {
-                        LangString::all_false()
+                        Default::default()
                     } else {
                         LangString::parse(&*syntax, ErrorCodes::Yes, false, Some(extra_info))
                     };
diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs
index 9807d8632c7..9da3072ec28 100644
--- a/src/librustdoc/html/markdown/tests.rs
+++ b/src/librustdoc/html/markdown/tests.rs
@@ -51,82 +51,65 @@ fn test_unique_id() {
 
 #[test]
 fn test_lang_string_parse() {
-    fn t(
-        s: &str,
-        should_panic: bool,
-        no_run: bool,
-        ignore: Ignore,
-        rust: bool,
-        test_harness: bool,
-        compile_fail: bool,
-        allow_fail: bool,
-        error_codes: Vec<String>,
-        edition: Option<Edition>,
-    ) {
-        assert_eq!(
-            LangString::parse(s, ErrorCodes::Yes, true, None),
-            LangString {
-                should_panic,
-                no_run,
-                ignore,
-                rust,
-                test_harness,
-                compile_fail,
-                error_codes,
-                original: s.to_owned(),
-                allow_fail,
-                edition,
-            }
-        )
+    fn t(lg: LangString) {
+        let s = &lg.original;
+        assert_eq!(LangString::parse(s, ErrorCodes::Yes, true, None), lg)
     }
-    let ignore_foo = Ignore::Some(vec!["foo".to_string()]);
 
-    fn v() -> Vec<String> {
-        Vec::new()
-    }
-
-    // marker                | should_panic | no_run | ignore | rust | test_harness
-    //                       | compile_fail | allow_fail | error_codes | edition
-    t("", false, false, Ignore::None, true, false, false, false, v(), None);
-    t("rust", false, false, Ignore::None, true, false, false, false, v(), None);
-    t("sh", false, false, Ignore::None, false, false, false, false, v(), None);
-    t("ignore", false, false, Ignore::All, true, false, false, false, v(), None);
-    t("ignore-foo", false, false, ignore_foo, true, false, false, false, v(), None);
-    t("should_panic", true, false, Ignore::None, true, false, false, false, v(), None);
-    t("no_run", false, true, Ignore::None, true, false, false, false, v(), None);
-    t("test_harness", false, false, Ignore::None, true, true, false, false, v(), None);
-    t("compile_fail", false, true, Ignore::None, true, false, true, false, v(), None);
-    t("allow_fail", false, false, Ignore::None, true, false, false, true, v(), None);
-    t("{.no_run .example}", false, true, Ignore::None, true, false, false, false, v(), None);
-    t("{.sh .should_panic}", true, false, Ignore::None, false, false, false, false, v(), None);
-    t("{.example .rust}", false, false, Ignore::None, true, false, false, false, v(), None);
-    t("{.test_harness .rust}", false, false, Ignore::None, true, true, false, false, v(), None);
-    t("text, no_run", false, true, Ignore::None, false, false, false, false, v(), None);
-    t("text,no_run", false, true, Ignore::None, false, false, false, false, v(), None);
-    t(
-        "edition2015",
-        false,
-        false,
-        Ignore::None,
-        true,
-        false,
-        false,
-        false,
-        v(),
-        Some(Edition::Edition2015),
-    );
-    t(
-        "edition2018",
-        false,
-        false,
-        Ignore::None,
-        true,
-        false,
-        false,
-        false,
-        v(),
-        Some(Edition::Edition2018),
-    );
+    t(Default::default());
+    t(LangString { original: "rust".into(), ..Default::default() });
+    t(LangString { original: "sh".into(), rust: false, ..Default::default() });
+    t(LangString { original: "ignore".into(), ignore: Ignore::All, ..Default::default() });
+    t(LangString {
+        original: "ignore-foo".into(),
+        ignore: Ignore::Some(vec!["foo".to_string()]),
+        ..Default::default()
+    });
+    t(LangString { original: "should_panic".into(), should_panic: true, ..Default::default() });
+    t(LangString { original: "no_run".into(), no_run: true, ..Default::default() });
+    t(LangString { original: "test_harness".into(), test_harness: true, ..Default::default() });
+    t(LangString {
+        original: "compile_fail".into(),
+        no_run: true,
+        compile_fail: true,
+        ..Default::default()
+    });
+    t(LangString { original: "allow_fail".into(), allow_fail: true, ..Default::default() });
+    t(LangString { original: "{.no_run .example}".into(), no_run: true, ..Default::default() });
+    t(LangString {
+        original: "{.sh .should_panic}".into(),
+        should_panic: true,
+        rust: false,
+        ..Default::default()
+    });
+    t(LangString { original: "{.example .rust}".into(), ..Default::default() });
+    t(LangString {
+        original: "{.test_harness .rust}".into(),
+        test_harness: true,
+        ..Default::default()
+    });
+    t(LangString {
+        original: "text, no_run".into(),
+        no_run: true,
+        rust: false,
+        ..Default::default()
+    });
+    t(LangString {
+        original: "text,no_run".into(),
+        no_run: true,
+        rust: false,
+        ..Default::default()
+    });
+    t(LangString {
+        original: "edition2015".into(),
+        edition: Some(Edition::Edition2015),
+        ..Default::default()
+    });
+    t(LangString {
+        original: "edition2018".into(),
+        edition: Some(Edition::Edition2018),
+        ..Default::default()
+    });
 }
 
 #[test]
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index 97f764517fa..c408e576639 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -2,7 +2,7 @@ use std::collections::BTreeMap;
 use std::path::Path;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Symbol};
 use serde::Serialize;
 
 use crate::clean::types::GetDefId;
@@ -31,7 +31,7 @@ crate fn extern_location(
 ) -> ExternalLocation {
     use ExternalLocation::*;
     // See if there's documentation generated into the local directory
-    let local_location = dst.join(&e.name);
+    let local_location = dst.join(&*e.name.as_str());
     if local_location.is_dir() {
         return Local;
     }
@@ -76,7 +76,7 @@ crate fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
         if let Some(&(ref fqp, _)) = paths.get(&did) {
             search_index.push(IndexItem {
                 ty: item.type_(),
-                name: item.name.clone().unwrap(),
+                name: item.name.unwrap().to_string(),
                 path: fqp[..fqp.len() - 1].join("::"),
                 desc: item.doc_value().map_or_else(|| String::new(), short_markdown_summary),
                 parent: Some(did),
@@ -165,7 +165,7 @@ crate fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
 }
 
 crate fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> {
-    let (all_types, ret_types) = match item.kind {
+    let (all_types, ret_types) = match *item.kind {
         clean::FunctionItem(ref f) => (&f.all_types, &f.ret_types),
         clean::MethodItem(ref m, _) => (&m.all_types, &m.ret_types),
         clean::TyMethodItem(ref m) => (&m.all_types, &m.ret_types),
@@ -191,12 +191,12 @@ fn get_index_type(clean_type: &clean::Type) -> RenderType {
     RenderType {
         ty: clean_type.def_id(),
         idx: None,
-        name: get_index_type_name(clean_type, true).map(|s| s.to_ascii_lowercase()),
+        name: get_index_type_name(clean_type, true).map(|s| s.as_str().to_ascii_lowercase()),
         generics: get_generics(clean_type),
     }
 }
 
-fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option<String> {
+fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option<Symbol> {
     match *clean_type {
         clean::ResolvedPath { ref path, .. } => {
             let segments = &path.segments;
@@ -206,10 +206,10 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option
                 clean_type, accept_generic
             )
             });
-            Some(path_segment.name.clone())
+            Some(path_segment.name)
         }
-        clean::Generic(ref s) if accept_generic => Some(s.clone()),
-        clean::Primitive(ref p) => Some(format!("{:?}", p)),
+        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),
         // FIXME: add all from clean::Type.
         _ => None,
@@ -222,7 +222,7 @@ fn get_generics(clean_type: &clean::Type) -> Option<Vec<Generic>> {
             .iter()
             .filter_map(|t| {
                 get_index_type_name(t, false).map(|name| Generic {
-                    name: name.to_ascii_lowercase(),
+                    name: name.as_str().to_ascii_lowercase(),
                     defid: t.def_id(),
                     idx: None,
                 })
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 901f00b21da..c19262b72cf 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -49,21 +49,24 @@ use std::sync::Arc;
 
 use itertools::Itertools;
 use rustc_ast_pretty::pprust;
-use rustc_attr::StabilityLevel;
+use rustc_attr::{Deprecation, StabilityLevel};
 use rustc_data_structures::flock;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::Mutability;
 use rustc_middle::middle::stability;
+use rustc_middle::ty;
+use rustc_middle::ty::TyCtxt;
+use rustc_session::Session;
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::FileName;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{kw, sym, Symbol};
 use serde::ser::SerializeSeq;
 use serde::{Serialize, Serializer};
 
-use crate::clean::{self, AttributesExt, Deprecation, GetDefId, RenderedLink, SelfTy, TypeKind};
+use crate::clean::{self, AttributesExt, GetDefId, RenderedLink, SelfTy, TypeKind};
 use crate::config::{RenderInfo, RenderOptions};
 use crate::docfs::{DocFS, PathError};
 use crate::doctree;
@@ -100,7 +103,7 @@ crate fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
 /// easily cloned because it is cloned per work-job (about once per item in the
 /// rustdoc tree).
 #[derive(Clone)]
-crate struct Context {
+crate struct Context<'tcx> {
     /// Current hierarchy of components leading down to what's currently being
     /// rendered
     crate current: Vec<String>,
@@ -113,14 +116,15 @@ crate struct Context {
     crate render_redirect_pages: bool,
     /// The map used to ensure all generated 'id=' attributes are unique.
     id_map: Rc<RefCell<IdMap>>,
-    crate shared: Arc<SharedContext>,
+    crate shared: Arc<SharedContext<'tcx>>,
     all: Rc<RefCell<AllTypes>>,
     /// Storage for the errors produced while generating documentation so they
     /// can be printed together at the end.
     crate errors: Rc<Receiver<String>>,
 }
 
-crate struct SharedContext {
+crate struct SharedContext<'tcx> {
+    crate tcx: TyCtxt<'tcx>,
     /// The path to the crate root source minus the file name.
     /// Used for simplifying paths to the highlighted source code files.
     crate src_root: PathBuf,
@@ -160,22 +164,28 @@ crate struct SharedContext {
     playground: Option<markdown::Playground>,
 }
 
-impl Context {
+impl<'tcx> Context<'tcx> {
     fn path(&self, filename: &str) -> PathBuf {
         // We use splitn vs Path::extension here because we might get a filename
         // like `style.min.css` and we want to process that into
         // `style-suffix.min.css`.  Path::extension would just return `css`
         // which would result in `style.min-suffix.css` which isn't what we
         // want.
-        let mut iter = filename.splitn(2, '.');
-        let base = iter.next().unwrap();
-        let ext = iter.next().unwrap();
-        let filename = format!("{}{}.{}", base, self.shared.resource_suffix, ext,);
+        let (base, ext) = filename.split_once('.').unwrap();
+        let filename = format!("{}{}.{}", base, self.shared.resource_suffix, ext);
         self.dst.join(&filename)
     }
+
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.shared.tcx
+    }
+
+    fn sess(&self) -> &Session {
+        &self.shared.tcx.sess
+    }
 }
 
-impl SharedContext {
+impl SharedContext<'_> {
     crate fn ensure_dir(&self, dst: &Path) -> Result<(), Error> {
         let mut dirs = self.created_dirs.borrow_mut();
         if !dirs.contains(dst) {
@@ -376,14 +386,15 @@ crate fn initial_ids() -> Vec<String> {
 }
 
 /// Generates the documentation for `crate` into the directory `dst`
-impl FormatRenderer for Context {
+impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
     fn init(
         mut krate: clean::Crate,
         options: RenderOptions,
         _render_info: RenderInfo,
         edition: Edition,
         cache: &mut Cache,
-    ) -> Result<(Context, clean::Crate), Error> {
+        tcx: ty::TyCtxt<'tcx>,
+    ) -> Result<(Self, clean::Crate), Error> {
         // need to save a copy of the options for rendering the index page
         let md_opts = options.clone();
         let RenderOptions {
@@ -412,14 +423,15 @@ impl FormatRenderer for Context {
         // If user passed in `--playground-url` arg, we fill in crate name here
         let mut playground = None;
         if let Some(url) = playground_url {
-            playground = Some(markdown::Playground { crate_name: Some(krate.name.clone()), url });
+            playground =
+                Some(markdown::Playground { crate_name: Some(krate.name.to_string()), url });
         }
         let mut layout = layout::Layout {
             logo: String::new(),
             favicon: String::new(),
             external_html,
             default_settings,
-            krate: krate.name.clone(),
+            krate: krate.name.to_string(),
             css_file_extension: extension_css,
             generate_search_filter,
         };
@@ -439,7 +451,7 @@ impl FormatRenderer for Context {
                     }
                     (sym::html_playground_url, Some(s)) => {
                         playground = Some(markdown::Playground {
-                            crate_name: Some(krate.name.clone()),
+                            crate_name: Some(krate.name.to_string()),
                             url: s.to_string(),
                         });
                     }
@@ -455,6 +467,7 @@ impl FormatRenderer for Context {
         }
         let (sender, receiver) = channel();
         let mut scx = SharedContext {
+            tcx,
             collapsed: krate.collapsed,
             src_root,
             include_sources,
@@ -523,9 +536,9 @@ impl FormatRenderer for Context {
     }
 
     fn after_krate(&mut self, krate: &clean::Crate, cache: &Cache) -> Result<(), Error> {
-        let final_file = self.dst.join(&krate.name).join("all.html");
+        let final_file = self.dst.join(&*krate.name.as_str()).join("all.html");
         let settings_file = self.dst.join("settings.html");
-        let crate_name = krate.name.clone();
+        let crate_name = krate.name;
 
         let mut root_path = self.dst.to_str().expect("invalid path").to_owned();
         if !root_path.ends_with('/') {
@@ -620,7 +633,7 @@ impl FormatRenderer for Context {
 
         // Render sidebar-items.js used throughout this module.
         if !self.render_redirect_pages {
-            let module = match item.kind {
+            let module = match *item.kind {
                 clean::StrippedItem(box clean::ModuleItem(ref m)) | clean::ModuleItem(ref m) => m,
                 _ => unreachable!(),
             };
@@ -658,7 +671,7 @@ impl FormatRenderer for Context {
         if !buf.is_empty() {
             let name = item.name.as_ref().unwrap();
             let item_type = item.type_();
-            let file_name = &item_path(item_type, name);
+            let file_name = &item_path(item_type, &name.as_str());
             self.shared.ensure_dir(&self.dst)?;
             let joint_dst = self.dst.join(file_name);
             self.shared.fs.write(&joint_dst, buf.as_bytes())?;
@@ -680,7 +693,7 @@ impl FormatRenderer for Context {
 }
 
 fn write_shared(
-    cx: &Context,
+    cx: &Context<'_>,
     krate: &clean::Crate,
     search_index: String,
     options: &RenderOptions,
@@ -1012,7 +1025,8 @@ themePicker.onblur = handleThemeButtonsBlur;
         }
 
         let dst = cx.dst.join(&format!("source-files{}.js", cx.shared.resource_suffix));
-        let (mut all_sources, _krates) = try_err!(collect(&dst, &krate.name, "sourcesIndex"), &dst);
+        let (mut all_sources, _krates) =
+            try_err!(collect(&dst, &krate.name.as_str(), "sourcesIndex"), &dst);
         all_sources.push(format!(
             "sourcesIndex[\"{}\"] = {};",
             &krate.name,
@@ -1028,7 +1042,7 @@ themePicker.onblur = handleThemeButtonsBlur;
 
     // Update the search index
     let dst = cx.dst.join(&format!("search-index{}.js", cx.shared.resource_suffix));
-    let (mut all_indexes, mut krates) = try_err!(collect_json(&dst, &krate.name), &dst);
+    let (mut all_indexes, mut krates) = try_err!(collect_json(&dst, &krate.name.as_str()), &dst);
     all_indexes.push(search_index);
 
     // Sort the indexes by crate so the file will be generated identically even
@@ -1063,7 +1077,7 @@ themePicker.onblur = handleThemeButtonsBlur;
                 extra_scripts: &[],
                 static_extra_scripts: &[],
             };
-            krates.push(krate.name.clone());
+            krates.push(krate.name.to_string());
             krates.sort();
             krates.dedup();
 
@@ -1155,7 +1169,7 @@ themePicker.onblur = handleThemeButtonsBlur;
         mydst.push(&format!("{}.{}.js", remote_item_type, remote_path[remote_path.len() - 1]));
 
         let (mut all_implementors, _) =
-            try_err!(collect(&mydst, &krate.name, "implementors"), &mydst);
+            try_err!(collect(&mydst, &krate.name.as_str(), "implementors"), &mydst);
         all_implementors.push(implementors);
         // Sort the implementors by crate so the file will be generated
         // identically even with rustdoc running in parallel.
@@ -1196,7 +1210,7 @@ fn write_minify(
     }
 }
 
-fn write_srclink(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) {
+fn write_srclink(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, cache: &Cache) {
     if let Some(l) = cx.src_href(item, cache) {
         write!(
             buf,
@@ -1507,7 +1521,7 @@ fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result<Strin
     ))
 }
 
-impl Context {
+impl Context<'_> {
     fn derive_id(&self, id: String) -> String {
         let mut map = self.id_map.borrow_mut();
         map.derive(id)
@@ -1536,7 +1550,7 @@ impl Context {
             if !title.is_empty() {
                 title.push_str("::");
             }
-            title.push_str(it.name.as_ref().unwrap());
+            title.push_str(&it.name.unwrap().as_str());
         }
         title.push_str(" - Rust");
         let tyname = it.type_();
@@ -1631,26 +1645,27 @@ impl Context {
     /// of their crate documentation isn't known.
     fn src_href(&self, item: &clean::Item, cache: &Cache) -> Option<String> {
         let mut root = self.root_path();
-
         let mut path = String::new();
+        let cnum = item.source.cnum(self.sess());
 
         // We can safely ignore synthetic `SourceFile`s.
-        let file = match item.source.filename {
+        let file = match item.source.filename(self.sess()) {
             FileName::Real(ref path) => path.local_path().to_path_buf(),
             _ => return None,
         };
         let file = &file;
 
-        let (krate, path) = if item.source.cnum == LOCAL_CRATE {
+        let symbol;
+        let (krate, path) = if cnum == LOCAL_CRATE {
             if let Some(path) = self.shared.local_sources.get(file) {
-                (&self.shared.layout.krate, path)
+                (self.shared.layout.krate.as_str(), path)
             } else {
                 return None;
             }
         } else {
-            let (krate, src_root) = match *cache.extern_locations.get(&item.source.cnum)? {
-                (ref name, ref src, ExternalLocation::Local) => (name, src),
-                (ref name, ref src, ExternalLocation::Remote(ref s)) => {
+            let (krate, src_root) = match *cache.extern_locations.get(&cnum)? {
+                (name, ref src, ExternalLocation::Local) => (name, src),
+                (name, ref src, ExternalLocation::Remote(ref s)) => {
                     root = s.to_string();
                     (name, src)
                 }
@@ -1664,14 +1679,14 @@ impl Context {
             let mut fname = file.file_name().expect("source has no filename").to_os_string();
             fname.push(".html");
             path.push_str(&fname.to_string_lossy());
-            (krate, &path)
+            symbol = krate.as_str();
+            (&*symbol, &path)
         };
 
-        let lines = if item.source.loline == item.source.hiline {
-            item.source.loline.to_string()
-        } else {
-            format!("{}-{}", item.source.loline, item.source.hiline)
-        };
+        let loline = item.source.lo(self.sess()).line;
+        let hiline = item.source.hi(self.sess()).line;
+        let lines =
+            if loline == hiline { loline.to_string() } else { format!("{}-{}", loline, hiline) };
         Some(format!(
             "{root}src/{krate}/{path}#{lines}",
             root = Escape(&root),
@@ -1691,14 +1706,14 @@ where
     write!(w, "</div>")
 }
 
-fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache) {
+fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, cache: &Cache) {
     debug_assert!(!item.is_stripped());
     // Write the breadcrumb trail header for the top
     write!(buf, "<h1 class=\"fqn\"><span class=\"out-of-band\">");
     render_stability_since_raw(
         buf,
-        item.stable_since().as_deref(),
-        item.const_stable_since().as_deref(),
+        item.stable_since(cx.tcx()).as_deref(),
+        item.const_stable_since(cx.tcx()).as_deref(),
         None,
         None,
     );
@@ -1724,7 +1739,7 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache)
 
     write!(buf, "</span>"); // out-of-band
     write!(buf, "<span class=\"in-band\">");
-    let name = match item.kind {
+    let name = match *item.kind {
         clean::ModuleItem(ref m) => {
             if m.is_crate {
                 "Crate "
@@ -1773,7 +1788,7 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache)
 
     write!(buf, "</span></h1>"); // in-band
 
-    match item.kind {
+    match *item.kind {
         clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items),
         clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) => {
             item_function(buf, cx, item, f)
@@ -1806,14 +1821,14 @@ fn item_path(ty: ItemType, name: &str) -> String {
     }
 }
 
-fn full_path(cx: &Context, item: &clean::Item) -> String {
+fn full_path(cx: &Context<'_>, item: &clean::Item) -> String {
     let mut s = cx.current.join("::");
     s.push_str("::");
-    s.push_str(item.name.as_ref().unwrap());
+    s.push_str(&item.name.unwrap().as_str());
     s
 }
 
-fn document(w: &mut Buffer, cx: &Context, item: &clean::Item, parent: Option<&clean::Item>) {
+fn document(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, parent: Option<&clean::Item>) {
     if let Some(ref name) = item.name {
         info!("Documenting {}", name);
     }
@@ -1824,7 +1839,7 @@ fn document(w: &mut Buffer, cx: &Context, item: &clean::Item, parent: Option<&cl
 /// Render md_text as markdown.
 fn render_markdown(
     w: &mut Buffer,
-    cx: &Context,
+    cx: &Context<'_>,
     md_text: &str,
     links: Vec<RenderedLink>,
     prefix: &str,
@@ -1853,7 +1868,7 @@ fn render_markdown(
 fn document_short(
     w: &mut Buffer,
     item: &clean::Item,
-    cx: &Context,
+    cx: &Context<'_>,
     link: AssocItemLink<'_>,
     prefix: &str,
     is_hidden: bool,
@@ -1894,7 +1909,13 @@ fn document_short(
     }
 }
 
-fn document_full(w: &mut Buffer, item: &clean::Item, cx: &Context, prefix: &str, is_hidden: bool) {
+fn document_full(
+    w: &mut Buffer,
+    item: &clean::Item,
+    cx: &Context<'_>,
+    prefix: &str,
+    is_hidden: bool,
+) {
     if let Some(s) = cx.shared.maybe_collapsed_doc_value(item) {
         debug!("Doc block: =====\n{}\n=====", s);
         render_markdown(w, cx, &*s, item.links(), prefix, is_hidden);
@@ -1915,7 +1936,7 @@ fn document_full(w: &mut Buffer, item: &clean::Item, cx: &Context, prefix: &str,
 /// * Required features (through the `doc_cfg` feature)
 fn document_item_info(
     w: &mut Buffer,
-    cx: &Context,
+    cx: &Context<'_>,
     item: &clean::Item,
     is_hidden: bool,
     parent: Option<&clean::Item>,
@@ -2019,7 +2040,7 @@ crate fn compare_names(mut lhs: &str, mut rhs: &str) -> Ordering {
     Ordering::Equal
 }
 
-fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean::Item]) {
+fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) {
     document(w, cx, item, None);
 
     let mut indices = (0..items.len()).filter(|i| !items[*i].is_stripped()).collect::<Vec<usize>>();
@@ -2044,14 +2065,20 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
         }
     }
 
-    fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering {
+    fn cmp(
+        i1: &clean::Item,
+        i2: &clean::Item,
+        idx1: usize,
+        idx2: usize,
+        tcx: TyCtxt<'_>,
+    ) -> Ordering {
         let ty1 = i1.type_();
         let ty2 = i2.type_();
         if ty1 != ty2 {
             return (reorder(ty1), idx1).cmp(&(reorder(ty2), idx2));
         }
-        let s1 = i1.stability.as_ref().map(|s| s.level);
-        let s2 = i2.stability.as_ref().map(|s| s.level);
+        let s1 = i1.stability(tcx).as_ref().map(|s| s.level);
+        let s2 = i2.stability(tcx).as_ref().map(|s| s.level);
         if let (Some(a), Some(b)) = (s1, s2) {
             match (a.is_stable(), b.is_stable()) {
                 (true, true) | (false, false) => {}
@@ -2059,13 +2086,13 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
                 (true, false) => return Ordering::Greater,
             }
         }
-        let lhs = i1.name.as_ref().map_or("", |s| &**s);
-        let rhs = i2.name.as_ref().map_or("", |s| &**s);
-        compare_names(lhs, rhs)
+        let lhs = i1.name.unwrap_or(kw::Empty).as_str();
+        let rhs = i2.name.unwrap_or(kw::Empty).as_str();
+        compare_names(&lhs, &rhs)
     }
 
     if cx.shared.sort_modules_alphabetically {
-        indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
+        indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2, cx.tcx()));
     }
     // This call is to remove re-export duplicates in cases such as:
     //
@@ -2122,7 +2149,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
             );
         }
 
-        match myitem.kind {
+        match *myitem.kind {
             clean::ExternCrateItem(ref name, ref src) => {
                 use crate::html::format::anchor;
 
@@ -2130,15 +2157,15 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
                     Some(ref src) => write!(
                         w,
                         "<tr><td><code>{}extern crate {} as {};",
-                        myitem.visibility.print_with_space(),
-                        anchor(myitem.def_id, src),
+                        myitem.visibility.print_with_space(cx.tcx(), myitem.def_id),
+                        anchor(myitem.def_id, &*src.as_str()),
                         name
                     ),
                     None => write!(
                         w,
                         "<tr><td><code>{}extern crate {};",
-                        myitem.visibility.print_with_space(),
-                        anchor(myitem.def_id, name)
+                        myitem.visibility.print_with_space(cx.tcx(), myitem.def_id),
+                        anchor(myitem.def_id, &*name.as_str())
                     ),
                 }
                 write!(w, "</code></td></tr>");
@@ -2148,7 +2175,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
                 write!(
                     w,
                     "<tr><td><code>{}{}</code></td></tr>",
-                    myitem.visibility.print_with_space(),
+                    myitem.visibility.print_with_space(cx.tcx(), myitem.def_id),
                     import.print()
                 );
             }
@@ -2158,7 +2185,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
                     continue;
                 }
 
-                let unsafety_flag = match myitem.kind {
+                let unsafety_flag = match *myitem.kind {
                     clean::FunctionItem(ref func) | clean::ForeignFunctionItem(ref func)
                         if func.header.unsafety == hir::Unsafety::Unsafe =>
                     {
@@ -2167,7 +2194,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
                     _ => "",
                 };
 
-                let stab = myitem.stability_class();
+                let stab = myitem.stability_class(cx.tcx());
                 let add = if stab.is_some() { " " } else { "" };
 
                 let doc_value = myitem.doc_value().unwrap_or("");
@@ -2179,13 +2206,13 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
                          <td class=\"docblock-short\">{stab_tags}{docs}</td>\
                      </tr>",
                     name = *myitem.name.as_ref().unwrap(),
-                    stab_tags = extra_info_tags(myitem, item),
+                    stab_tags = extra_info_tags(myitem, item, cx.tcx()),
                     docs = MarkdownSummaryLine(doc_value, &myitem.links()).into_string(),
                     class = myitem.type_(),
                     add = add,
                     stab = stab.unwrap_or_else(String::new),
                     unsafety_flag = unsafety_flag,
-                    href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()),
+                    href = item_path(myitem.type_(), &myitem.name.unwrap().as_str()),
                     title = [full_path(cx, myitem), myitem.type_().to_string()]
                         .iter()
                         .filter_map(|s| if !s.is_empty() { Some(s.as_str()) } else { None })
@@ -2203,7 +2230,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
 
 /// Render the stability, deprecation and portability tags that are displayed in the item's summary
 /// at the module level.
-fn extra_info_tags(item: &clean::Item, parent: &clean::Item) -> String {
+fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) -> String {
     let mut tags = String::new();
 
     fn tag_html(class: &str, title: &str, contents: &str) -> String {
@@ -2211,9 +2238,12 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item) -> String {
     }
 
     // The trailing space after each tag is to space it properly against the rest of the docs.
-    if let Some(depr) = &item.deprecation {
+    if let Some(depr) = &item.deprecation(tcx) {
         let mut message = "Deprecated";
-        if !stability::deprecation_in_effect(depr.is_since_rustc_version, depr.since.as_deref()) {
+        if !stability::deprecation_in_effect(
+            depr.is_since_rustc_version,
+            depr.since.map(|s| s.as_str()).as_deref(),
+        ) {
             message = "Deprecation planned";
         }
         tags += &tag_html("deprecated", "", message);
@@ -2221,7 +2251,10 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item) -> String {
 
     // The "rustc_private" crates are permanently unstable so it makes no sense
     // to render "unstable" everywhere.
-    if item.stability.as_ref().map(|s| s.level.is_unstable() && s.feature != sym::rustc_private)
+    if item
+        .stability(tcx)
+        .as_ref()
+        .map(|s| s.level.is_unstable() && s.feature != sym::rustc_private)
         == Some(true)
     {
         tags += &tag_html("unstable", "", "Experimental");
@@ -2258,24 +2291,36 @@ fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option<Strin
 
 /// Render the stability, deprecation and portability information that is displayed at the top of
 /// the item's documentation.
-fn short_item_info(item: &clean::Item, cx: &Context, parent: Option<&clean::Item>) -> Vec<String> {
+fn short_item_info(
+    item: &clean::Item,
+    cx: &Context<'_>,
+    parent: Option<&clean::Item>,
+) -> Vec<String> {
     let mut extra_info = vec![];
     let error_codes = cx.shared.codes;
 
-    if let Some(Deprecation { ref note, ref since, is_since_rustc_version }) = item.deprecation {
+    if let Some(Deprecation { note, since, is_since_rustc_version, suggestion: _ }) =
+        item.deprecation(cx.tcx())
+    {
         // We display deprecation messages for #[deprecated] and #[rustc_deprecated]
         // but only display the future-deprecation messages for #[rustc_deprecated].
         let mut message = if let Some(since) = since {
+            let since = &since.as_str();
             if !stability::deprecation_in_effect(is_since_rustc_version, Some(since)) {
-                format!("Deprecating in {}", Escape(&since))
+                if *since == "TBD" {
+                    format!("Deprecating in a future Rust version")
+                } else {
+                    format!("Deprecating in {}", Escape(since))
+                }
             } else {
-                format!("Deprecated since {}", Escape(&since))
+                format!("Deprecated since {}", Escape(since))
             }
         } else {
             String::from("Deprecated")
         };
 
         if let Some(note) = note {
+            let note = note.as_str();
             let mut ids = cx.id_map.borrow_mut();
             let html = MarkdownHtml(
                 &note,
@@ -2295,7 +2340,7 @@ fn short_item_info(item: &clean::Item, cx: &Context, parent: Option<&clean::Item
     // Render unstable items. But don't render "rustc_private" crates (internal compiler crates).
     // Those crates are permanently unstable so it makes no sense to render "unstable" everywhere.
     if let Some((StabilityLevel::Unstable { reason, issue, .. }, feature)) = item
-        .stability
+        .stability(cx.tcx())
         .as_ref()
         .filter(|stab| stab.feature != sym::rustc_private)
         .map(|stab| (stab.level, stab.feature))
@@ -2340,14 +2385,14 @@ fn short_item_info(item: &clean::Item, cx: &Context, parent: Option<&clean::Item
     extra_info
 }
 
-fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Constant) {
+fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) {
     write!(w, "<pre class=\"rust const\">");
     render_attributes(w, it, false);
 
     write!(
         w,
         "{vis}const {name}: {typ}",
-        vis = it.visibility.print_with_space(),
+        vis = it.visibility.print_with_space(cx.tcx(), it.def_id),
         name = it.name.as_ref().unwrap(),
         typ = c.type_.print(),
     );
@@ -2375,13 +2420,13 @@ fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Cons
     document(w, cx, it, None)
 }
 
-fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static) {
+fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) {
     write!(w, "<pre class=\"rust static\">");
     render_attributes(w, it, false);
     write!(
         w,
         "{vis}static {mutability}{name}: {typ}</pre>",
-        vis = it.visibility.print_with_space(),
+        vis = it.visibility.print_with_space(cx.tcx(), it.def_id),
         mutability = s.mutability.print_with_space(),
         name = it.name.as_ref().unwrap(),
         typ = s.type_.print()
@@ -2389,10 +2434,10 @@ fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static
     document(w, cx, it, None)
 }
 
-fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Function) {
+fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) {
     let header_len = format!(
         "{}{}{}{}{:#}fn {}{:#}",
-        it.visibility.print_with_space(),
+        it.visibility.print_with_space(cx.tcx(), it.def_id),
         f.header.constness.print_with_space(),
         f.header.asyncness.print_with_space(),
         f.header.unsafety.print_with_space(),
@@ -2407,7 +2452,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
         w,
         "{vis}{constness}{asyncness}{unsafety}{abi}fn \
          {name}{generics}{decl}{spotlight}{where_clause}</pre>",
-        vis = it.visibility.print_with_space(),
+        vis = it.visibility.print_with_space(cx.tcx(), it.def_id),
         constness = f.header.constness.print_with_space(),
         asyncness = f.header.asyncness.print_with_space(),
         unsafety = f.header.unsafety.print_with_space(),
@@ -2423,11 +2468,11 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func
 }
 
 fn render_implementor(
-    cx: &Context,
+    cx: &Context<'_>,
     implementor: &Impl,
     parent: &clean::Item,
     w: &mut Buffer,
-    implementor_dups: &FxHashMap<&str, (DefId, bool)>,
+    implementor_dups: &FxHashMap<Symbol, (DefId, bool)>,
     aliases: &[String],
     cache: &Cache,
 ) {
@@ -2438,7 +2483,7 @@ fn render_implementor(
         | clean::BorrowedRef {
             type_: box clean::ResolvedPath { ref path, is_generic: false, .. },
             ..
-        } => implementor_dups[path.last_name()].1,
+        } => implementor_dups[&path.last()].1,
         _ => false,
     };
     render_impl(
@@ -2448,8 +2493,8 @@ fn render_implementor(
         parent,
         AssocItemLink::Anchor(None),
         RenderMode::Normal,
-        implementor.impl_item.stable_since().as_deref(),
-        implementor.impl_item.const_stable_since().as_deref(),
+        implementor.impl_item.stable_since(cx.tcx()).as_deref(),
+        implementor.impl_item.const_stable_since(cx.tcx()).as_deref(),
         false,
         Some(use_absolute),
         false,
@@ -2460,7 +2505,7 @@ fn render_implementor(
 }
 
 fn render_impls(
-    cx: &Context,
+    cx: &Context<'_>,
     w: &mut Buffer,
     traits: &[&&Impl],
     containing_item: &clean::Item,
@@ -2479,8 +2524,8 @@ fn render_impls(
                 containing_item,
                 assoc_link,
                 RenderMode::Normal,
-                containing_item.stable_since().as_deref(),
-                containing_item.const_stable_since().as_deref(),
+                containing_item.stable_since(cx.tcx()).as_deref(),
+                containing_item.const_stable_since(cx.tcx()).as_deref(),
                 true,
                 None,
                 false,
@@ -2519,7 +2564,7 @@ fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl) -> Ordering {
     compare_names(&lhs, &rhs)
 }
 
-fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait, cache: &Cache) {
+fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait, cache: &Cache) {
     let bounds = bounds(&t.bounds, false);
     let types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>();
     let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>();
@@ -2533,7 +2578,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
         write!(
             w,
             "{}{}{}trait {}{}{}",
-            it.visibility.print_with_space(),
+            it.visibility.print_with_space(cx.tcx(), it.def_id),
             t.unsafety.print_with_space(),
             if t.is_auto { "auto " } else { "" },
             it.name.as_ref().unwrap(),
@@ -2553,21 +2598,21 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
             // FIXME: we should be using a derived_id for the Anchors here
             write!(w, "{{\n");
             for t in &types {
-                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait);
+                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
                 write!(w, ";\n");
             }
             if !types.is_empty() && !consts.is_empty() {
                 w.write_str("\n");
             }
             for t in &consts {
-                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait);
+                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
                 write!(w, ";\n");
             }
             if !consts.is_empty() && !required.is_empty() {
                 w.write_str("\n");
             }
             for (pos, m) in required.iter().enumerate() {
-                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait);
+                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx);
                 write!(w, ";\n");
 
                 if pos < required.len() - 1 {
@@ -2578,8 +2623,8 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
                 w.write_str("\n");
             }
             for (pos, m) in provided.iter().enumerate() {
-                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait);
-                match m.kind {
+                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx);
+                match *m.kind {
                     clean::MethodItem(ref inner, _)
                         if !inner.generics.where_predicates.is_empty() =>
                     {
@@ -2615,15 +2660,21 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
         write!(w, "{}<span class=\"loading-content\">Loading content...</span>", extra_content)
     }
 
-    fn trait_item(w: &mut Buffer, cx: &Context, m: &clean::Item, t: &clean::Item, cache: &Cache) {
+    fn trait_item(
+        w: &mut Buffer,
+        cx: &Context<'_>,
+        m: &clean::Item,
+        t: &clean::Item,
+        cache: &Cache,
+    ) {
         let name = m.name.as_ref().unwrap();
-        info!("Documenting {} on {}", name, t.name.as_deref().unwrap_or_default());
+        info!("Documenting {} on {:?}", name, t.name);
         let item_type = m.type_();
         let id = cx.derive_id(format!("{}.{}", item_type, name));
         write!(w, "<h3 id=\"{id}\" class=\"method\"><code>", id = id,);
-        render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl);
+        render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl, cx);
         write!(w, "</code>");
-        render_stability_since(w, m, t);
+        render_stability_since(w, m, t, cx.tcx());
         write_srclink(cx, m, w, cache);
         write!(w, "</h3>");
         document(w, cx, m, Some(t));
@@ -2687,7 +2738,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
     if let Some(implementors) = cache.implementors.get(&it.def_id) {
         // The DefId is for the first Type found with that name. The bool is
         // if any Types with the same name but different DefId have been found.
-        let mut implementor_dups: FxHashMap<&str, (DefId, bool)> = FxHashMap::default();
+        let mut implementor_dups: FxHashMap<Symbol, (DefId, bool)> = FxHashMap::default();
         for implementor in implementors {
             match implementor.inner_impl().for_ {
                 clean::ResolvedPath { ref path, did, is_generic: false, .. }
@@ -2696,7 +2747,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
                     ..
                 } => {
                     let &mut (prev_did, ref mut has_duplicates) =
-                        implementor_dups.entry(path.last_name()).or_insert((did, false));
+                        implementor_dups.entry(path.last()).or_insert((did, false));
                     if prev_did != did {
                         *has_duplicates = true;
                     }
@@ -2730,8 +2781,8 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
                     it,
                     assoc_link,
                     RenderMode::Normal,
-                    implementor.impl_item.stable_since().as_deref(),
-                    implementor.impl_item.const_stable_since().as_deref(),
+                    implementor.impl_item.stable_since(cx.tcx()).as_deref(),
+                    implementor.impl_item.const_stable_since(cx.tcx()).as_deref(),
                     false,
                     None,
                     true,
@@ -2839,12 +2890,13 @@ fn assoc_const(
     _default: Option<&String>,
     link: AssocItemLink<'_>,
     extra: &str,
+    cx: &Context<'_>,
 ) {
     write!(
         w,
         "{}{}const <a href=\"{}\" class=\"constant\"><b>{}</b></a>: {}",
         extra,
-        it.visibility.print_with_space(),
+        it.visibility.print_with_space(cx.tcx(), it.def_id),
         naive_assoc_href(it, link),
         it.name.as_ref().unwrap(),
         ty.print()
@@ -2912,13 +2964,18 @@ fn render_stability_since_raw(
     }
 }
 
-fn render_stability_since(w: &mut Buffer, item: &clean::Item, containing_item: &clean::Item) {
+fn render_stability_since(
+    w: &mut Buffer,
+    item: &clean::Item,
+    containing_item: &clean::Item,
+    tcx: TyCtxt<'_>,
+) {
     render_stability_since_raw(
         w,
-        item.stable_since().as_deref(),
-        item.const_stable_since().as_deref(),
-        containing_item.stable_since().as_deref(),
-        containing_item.const_stable_since().as_deref(),
+        item.stable_since(tcx).as_deref(),
+        item.const_stable_since(tcx).as_deref(),
+        containing_item.stable_since(tcx).as_deref(),
+        containing_item.const_stable_since(tcx).as_deref(),
     )
 }
 
@@ -2927,6 +2984,7 @@ fn render_assoc_item(
     item: &clean::Item,
     link: AssocItemLink<'_>,
     parent: ItemType,
+    cx: &Context<'_>,
 ) {
     fn method(
         w: &mut Buffer,
@@ -2936,6 +2994,7 @@ fn render_assoc_item(
         d: &clean::FnDecl,
         link: AssocItemLink<'_>,
         parent: ItemType,
+        cx: &Context<'_>,
     ) {
         let name = meth.name.as_ref().unwrap();
         let anchor = format!("#{}.{}", meth.type_(), name);
@@ -2945,7 +3004,7 @@ fn render_assoc_item(
             AssocItemLink::GotoSource(did, provided_methods) => {
                 // We're creating a link from an impl-item to the corresponding
                 // trait-item and need to map the anchored type accordingly.
-                let ty = if provided_methods.contains(name) {
+                let ty = if provided_methods.contains(&name) {
                     ItemType::Method
                 } else {
                     ItemType::TyMethod
@@ -2956,7 +3015,7 @@ fn render_assoc_item(
         };
         let mut header_len = format!(
             "{}{}{}{}{}{:#}fn {}{:#}",
-            meth.visibility.print_with_space(),
+            meth.visibility.print_with_space(cx.tcx(), meth.def_id),
             header.constness.print_with_space(),
             header.asyncness.print_with_space(),
             header.unsafety.print_with_space(),
@@ -2978,7 +3037,7 @@ fn render_assoc_item(
             "{}{}{}{}{}{}{}fn <a href=\"{href}\" class=\"fnname\">{name}</a>\
              {generics}{decl}{spotlight}{where_clause}",
             if parent == ItemType::Trait { "    " } else { "" },
-            meth.visibility.print_with_space(),
+            meth.visibility.print_with_space(cx.tcx(), meth.def_id),
             header.constness.print_with_space(),
             header.asyncness.print_with_space(),
             header.unsafety.print_with_space(),
@@ -2992,11 +3051,13 @@ fn render_assoc_item(
             where_clause = WhereClause { gens: g, indent, end_newline }
         )
     }
-    match item.kind {
+    match *item.kind {
         clean::StrippedItem(..) => {}
-        clean::TyMethodItem(ref m) => method(w, item, m.header, &m.generics, &m.decl, link, parent),
+        clean::TyMethodItem(ref m) => {
+            method(w, item, m.header, &m.generics, &m.decl, link, parent, cx)
+        }
         clean::MethodItem(ref m, _) => {
-            method(w, item, m.header, &m.generics, &m.decl, link, parent)
+            method(w, item, m.header, &m.generics, &m.decl, link, parent, cx)
         }
         clean::AssocConstItem(ref ty, ref default) => assoc_const(
             w,
@@ -3005,6 +3066,7 @@ fn render_assoc_item(
             default.as_ref(),
             link,
             if parent == ItemType::Trait { "    " } else { "" },
+            cx,
         ),
         clean::AssocTypeItem(ref bounds, ref default) => assoc_type(
             w,
@@ -3018,11 +3080,17 @@ fn render_assoc_item(
     }
 }
 
-fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct, cache: &Cache) {
+fn item_struct(
+    w: &mut Buffer,
+    cx: &Context<'_>,
+    it: &clean::Item,
+    s: &clean::Struct,
+    cache: &Cache,
+) {
     wrap_into_docblock(w, |w| {
         write!(w, "<pre class=\"rust struct\">");
         render_attributes(w, it, true);
-        render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true);
+        render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx);
         write!(w, "</pre>")
     });
 
@@ -3030,7 +3098,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct
     let mut fields = s
         .fields
         .iter()
-        .filter_map(|f| match f.kind {
+        .filter_map(|f| match *f.kind {
             clean::StructFieldItem(ref ty) => Some((f, ty)),
             _ => None,
         })
@@ -3068,11 +3136,11 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
-fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union, cache: &Cache) {
+fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union, cache: &Cache) {
     wrap_into_docblock(w, |w| {
         write!(w, "<pre class=\"rust union\">");
         render_attributes(w, it, true);
-        render_union(w, it, Some(&s.generics), &s.fields, "", true);
+        render_union(w, it, Some(&s.generics), &s.fields, "", true, cx);
         write!(w, "</pre>")
     });
 
@@ -3080,7 +3148,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union,
     let mut fields = s
         .fields
         .iter()
-        .filter_map(|f| match f.kind {
+        .filter_map(|f| match *f.kind {
             clean::StructFieldItem(ref ty) => Some((f, ty)),
             _ => None,
         })
@@ -3105,7 +3173,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union,
                 shortty = ItemType::StructField,
                 ty = ty.print()
             );
-            if let Some(stability_class) = field.stability_class() {
+            if let Some(stability_class) = field.stability_class(cx.tcx()) {
                 write!(w, "<span class=\"stab {stab}\"></span>", stab = stability_class);
             }
             document(w, cx, field, Some(it));
@@ -3114,14 +3182,14 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union,
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
-fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, cache: &Cache) {
+fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum, cache: &Cache) {
     wrap_into_docblock(w, |w| {
         write!(w, "<pre class=\"rust enum\">");
         render_attributes(w, it, true);
         write!(
             w,
             "{}enum {}{}{}",
-            it.visibility.print_with_space(),
+            it.visibility.print_with_space(cx.tcx(), it.def_id),
             it.name.as_ref().unwrap(),
             e.generics.print(),
             WhereClause { gens: &e.generics, indent: 0, end_newline: true }
@@ -3133,7 +3201,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
             for v in &e.variants {
                 write!(w, "    ");
                 let name = v.name.as_ref().unwrap();
-                match v.kind {
+                match *v.kind {
                     clean::VariantItem(ref var) => match var.kind {
                         clean::VariantKind::CLike => write!(w, "{}", name),
                         clean::VariantKind::Tuple(ref tys) => {
@@ -3147,7 +3215,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
                             write!(w, ")");
                         }
                         clean::VariantKind::Struct(ref s) => {
-                            render_struct(w, v, None, s.struct_type, &s.fields, "    ", false);
+                            render_struct(w, v, None, s.struct_type, &s.fields, "    ", false, cx);
                         }
                     },
                     _ => unreachable!(),
@@ -3183,7 +3251,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
                 id = id,
                 name = variant.name.as_ref().unwrap()
             );
-            if let clean::VariantItem(ref var) = variant.kind {
+            if let clean::VariantItem(ref var) = *variant.kind {
                 if let clean::VariantKind::Tuple(ref tys) = var.kind {
                     write!(w, "(");
                     for (i, ty) in tys.iter().enumerate() {
@@ -3200,7 +3268,8 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
             document_non_exhaustive(w, variant);
 
             use crate::clean::{Variant, VariantKind};
-            if let clean::VariantItem(Variant { kind: VariantKind::Struct(ref s) }) = variant.kind {
+            if let clean::VariantItem(Variant { kind: VariantKind::Struct(ref s) }) = *variant.kind
+            {
                 let variant_id = cx.derive_id(format!(
                     "{}.{}.fields",
                     ItemType::Variant,
@@ -3214,7 +3283,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
                 );
                 for field in &s.fields {
                     use crate::clean::StructFieldItem;
-                    if let StructFieldItem(ref ty) = field.kind {
+                    if let StructFieldItem(ref ty) = *field.kind {
                         let id = cx.derive_id(format!(
                             "variant.{}.field.{}",
                             variant.name.as_ref().unwrap(),
@@ -3235,7 +3304,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
                 }
                 write!(w, "</div></div>");
             }
-            render_stability_since(w, variant, it);
+            render_stability_since(w, variant, it, cx.tcx());
         }
     }
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
@@ -3291,11 +3360,12 @@ fn render_struct(
     fields: &[clean::Item],
     tab: &str,
     structhead: bool,
+    cx: &Context<'_>,
 ) {
     write!(
         w,
         "{}{}{}",
-        it.visibility.print_with_space(),
+        it.visibility.print_with_space(cx.tcx(), it.def_id),
         if structhead { "struct " } else { "" },
         it.name.as_ref().unwrap()
     );
@@ -3310,12 +3380,12 @@ fn render_struct(
             let mut has_visible_fields = false;
             write!(w, " {{");
             for field in fields {
-                if let clean::StructFieldItem(ref ty) = field.kind {
+                if let clean::StructFieldItem(ref ty) = *field.kind {
                     write!(
                         w,
                         "\n{}    {}{}: {},",
                         tab,
-                        field.visibility.print_with_space(),
+                        field.visibility.print_with_space(cx.tcx(), field.def_id),
                         field.name.as_ref().unwrap(),
                         ty.print()
                     );
@@ -3341,10 +3411,15 @@ fn render_struct(
                 if i > 0 {
                     write!(w, ", ");
                 }
-                match field.kind {
+                match *field.kind {
                     clean::StrippedItem(box clean::StructFieldItem(..)) => write!(w, "_"),
                     clean::StructFieldItem(ref ty) => {
-                        write!(w, "{}{}", field.visibility.print_with_space(), ty.print())
+                        write!(
+                            w,
+                            "{}{}",
+                            field.visibility.print_with_space(cx.tcx(), field.def_id),
+                            ty.print()
+                        )
                     }
                     _ => unreachable!(),
                 }
@@ -3372,11 +3447,12 @@ fn render_union(
     fields: &[clean::Item],
     tab: &str,
     structhead: bool,
+    cx: &Context<'_>,
 ) {
     write!(
         w,
         "{}{}{}",
-        it.visibility.print_with_space(),
+        it.visibility.print_with_space(cx.tcx(), it.def_id),
         if structhead { "union " } else { "" },
         it.name.as_ref().unwrap()
     );
@@ -3387,11 +3463,11 @@ fn render_union(
 
     write!(w, " {{\n{}", tab);
     for field in fields {
-        if let clean::StructFieldItem(ref ty) = field.kind {
+        if let clean::StructFieldItem(ref ty) = *field.kind {
             write!(
                 w,
                 "    {}{}: {},\n{}",
-                field.visibility.print_with_space(),
+                field.visibility.print_with_space(cx.tcx(), field.def_id),
                 field.name.as_ref().unwrap(),
                 ty.print(),
                 tab
@@ -3408,11 +3484,11 @@ fn render_union(
 #[derive(Copy, Clone)]
 enum AssocItemLink<'a> {
     Anchor(Option<&'a str>),
-    GotoSource(DefId, &'a FxHashSet<String>),
+    GotoSource(DefId, &'a FxHashSet<Symbol>),
 }
 
 impl<'a> AssocItemLink<'a> {
-    fn anchor(&self, id: &'a String) -> Self {
+    fn anchor(&self, id: &'a str) -> Self {
         match *self {
             AssocItemLink::Anchor(_) => AssocItemLink::Anchor(Some(&id)),
             ref other => *other,
@@ -3422,16 +3498,13 @@ impl<'a> AssocItemLink<'a> {
 
 fn render_assoc_items(
     w: &mut Buffer,
-    cx: &Context,
+    cx: &Context<'_>,
     containing_item: &clean::Item,
     it: DefId,
     what: AssocItemRender<'_>,
     cache: &Cache,
 ) {
-    info!(
-        "Documenting associated items of {}",
-        containing_item.name.as_deref().unwrap_or_default()
-    );
+    info!("Documenting associated items of {:?}", containing_item.name);
     let v = match cache.impls.get(&it) {
         Some(v) => v,
         None => return,
@@ -3469,8 +3542,8 @@ fn render_assoc_items(
                 containing_item,
                 AssocItemLink::Anchor(None),
                 render_mode,
-                containing_item.stable_since().as_deref(),
-                containing_item.const_stable_since().as_deref(),
+                containing_item.stable_since(cx.tcx()).as_deref(),
+                containing_item.const_stable_since(cx.tcx()).as_deref(),
                 true,
                 None,
                 false,
@@ -3541,7 +3614,7 @@ fn render_assoc_items(
 
 fn render_deref_methods(
     w: &mut Buffer,
-    cx: &Context,
+    cx: &Context<'_>,
     impl_: &Impl,
     container_item: &clean::Item,
     deref_mut: bool,
@@ -3552,7 +3625,7 @@ fn render_deref_methods(
         .inner_impl()
         .items
         .iter()
-        .find_map(|item| match item.kind {
+        .find_map(|item| match *item.kind {
             clean::TypedefItem(ref t, true) => Some(match *t {
                 clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
                 _ => (&t.type_, &t.type_),
@@ -3574,7 +3647,7 @@ fn render_deref_methods(
 }
 
 fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool {
-    let self_type_opt = match item.kind {
+    let self_type_opt = match *item.kind {
         clean::MethodItem(ref method, _) => method.decl.self_type(),
         clean::TyMethodItem(ref method) => method.decl.self_type(),
         _ => None,
@@ -3625,7 +3698,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
                     ));
                     let t_did = impl_.trait_.def_id().unwrap();
                     for it in &impl_.items {
-                        if let clean::TypedefItem(ref tydef, _) = it.kind {
+                        if let clean::TypedefItem(ref tydef, _) = *it.kind {
                             out.push_str("<span class=\"where fmt-newline\">    ");
                             assoc_type(
                                 &mut out,
@@ -3657,7 +3730,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
 
 fn render_impl(
     w: &mut Buffer,
-    cx: &Context,
+    cx: &Context<'_>,
     i: &Impl,
     parent: &clean::Item,
     link: AssocItemLink<'_>,
@@ -3697,7 +3770,7 @@ fn render_impl(
             fmt_impl_for_trait_page(&i.inner_impl(), w, use_absolute);
             if show_def_docs {
                 for it in &i.inner_impl().items {
-                    if let clean::TypedefItem(ref tydef, _) = it.kind {
+                    if let clean::TypedefItem(ref tydef, _) = *it.kind {
                         write!(w, "<span class=\"where fmt-newline\">  ");
                         assoc_type(w, it, &[], Some(&tydef.type_), AssocItemLink::Anchor(None), "");
                         write!(w, ";</span>");
@@ -3717,8 +3790,8 @@ fn render_impl(
         write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
         render_stability_since_raw(
             w,
-            i.impl_item.stable_since().as_deref(),
-            i.impl_item.const_stable_since().as_deref(),
+            i.impl_item.stable_since(cx.tcx()).as_deref(),
+            i.impl_item.const_stable_since(cx.tcx()).as_deref(),
             outer_version,
             outer_const_version,
         );
@@ -3751,7 +3824,7 @@ fn render_impl(
 
     fn doc_impl_item(
         w: &mut Buffer,
-        cx: &Context,
+        cx: &Context<'_>,
         item: &clean::Item,
         parent: &clean::Item,
         link: AssocItemLink<'_>,
@@ -3779,19 +3852,19 @@ fn render_impl(
             } else {
                 (true, " hidden")
             };
-        match item.kind {
+        match *item.kind {
             clean::MethodItem(..) | clean::TyMethodItem(_) => {
                 // Only render when the method is not static or we allow static methods
                 if render_method_item {
                     let id = cx.derive_id(format!("{}.{}", item_type, name));
                     write!(w, "<h4 id=\"{}\" class=\"{}{}\">", id, item_type, extra_class);
                     write!(w, "<code>");
-                    render_assoc_item(w, item, link.anchor(&id), ItemType::Impl);
+                    render_assoc_item(w, item, link.anchor(&id), ItemType::Impl, cx);
                     write!(w, "</code>");
                     render_stability_since_raw(
                         w,
-                        item.stable_since().as_deref(),
-                        item.const_stable_since().as_deref(),
+                        item.stable_since(cx.tcx()).as_deref(),
+                        item.const_stable_since(cx.tcx()).as_deref(),
                         outer_version,
                         outer_const_version,
                     );
@@ -3808,12 +3881,12 @@ fn render_impl(
             clean::AssocConstItem(ref ty, ref default) => {
                 let id = cx.derive_id(format!("{}.{}", item_type, name));
                 write!(w, "<h4 id=\"{}\" class=\"{}{}\"><code>", id, item_type, extra_class);
-                assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "");
+                assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "", cx);
                 write!(w, "</code>");
                 render_stability_since_raw(
                     w,
-                    item.stable_since().as_deref(),
-                    item.const_stable_since().as_deref(),
+                    item.stable_since(cx.tcx()).as_deref(),
+                    item.const_stable_since(cx.tcx()).as_deref(),
                     outer_version,
                     outer_const_version,
                 );
@@ -3888,7 +3961,7 @@ fn render_impl(
 
     fn render_default_items(
         w: &mut Buffer,
-        cx: &Context,
+        cx: &Context<'_>,
         t: &clean::Trait,
         i: &clean::Impl,
         parent: &clean::Item,
@@ -3899,7 +3972,7 @@ fn render_impl(
         cache: &Cache,
     ) {
         for trait_item in &t.items {
-            let n = trait_item.name.clone();
+            let n = trait_item.name;
             if i.items.iter().any(|m| m.name == n) {
                 continue;
             }
@@ -3948,7 +4021,7 @@ fn render_impl(
 
 fn item_opaque_ty(
     w: &mut Buffer,
-    cx: &Context,
+    cx: &Context<'_>,
     it: &clean::Item,
     t: &clean::OpaqueTy,
     cache: &Cache,
@@ -3975,7 +4048,7 @@ fn item_opaque_ty(
 
 fn item_trait_alias(
     w: &mut Buffer,
-    cx: &Context,
+    cx: &Context<'_>,
     it: &clean::Item,
     t: &clean::TraitAlias,
     cache: &Cache,
@@ -4000,7 +4073,13 @@ fn item_trait_alias(
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
-fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef, cache: &Cache) {
+fn item_typedef(
+    w: &mut Buffer,
+    cx: &Context<'_>,
+    it: &clean::Item,
+    t: &clean::Typedef,
+    cache: &Cache,
+) {
     write!(w, "<pre class=\"rust typedef\">");
     render_attributes(w, it, false);
     write!(
@@ -4021,13 +4100,13 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
-fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cache) {
+fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, cache: &Cache) {
     writeln!(w, "<pre class=\"rust foreigntype\">extern {{");
     render_attributes(w, it, false);
     write!(
         w,
         "    {}type {};\n}}</pre>",
-        it.visibility.print_with_space(),
+        it.visibility.print_with_space(cx.tcx(), it.def_id),
         it.name.as_ref().unwrap(),
     );
 
@@ -4036,7 +4115,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cac
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
-fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Cache) {
+fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer, cache: &Cache) {
     let parentlen = cx.current.len() - if it.is_mod() { 1 } else { 0 };
 
     if it.is_struct()
@@ -4050,7 +4129,7 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca
         write!(
             buffer,
             "<p class=\"location\">{}{}</p>",
-            match it.kind {
+            match *it.kind {
                 clean::StructItem(..) => "Struct ",
                 clean::TraitItem(..) => "Trait ",
                 clean::PrimitiveItem(..) => "Primitive Type ",
@@ -4090,7 +4169,7 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca
             it.name.as_ref().expect("crates always have a name")
         );
     }
-    match it.kind {
+    match *it.kind {
         clean::StructItem(ref s) => sidebar_struct(buffer, it, s),
         clean::TraitItem(ref t) => sidebar_trait(buffer, it, t),
         clean::PrimitiveItem(_) => sidebar_primitive(buffer, it),
@@ -4133,7 +4212,7 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca
                 ty: \"{ty}\", \
                 relpath: \"{path}\"\
             }};</script>",
-        name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""),
+        name = it.name.unwrap_or(kw::Empty),
         ty = it.type_(),
         path = relpath
     );
@@ -4230,7 +4309,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
                 .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did)
             {
                 if let Some((target, real_target)) =
-                    impl_.inner_impl().items.iter().find_map(|item| match item.kind {
+                    impl_.inner_impl().items.iter().find_map(|item| match *item.kind {
                         clean::TypedefItem(ref t, true) => Some(match *t {
                             clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
                             _ => (&t.type_, &t.type_),
@@ -4369,7 +4448,7 @@ fn get_id_for_impl_on_foreign_type(for_: &clean::Type, trait_: &clean::Type) ->
 }
 
 fn extract_for_impl_name(item: &clean::Item) -> Option<(String, String)> {
-    match item.kind {
+    match *item.kind {
         clean::ItemKind::ImplItem(ref i) => {
             if let Some(ref trait_) = i.trait_ {
                 Some((
@@ -4520,7 +4599,7 @@ fn sidebar_typedef(buf: &mut Buffer, it: &clean::Item) {
 fn get_struct_fields_name(fields: &[clean::Item]) -> String {
     let mut fields = fields
         .iter()
-        .filter(|f| if let clean::StructFieldItem(..) = f.kind { true } else { false })
+        .filter(|f| matches!(*f.kind, clean::StructFieldItem(..)))
         .filter_map(|f| match f.name {
             Some(ref name) => {
                 Some(format!("<a href=\"#structfield.{name}\">{name}</a>", name = name))
@@ -4667,19 +4746,20 @@ fn sidebar_foreign_type(buf: &mut Buffer, it: &clean::Item) {
     }
 }
 
-fn item_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Macro) {
+fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) {
     wrap_into_docblock(w, |w| {
         w.write_str(&highlight::render_with_highlighting(
             t.source.clone(),
             Some("macro"),
             None,
             None,
+            it.source.span().edition(),
         ))
     });
     document(w, cx, it, None)
 }
 
-fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::ProcMacro) {
+fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro) {
     let name = it.name.as_ref().expect("proc-macros always have names");
     match m.kind {
         MacroKind::Bang => {
@@ -4709,12 +4789,12 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::Pr
     document(w, cx, it, None)
 }
 
-fn item_primitive(w: &mut Buffer, cx: &Context, it: &clean::Item, cache: &Cache) {
+fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, cache: &Cache) {
     document(w, cx, it, None);
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All, cache)
 }
 
-fn item_keyword(w: &mut Buffer, cx: &Context, it: &clean::Item) {
+fn item_keyword(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
     document(w, cx, it, None)
 }
 
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index e7b5a90d84d..ac07aeb8bc8 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -7,6 +7,8 @@ use crate::html::highlight;
 use crate::html::layout;
 use crate::html::render::{SharedContext, BASIC_KEYWORDS};
 use rustc_hir::def_id::LOCAL_CRATE;
+use rustc_session::Session;
+use rustc_span::edition::Edition;
 use rustc_span::source_map::FileName;
 use std::ffi::OsStr;
 use std::fs;
@@ -14,57 +16,65 @@ use std::path::{Component, Path, PathBuf};
 
 crate fn render(
     dst: &Path,
-    scx: &mut SharedContext,
+    scx: &mut SharedContext<'_>,
     krate: clean::Crate,
 ) -> Result<clean::Crate, Error> {
     info!("emitting source files");
-    let dst = dst.join("src").join(&krate.name);
+    let dst = dst.join("src").join(&*krate.name.as_str());
     scx.ensure_dir(&dst)?;
     let mut folder = SourceCollector { dst, scx };
     Ok(folder.fold_crate(krate))
 }
 
 /// Helper struct to render all source code to HTML pages
-struct SourceCollector<'a> {
-    scx: &'a mut SharedContext,
+struct SourceCollector<'a, 'tcx> {
+    scx: &'a mut SharedContext<'tcx>,
 
     /// Root destination to place all HTML output into
     dst: PathBuf,
 }
 
-impl<'a> DocFolder for SourceCollector<'a> {
+impl DocFolder for SourceCollector<'_, '_> {
     fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
+        // If we're not rendering sources, there's nothing to do.
         // If we're including source files, and we haven't seen this file yet,
         // then we need to render it out to the filesystem.
         if self.scx.include_sources
             // skip all synthetic "files"
-            && item.source.filename.is_real()
+            && item.source.filename(self.sess()).is_real()
             // skip non-local files
-            && item.source.cnum == LOCAL_CRATE
+            && item.source.cnum(self.sess()) == LOCAL_CRATE
         {
+            let filename = item.source.filename(self.sess());
             // If it turns out that we couldn't read this file, then we probably
             // can't read any of the files (generating html output from json or
             // something like that), so just don't include sources for the
             // entire crate. The other option is maintaining this mapping on a
             // per-file basis, but that's probably not worth it...
-            self.scx.include_sources = match self.emit_source(&item.source.filename) {
+            self.scx.include_sources = match self.emit_source(&filename) {
                 Ok(()) => true,
                 Err(e) => {
                     println!(
                         "warning: source code was requested to be rendered, \
                          but processing `{}` had an error: {}",
-                        item.source.filename, e
+                        filename, e
                     );
                     println!("         skipping rendering of source code");
                     false
                 }
             };
         }
+        // FIXME: if `include_sources` isn't set and DocFolder didn't require consuming the crate by value,
+        // we could return None here without having to walk the rest of the crate.
         Some(self.fold_item_recur(item))
     }
 }
 
-impl<'a> SourceCollector<'a> {
+impl SourceCollector<'_, '_> {
+    fn sess(&self) -> &Session {
+        &self.scx.tcx.sess
+    }
+
     /// Renders the given filename into its corresponding HTML source file.
     fn emit_source(&mut self, filename: &FileName) -> Result<(), Error> {
         let p = match *filename {
@@ -123,7 +133,7 @@ impl<'a> SourceCollector<'a> {
             &self.scx.layout,
             &page,
             "",
-            |buf: &mut _| print_src(buf, contents),
+            |buf: &mut _| print_src(buf, contents, self.scx.edition),
             &self.scx.style_files,
         );
         self.scx.fs.write(&cur, v.as_bytes())?;
@@ -161,7 +171,7 @@ where
 
 /// Wrapper struct to render the source code of a file. This will do things like
 /// adding line numbers to the left-hand side.
-fn print_src(buf: &mut Buffer, s: String) {
+fn print_src(buf: &mut Buffer, s: String, edition: Edition) {
     let lines = s.lines().count();
     let mut cols = 0;
     let mut tmp = lines;
@@ -174,5 +184,5 @@ fn print_src(buf: &mut Buffer, s: String) {
         write!(buf, "<span id=\"{0}\">{0:1$}</span>\n", i, cols);
     }
     write!(buf, "</pre>");
-    write!(buf, "{}", highlight::render_with_highlighting(s, None, None, None));
+    write!(buf, "{}", highlight::render_with_highlighting(s, None, None, None, edition));
 }
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index a0ccb078c4a..1de4b0016c5 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -1633,10 +1633,10 @@ function defocusSearchBar() {
 
         function makeTabHeader(tabNb, text, nbElems) {
             if (currentTab === tabNb) {
-                return "<div class=\"selected\">" + text +
-                       " <div class=\"count\">(" + nbElems + ")</div></div>";
+                return "<button class=\"selected\">" + text +
+                       " <div class=\"count\">(" + nbElems + ")</div></button>";
             }
-            return "<div>" + text + " <div class=\"count\">(" + nbElems + ")</div></div>";
+            return "<button>" + text + " <div class=\"count\">(" + nbElems + ")</div></button>";
         }
 
         function showResults(results) {
@@ -2274,9 +2274,12 @@ function defocusSearchBar() {
 
         function implHider(addOrRemove, fullHide) {
             return function(n) {
-                var is_method = hasClass(n, "method") || fullHide;
-                if (is_method || hasClass(n, "type")) {
-                    if (is_method === true) {
+                var shouldHide =
+                    fullHide === true ||
+                    hasClass(n, "method") === true ||
+                    hasClass(n, "associatedconstant") === true;
+                if (shouldHide === true || hasClass(n, "type") === true) {
+                    if (shouldHide === true) {
                         if (addOrRemove) {
                             addClass(n, "hidden-by-impl-hider");
                         } else {
diff --git a/src/librustdoc/html/static/noscript.css b/src/librustdoc/html/static/noscript.css
index 832bd9ba2d6..ffa1a7639ab 100644
--- a/src/librustdoc/html/static/noscript.css
+++ b/src/librustdoc/html/static/noscript.css
@@ -1,3 +1,9 @@
+/*
+This whole CSS file is used only in case rustdoc is rendered with javascript disabled. Since a lot
+of content is hidden by default (depending on the settings too), we have to overwrite some of the
+rules.
+*/
+
 #main > h2 + div, #main > h2 + h3, #main > h3 + div {
 	display: block;
 }
@@ -13,3 +19,7 @@
 #main > h2 + h3 {
 	display: flex;
 }
+
+#main .impl-items .hidden {
+	display: block !important;
+}
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 8eef65a231d..62b08e519bf 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -122,7 +122,9 @@ h3.impl, h3.method, h3.type {
 h1, h2, h3, h4,
 .sidebar, a.source, .search-input, .content table td:first-child > a,
 .collapse-toggle, div.item-list .out-of-band,
-#source-sidebar, #sidebar-toggle {
+#source-sidebar, #sidebar-toggle,
+/* This selector is for the items listed in the "all items" page. */
+#main > ul.docblock > li > a {
 	font-family: "Fira Sans", sans-serif;
 }
 
@@ -1079,20 +1081,29 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
 	cursor: pointer;
 }
 
-.tooltip .tooltiptext {
-	width: 120px;
+.tooltip::after {
 	display: none;
 	text-align: center;
 	padding: 5px 3px 3px 3px;
 	border-radius: 6px;
 	margin-left: 5px;
-	top: -5px;
-	left: 105%;
-	z-index: 10;
 	font-size: 16px;
 }
 
-.tooltip .tooltiptext::after {
+.tooltip.ignore::after {
+	content: "This example is not tested";
+}
+.tooltip.compile_fail::after {
+	content: "This example deliberately fails to compile";
+}
+.tooltip.should_panic::after {
+	content: "This example panics";
+}
+.tooltip.edition::after {
+	content: "This code runs with edition " attr(data-edition);
+}
+
+.tooltip::before {
 	content: " ";
 	position: absolute;
 	top: 50%;
@@ -1100,9 +1111,10 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
 	margin-top: -5px;
 	border-width: 5px;
 	border-style: solid;
+	display: none;
 }
 
-.tooltip:hover .tooltiptext {
+.tooltip:hover::before, .tooltip:hover::after {
 	display: inline;
 }
 
@@ -1176,21 +1188,22 @@ pre.rust {
 	height: 35px;
 }
 
-#titles > div {
+#titles > button {
 	float: left;
 	width: 33.3%;
 	text-align: center;
 	font-size: 18px;
 	cursor: pointer;
+	border: 0;
 	border-top: 2px solid;
 }
 
-#titles > div:not(:last-child) {
+#titles > button:not(:last-child) {
 	margin-right: 1px;
 	width: calc(33.3% - 1px);
 }
 
-#titles > div > div.count {
+#titles > button > div.count {
 	display: inline-block;
 	font-size: 16px;
 }
@@ -1459,7 +1472,7 @@ h4 > .notable-traits {
 		top: 24px;
 	}
 
-	#titles > div > div.count {
+	#titles > button > div.count {
 		float: left;
 		width: 100%;
 	}
@@ -1565,13 +1578,17 @@ h4 > .notable-traits {
 }
 
 @media (max-width: 416px) {
-	#titles, #titles > div {
+	#titles, #titles > button {
 		height: 73px;
 	}
 
+	#main {
+		margin-top: 100px;
+	}
+
 	#main > table:not(.table-display) td {
 		word-break: break-word;
-		min-width: 10%;
+		width: 50%;
 	}
 
 	.search-container > div {
diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css
index c1f796f09e8..fd8153519af 100644
--- a/src/librustdoc/html/static/themes/ayu.css
+++ b/src/librustdoc/html/static/themes/ayu.css
@@ -388,13 +388,13 @@ pre.ignore:hover, .information:hover + pre.ignore {
 	color: #39AFD7;
 }
 
-.tooltip .tooltiptext {
+.tooltip::after {
 	background-color: #314559;
 	color: #c5c5c5;
 	border: 1px solid #5c6773;
 }
 
-.tooltip .tooltiptext::after {
+.tooltip::before {
 	border-color: transparent #314559 transparent transparent;
 }
 
@@ -403,22 +403,22 @@ pre.ignore:hover, .information:hover + pre.ignore {
 	border-color: #5c6773;
 }
 
-#titles > div.selected {
+#titles > button.selected {
 	background-color: #141920 !important;
 	border-bottom: 1px solid #ffb44c !important;
 	border-top: none;
 }
 
-#titles > div:not(.selected) {
+#titles > button:not(.selected) {
 	background-color: transparent !important;
 	border: none;
 }
 
-#titles > div:hover {
+#titles > button:hover {
 	border-bottom: 1px solid rgba(242, 151, 24, 0.3);
 }
 
-#titles > div > div.count {
+#titles > button > div.count {
 	color: #888;
 }
 
@@ -434,7 +434,7 @@ above the `@media (max-width: 700px)` rules due to a bug in the css checker */
 .block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro {}
 .content .highlighted.trait {}
 .content span.struct,.content a.struct,.block a.current.struct {}
-#titles>div:hover,#titles>div.selected {}
+#titles>button:hover,#titles>button.selected {}
 .content .highlighted.traitalias {}
 .content span.type,.content a.type,.block a.current.type {}
 .content span.union,.content a.union,.block a.current.union {}
diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css
index 946ca0a40c9..8c7794479a7 100644
--- a/src/librustdoc/html/static/themes/dark.css
+++ b/src/librustdoc/html/static/themes/dark.css
@@ -337,13 +337,13 @@ pre.ignore:hover, .information:hover + pre.ignore {
 	color: #0089ff;
 }
 
-.tooltip .tooltiptext {
+.tooltip::after {
 	background-color: #000;
 	color: #fff;
 	border-color: #000;
 }
 
-.tooltip .tooltiptext::after {
+.tooltip::before {
 	border-color: transparent black transparent transparent;
 }
 
@@ -352,16 +352,17 @@ pre.ignore:hover, .information:hover + pre.ignore {
 	border-color: #777;
 }
 
-#titles > div:not(.selected) {
+#titles > button:not(.selected) {
 	background-color: #252525;
 	border-top-color: #252525;
 }
 
-#titles > div:hover, #titles > div.selected {
+#titles > button:hover, #titles > button.selected {
 	border-top-color: #0089ff;
+	background-color: #353535;
 }
 
-#titles > div > div.count {
+#titles > button > div.count {
 	color: #888;
 }
 
diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css
index e0b9a04921a..814043b35ae 100644
--- a/src/librustdoc/html/static/themes/light.css
+++ b/src/librustdoc/html/static/themes/light.css
@@ -329,12 +329,12 @@ pre.ignore:hover, .information:hover + pre.ignore {
 	color: #0089ff;
 }
 
-.tooltip .tooltiptext {
+.tooltip::after {
 	background-color: #000;
 	color: #fff;
 }
 
-.tooltip .tooltiptext::after {
+.tooltip::before {
 	border-color: transparent black transparent transparent;
 }
 
@@ -343,16 +343,17 @@ pre.ignore:hover, .information:hover + pre.ignore {
 	border-color: #999;
 }
 
-#titles > div:not(.selected) {
+#titles > button:not(.selected) {
 	background-color: #e6e6e6;
 	border-top-color: #e6e6e6;
 }
 
-#titles > div:hover, #titles > div.selected {
+#titles > button:hover, #titles > button.selected {
+	background-color: #ffffff;
 	border-top-color: #0089ff;
 }
 
-#titles > div > div.count {
+#titles > button > div.count {
 	color: #888;
 }
 
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index afb8dfa6766..e347f7f8411 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -6,34 +6,27 @@ use std::convert::From;
 
 use rustc_ast::ast;
 use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
+use rustc_span::Pos;
 
 use crate::clean;
 use crate::doctree;
 use crate::formats::item_type::ItemType;
 use crate::json::types::*;
+use crate::json::JsonRenderer;
 
-impl From<clean::Item> for Option<Item> {
-    fn from(item: clean::Item) -> Self {
+impl JsonRenderer<'_> {
+    pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> {
         let item_type = ItemType::from(&item);
-        let clean::Item {
-            source,
-            name,
-            attrs,
-            kind,
-            visibility,
-            def_id,
-            stability: _,
-            const_stability: _,
-            deprecation,
-        } = item;
-        match kind {
+        let deprecation = item.deprecation(self.tcx);
+        let clean::Item { source, name, attrs, kind, visibility, def_id } = item;
+        match *kind {
             clean::StrippedItem(_) => None,
-            _ => Some(Item {
+            kind => Some(Item {
                 id: def_id.into(),
                 crate_id: def_id.krate.as_u32(),
-                name,
-                source: source.into(),
-                visibility: visibility.into(),
+                name: name.map(|sym| sym.to_string()),
+                source: self.convert_span(source),
+                visibility: self.convert_visibility(visibility),
                 docs: attrs.collapsed_doc_value().unwrap_or_default(),
                 links: attrs
                     .links
@@ -53,49 +46,49 @@ impl From<clean::Item> for Option<Item> {
             }),
         }
     }
-}
 
-impl From<clean::Span> for Option<Span> {
-    fn from(span: clean::Span) -> Self {
-        let clean::Span { loline, locol, hiline, hicol, .. } = span;
-        match span.filename {
-            rustc_span::FileName::Real(name) => Some(Span {
-                filename: match name {
-                    rustc_span::RealFileName::Named(path) => path,
-                    rustc_span::RealFileName::Devirtualized { local_path, virtual_name: _ } => {
-                        local_path
-                    }
-                },
-                begin: (loline, locol),
-                end: (hiline, hicol),
-            }),
+    fn convert_span(&self, span: clean::Span) -> Option<Span> {
+        match span.filename(self.sess()) {
+            rustc_span::FileName::Real(name) => {
+                let hi = span.hi(self.sess());
+                let lo = span.lo(self.sess());
+                Some(Span {
+                    filename: match name {
+                        rustc_span::RealFileName::Named(path) => path,
+                        rustc_span::RealFileName::Devirtualized { local_path, virtual_name: _ } => {
+                            local_path
+                        }
+                    },
+                    begin: (lo.line, lo.col.to_usize()),
+                    end: (hi.line, hi.col.to_usize()),
+                })
+            }
             _ => None,
         }
     }
-}
 
-impl From<clean::Deprecation> for Deprecation {
-    fn from(deprecation: clean::Deprecation) -> Self {
-        let clean::Deprecation { since, note, is_since_rustc_version: _ } = deprecation;
-        Deprecation { since, note }
-    }
-}
-
-impl From<clean::Visibility> for Visibility {
-    fn from(v: clean::Visibility) -> Self {
+    fn convert_visibility(&self, v: clean::Visibility) -> Visibility {
         use clean::Visibility::*;
         match v {
             Public => Visibility::Public,
             Inherited => Visibility::Default,
-            Restricted(did, _) if did.index == CRATE_DEF_INDEX => Visibility::Crate,
-            Restricted(did, path) => Visibility::Restricted {
+            Restricted(did) if did.index == CRATE_DEF_INDEX => Visibility::Crate,
+            Restricted(did) => Visibility::Restricted {
                 parent: did.into(),
-                path: path.to_string_no_crate_verbose(),
+                path: self.tcx.def_path(did).to_string_no_crate_verbose(),
             },
         }
     }
 }
 
+impl From<rustc_attr::Deprecation> for Deprecation {
+    fn from(deprecation: rustc_attr::Deprecation) -> Self {
+        #[rustfmt::skip]
+        let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation;
+        Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) }
+    }
+}
+
 impl From<clean::GenericArgs> for GenericArgs {
     fn from(args: clean::GenericArgs) -> Self {
         use clean::GenericArgs::*;
@@ -116,7 +109,7 @@ impl From<clean::GenericArg> for GenericArg {
     fn from(arg: clean::GenericArg) -> Self {
         use clean::GenericArg::*;
         match arg {
-            Lifetime(l) => GenericArg::Lifetime(l.0),
+            Lifetime(l) => GenericArg::Lifetime(l.0.to_string()),
             Type(t) => GenericArg::Type(t.into()),
             Const(c) => GenericArg::Const(c.into()),
         }
@@ -132,7 +125,7 @@ impl From<clean::Constant> for Constant {
 
 impl From<clean::TypeBinding> for TypeBinding {
     fn from(binding: clean::TypeBinding) -> Self {
-        TypeBinding { name: binding.name, binding: binding.kind.into() }
+        TypeBinding { name: binding.name.to_string(), binding: binding.kind.into() }
     }
 }
 
@@ -159,7 +152,9 @@ impl From<clean::ItemKind> for ItemEnum {
         use clean::ItemKind::*;
         match item {
             ModuleItem(m) => ItemEnum::ModuleItem(m.into()),
-            ExternCrateItem(c, a) => ItemEnum::ExternCrateItem { name: c, rename: a },
+            ExternCrateItem(c, a) => {
+                ItemEnum::ExternCrateItem { name: c.to_string(), rename: a.map(|x| x.to_string()) }
+            }
             ImportItem(i) => ItemEnum::ImportItem(i.into()),
             StructItem(s) => ItemEnum::StructItem(s.into()),
             UnionItem(u) => ItemEnum::StructItem(u.into()),
@@ -271,7 +266,7 @@ impl From<clean::Generics> for Generics {
 
 impl From<clean::GenericParamDef> for GenericParamDef {
     fn from(generic_param: clean::GenericParamDef) -> Self {
-        GenericParamDef { name: generic_param.name, kind: generic_param.kind.into() }
+        GenericParamDef { name: generic_param.name.to_string(), kind: generic_param.kind.into() }
     }
 }
 
@@ -298,7 +293,7 @@ impl From<clean::WherePredicate> for WherePredicate {
                 bounds: bounds.into_iter().map(Into::into).collect(),
             },
             RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate {
-                lifetime: lifetime.0,
+                lifetime: lifetime.0.to_string(),
                 bounds: bounds.into_iter().map(Into::into).collect(),
             },
             EqPredicate { lhs, rhs } => {
@@ -319,7 +314,7 @@ impl From<clean::GenericBound> for GenericBound {
                     modifier: modifier.into(),
                 }
             }
-            Outlives(lifetime) => GenericBound::Outlives(lifetime.0),
+            Outlives(lifetime) => GenericBound::Outlives(lifetime.0.to_string()),
         }
     }
 }
@@ -347,7 +342,7 @@ impl From<clean::Type> for Type {
                     .map(|v| v.into_iter().map(Into::into).collect())
                     .unwrap_or_default(),
             },
-            Generic(s) => Type::Generic(s),
+            Generic(s) => Type::Generic(s.to_string()),
             Primitive(p) => Type::Primitive(p.as_str().to_string()),
             BareFunction(f) => Type::FunctionPointer(Box::new((*f).into())),
             Tuple(t) => Type::Tuple(t.into_iter().map(Into::into).collect()),
@@ -361,12 +356,12 @@ impl From<clean::Type> for Type {
                 type_: Box::new((*type_).into()),
             },
             BorrowedRef { lifetime, mutability, type_ } => Type::BorrowedRef {
-                lifetime: lifetime.map(|l| l.0),
+                lifetime: lifetime.map(|l| l.0.to_string()),
                 mutable: mutability == ast::Mutability::Mut,
                 type_: Box::new((*type_).into()),
             },
             QPath { name, self_type, trait_ } => Type::QualifiedPath {
-                name,
+                name: name.to_string(),
                 self_type: Box::new((*self_type).into()),
                 trait_: Box::new((*trait_).into()),
             },
@@ -390,7 +385,11 @@ impl From<clean::FnDecl> for FnDecl {
     fn from(decl: clean::FnDecl) -> Self {
         let clean::FnDecl { inputs, output, c_variadic, attrs: _ } = decl;
         FnDecl {
-            inputs: inputs.values.into_iter().map(|arg| (arg.name, arg.type_.into())).collect(),
+            inputs: inputs
+                .values
+                .into_iter()
+                .map(|arg| (arg.name.to_string(), arg.type_.into()))
+                .collect(),
             output: match output {
                 clean::FnRetTy::Return(t) => Some(t.into()),
                 clean::FnRetTy::DefaultReturn => None,
@@ -430,7 +429,10 @@ impl From<clean::Impl> for Impl {
         Impl {
             is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe,
             generics: generics.into(),
-            provided_trait_methods: provided_trait_methods.into_iter().collect(),
+            provided_trait_methods: provided_trait_methods
+                .into_iter()
+                .map(|x| x.to_string())
+                .collect(),
             trait_: trait_.map(Into::into),
             for_: for_.into(),
             items: ids(items),
@@ -495,7 +497,7 @@ impl From<clean::Import> for Import {
         match import.kind {
             Simple(s) => Import {
                 span: import.source.path.whole_name(),
-                name: s,
+                name: s.to_string(),
                 id: import.source.did.map(Into::into),
                 glob: false,
             },
@@ -511,7 +513,10 @@ impl From<clean::Import> for Import {
 
 impl From<clean::ProcMacro> for ProcMacro {
     fn from(mac: clean::ProcMacro) -> Self {
-        ProcMacro { kind: mac.kind.into(), helpers: mac.helpers }
+        ProcMacro {
+            kind: mac.kind.into(),
+            helpers: mac.helpers.iter().map(|x| x.to_string()).collect(),
+        }
     }
 }
 
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 5f640bfddf1..df7ab9b7361 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -13,6 +13,8 @@ use std::path::PathBuf;
 use std::rc::Rc;
 
 use rustc_data_structures::fx::FxHashMap;
+use rustc_middle::ty;
+use rustc_session::Session;
 use rustc_span::edition::Edition;
 
 use crate::clean;
@@ -23,7 +25,8 @@ use crate::formats::FormatRenderer;
 use crate::html::render::cache::ExternalLocation;
 
 #[derive(Clone)]
-crate struct JsonRenderer {
+crate struct JsonRenderer<'tcx> {
+    tcx: ty::TyCtxt<'tcx>,
     /// A mapping of IDs that contains all local items for this crate which gets output as a top
     /// level field of the JSON blob.
     index: Rc<RefCell<FxHashMap<types::Id, types::Item>>>,
@@ -31,7 +34,11 @@ crate struct JsonRenderer {
     out_path: PathBuf,
 }
 
-impl JsonRenderer {
+impl JsonRenderer<'_> {
+    fn sess(&self) -> &Session {
+        self.tcx.sess
+    }
+
     fn get_trait_implementors(
         &mut self,
         id: rustc_span::def_id::DefId,
@@ -117,17 +124,19 @@ impl JsonRenderer {
     }
 }
 
-impl FormatRenderer for JsonRenderer {
+impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
     fn init(
         krate: clean::Crate,
         options: RenderOptions,
         _render_info: RenderInfo,
         _edition: Edition,
         _cache: &mut Cache,
+        tcx: ty::TyCtxt<'tcx>,
     ) -> Result<(Self, clean::Crate), Error> {
         debug!("Initializing json renderer");
         Ok((
             JsonRenderer {
+                tcx,
                 index: Rc::new(RefCell::new(FxHashMap::default())),
                 out_path: options.output,
             },
@@ -143,7 +152,7 @@ impl FormatRenderer for JsonRenderer {
         item.kind.inner_items().for_each(|i| self.item(i.clone(), cache).unwrap());
 
         let id = item.def_id;
-        if let Some(mut new_item) = item.into(): Option<types::Item> {
+        if let Some(mut new_item) = self.convert_item(item) {
             if let types::ItemEnum::TraitItem(ref mut t) = new_item.inner {
                 t.implementors = self.get_trait_implementors(id, cache)
             } else if let types::ItemEnum::StructItem(ref mut s) = new_item.inner {
@@ -169,9 +178,9 @@ impl FormatRenderer for JsonRenderer {
         cache: &Cache,
     ) -> Result<(), Error> {
         use clean::types::ItemKind::*;
-        if let ModuleItem(m) = &item.kind {
+        if let ModuleItem(m) = &*item.kind {
             for item in &m.items {
-                match &item.kind {
+                match &*item.kind {
                     // These don't have names so they don't get added to the output by default
                     ImportItem(_) => self.item(item.clone(), cache).unwrap(),
                     ExternCrateItem(_, _) => self.item(item.clone(), cache).unwrap(),
@@ -218,7 +227,7 @@ impl FormatRenderer for JsonRenderer {
                     (
                         k.as_u32(),
                         types::ExternalCrate {
-                            name: v.0.clone(),
+                            name: v.0.to_string(),
                             html_root_url: match &v.2 {
                                 ExternalLocation::Remote(s) => Some(s.clone()),
                                 _ => None,
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 26bf4b569ff..7ed64c5813f 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -16,6 +16,8 @@
 #![feature(once_cell)]
 #![feature(type_ascription)]
 #![feature(split_inclusive)]
+#![feature(str_split_once)]
+#![feature(iter_intersperse)]
 #![recursion_limit = "256"]
 
 #[macro_use]
@@ -61,7 +63,10 @@ use std::default::Default;
 use std::env;
 use std::process;
 
+use rustc_driver::abort_on_err;
 use rustc_errors::ErrorReported;
+use rustc_interface::interface;
+use rustc_middle::ty;
 use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup};
 use rustc_session::getopts;
 use rustc_session::{early_error, early_warn};
@@ -114,21 +119,9 @@ fn get_args() -> Option<Vec<String>> {
         .collect()
 }
 
-fn stable<F>(name: &'static str, f: F) -> RustcOptGroup
-where
-    F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
-{
-    RustcOptGroup::stable(name, f)
-}
-
-fn unstable<F>(name: &'static str, f: F) -> RustcOptGroup
-where
-    F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
-{
-    RustcOptGroup::unstable(name, f)
-}
-
 fn opts() -> Vec<RustcOptGroup> {
+    let stable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::stable;
+    let unstable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::unstable;
     vec![
         stable("h", |o| o.optflag("h", "help", "show this help message")),
         stable("V", |o| o.optflag("V", "version", "print rustdoc's version")),
@@ -271,13 +264,13 @@ fn opts() -> Vec<RustcOptGroup> {
                 "sort modules by where they appear in the program, rather than alphabetically",
             )
         }),
-        unstable("default-theme", |o| {
+        stable("default-theme", |o| {
             o.optopt(
                 "",
                 "default-theme",
                 "Set the default theme. THEME should be the theme name, generally lowercase. \
                  If an unknown default theme is specified, the builtin default is used. \
-                 The set of themes, and the rustdoc built-in default is not stable.",
+                 The set of themes, and the rustdoc built-in default, are not stable.",
                 "THEME",
             )
         }),
@@ -477,14 +470,15 @@ fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainRes
     }
 }
 
-fn run_renderer<T: formats::FormatRenderer>(
+fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
     krate: clean::Crate,
     renderopts: config::RenderOptions,
     render_info: config::RenderInfo,
     diag: &rustc_errors::Handler,
     edition: rustc_span::edition::Edition,
+    tcx: ty::TyCtxt<'tcx>,
 ) -> MainResult {
-    match formats::run_format::<T>(krate, renderopts, render_info, &diag, edition) {
+    match formats::run_format::<T>(krate, renderopts, render_info, &diag, edition, tcx) {
         Ok(_) => Ok(()),
         Err(e) => {
             let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error));
@@ -527,37 +521,81 @@ fn main_options(options: config::Options) -> MainResult {
     // compiler all the way through the analysis passes. The rustdoc output is
     // then generated from the cleaned AST of the crate. This runs all the
     // plug/cleaning passes.
-    let crate_name = options.crate_name.clone();
     let crate_version = options.crate_version.clone();
+
+    let default_passes = options.default_passes;
     let output_format = options.output_format;
-    let (mut krate, renderinfo, renderopts, sess) = core::run_core(options);
+    // 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);
 
-    info!("finished with rustc");
+    interface::create_compiler_and_run(config, |compiler| {
+        compiler.enter(|queries| {
+            let sess = compiler.session();
 
-    if let Some(name) = crate_name {
-        krate.name = name
-    }
+            // 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(externs, queries, &sess);
 
-    krate.version = crate_version;
+            if sess.has_errors() {
+                sess.fatal("Compilation failed, aborting rustdoc");
+            }
 
-    if show_coverage {
-        // if we ran coverage, bail early, we don't need to also generate docs at this point
-        // (also we didn't load in any of the useful passes)
-        return Ok(());
-    } else if run_check {
-        // Since we're in "check" mode, no need to generate anything beyond this point.
-        return Ok(());
-    }
+            let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take();
 
-    info!("going to format");
-    let (error_format, edition, debugging_options) = diag_opts;
-    let diag = core::new_handler(error_format, None, &debugging_options);
-    match output_format {
-        None | Some(config::OutputFormat::Html) => sess.time("render_html", || {
-            run_renderer::<html::render::Context>(krate, renderopts, renderinfo, &diag, edition)
-        }),
-        Some(config::OutputFormat::Json) => sess.time("render_json", || {
-            run_renderer::<json::JsonRenderer>(krate, renderopts, renderinfo, &diag, edition)
-        }),
-    }
+            global_ctxt.enter(|tcx| {
+                let (mut krate, render_info, render_opts) = sess.time("run_global_ctxt", || {
+                    core::run_global_ctxt(
+                        tcx,
+                        resolver,
+                        default_passes,
+                        manual_passes,
+                        render_options,
+                        output_format,
+                    )
+                });
+                info!("finished with rustc");
+
+                krate.version = crate_version;
+
+                if show_coverage {
+                    // if we ran coverage, bail early, we don't need to also generate docs at this point
+                    // (also we didn't load in any of the useful passes)
+                    return Ok(());
+                } else if run_check {
+                    // Since we're in "check" mode, no need to generate anything beyond this point.
+                    return Ok(());
+                }
+
+                info!("going to format");
+                let (error_format, edition, debugging_options) = diag_opts;
+                let diag = core::new_handler(error_format, None, &debugging_options);
+                match output_format {
+                    None | Some(config::OutputFormat::Html) => sess.time("render_html", || {
+                        run_renderer::<html::render::Context<'_>>(
+                            krate,
+                            render_opts,
+                            render_info,
+                            &diag,
+                            edition,
+                            tcx,
+                        )
+                    }),
+                    Some(config::OutputFormat::Json) => sess.time("render_json", || {
+                        run_renderer::<json::JsonRenderer<'_>>(
+                            krate,
+                            render_opts,
+                            render_info,
+                            &diag,
+                            edition,
+                            tcx,
+                        )
+                    }),
+                }
+            })
+        })
+    })
 }
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs
index 3f9978c8fca..0a00323a317 100644
--- a/src/librustdoc/passes/calculate_doc_coverage.rs
+++ b/src/librustdoc/passes/calculate_doc_coverage.rs
@@ -5,7 +5,7 @@ use crate::html::markdown::{find_testable_code, ErrorCodes};
 use crate::passes::doc_test_lints::{should_have_doc_example, Tests};
 use crate::passes::Pass;
 use rustc_lint::builtin::MISSING_DOCS;
-use rustc_middle::lint::LintSource;
+use rustc_middle::lint::LintLevelSource;
 use rustc_session::lint;
 use rustc_span::symbol::sym;
 use rustc_span::FileName;
@@ -187,7 +187,7 @@ impl<'a, 'b> CoverageCalculator<'a, 'b> {
 
 impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> {
     fn fold_item(&mut self, i: clean::Item) -> Option<clean::Item> {
-        match i.kind {
+        match *i.kind {
             _ if !i.def_id.is_local() => {
                 // non-local items are skipped because they can be out of the users control,
                 // especially in the case of trait impls, which rustdoc eagerly inlines
@@ -216,13 +216,9 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> {
                 return Some(i);
             }
             clean::ImplItem(ref impl_) => {
+                let filename = i.source.filename(self.ctx.sess());
                 if let Some(ref tr) = impl_.trait_ {
-                    debug!(
-                        "impl {:#} for {:#} in {}",
-                        tr.print(),
-                        impl_.for_.print(),
-                        i.source.filename
-                    );
+                    debug!("impl {:#} for {:#} in {}", tr.print(), impl_.for_.print(), filename,);
 
                     // don't count trait impls, the missing-docs lint doesn't so we shouldn't
                     // either
@@ -231,7 +227,7 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> {
                     // inherent impls *can* be documented, and those docs show up, but in most
                     // cases it doesn't make sense, as all methods on a type are in one single
                     // impl block
-                    debug!("impl {:#} in {}", impl_.for_.print(), i.source.filename);
+                    debug!("impl {:#} in {}", impl_.for_.print(), filename);
                 }
             }
             _ => {
@@ -251,15 +247,16 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> {
                     None,
                 );
 
+                let filename = i.source.filename(self.ctx.sess());
                 let has_doc_example = tests.found_tests != 0;
                 let hir_id = self.ctx.tcx.hir().local_def_id_to_hir_id(i.def_id.expect_local());
                 let (level, source) = self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id);
                 // `missing_docs` is allow-by-default, so don't treat this as ignoring the item
                 // unless the user had an explicit `allow`
                 let should_have_docs =
-                    level != lint::Level::Allow || matches!(source, LintSource::Default);
-                debug!("counting {:?} {:?} in {}", i.type_(), i.name, i.source.filename);
-                self.items.entry(i.source.filename.clone()).or_default().count_item(
+                    level != lint::Level::Allow || matches!(source, LintLevelSource::Default);
+                debug!("counting {:?} {:?} in {}", i.type_(), i.name, filename);
+                self.items.entry(filename).or_default().count_item(
                     has_docs,
                     has_doc_example,
                     should_have_doc_example(self.ctx, &i),
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 551c086a8d4..9f15038a353 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -3,24 +3,23 @@
 //! [RFC 1946]: https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md
 
 use rustc_ast as ast;
-use rustc_data_structures::stable_set::FxHashSet;
+use rustc_data_structures::{fx::FxHashMap, stable_set::FxHashSet};
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_expand::base::SyntaxExtensionKind;
 use rustc_hir as hir;
 use rustc_hir::def::{
     DefKind,
     Namespace::{self, *},
-    PerNS, Res,
+    PerNS,
 };
 use rustc_hir::def_id::{CrateNum, DefId};
-use rustc_middle::ty;
+use rustc_middle::{bug, ty};
 use rustc_resolve::ParentScope;
 use rustc_session::lint::{
     builtin::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS},
     Lint,
 };
 use rustc_span::hygiene::MacroKind;
-use rustc_span::symbol::sym;
 use rustc_span::symbol::Ident;
 use rustc_span::symbol::Symbol;
 use rustc_span::DUMMY_SP;
@@ -28,10 +27,11 @@ use smallvec::{smallvec, SmallVec};
 
 use std::borrow::Cow;
 use std::cell::Cell;
+use std::convert::{TryFrom, TryInto};
 use std::mem;
 use std::ops::Range;
 
-use crate::clean::{self, Crate, GetDefId, Item, ItemLink, PrimitiveType};
+use crate::clean::{self, utils::find_nearest_parent_module, Crate, Item, ItemLink, PrimitiveType};
 use crate::core::DocContext;
 use crate::fold::DocFolder;
 use crate::html::markdown::markdown_links;
@@ -61,6 +61,71 @@ impl<'a> From<ResolutionFailure<'a>> for ErrorKind<'a> {
     }
 }
 
+#[derive(Copy, Clone, Debug, Hash)]
+enum Res {
+    Def(DefKind, DefId),
+    Primitive(PrimitiveType),
+}
+
+type ResolveRes = rustc_hir::def::Res<rustc_ast::NodeId>;
+
+impl Res {
+    fn descr(self) -> &'static str {
+        match self {
+            Res::Def(kind, id) => ResolveRes::Def(kind, id).descr(),
+            Res::Primitive(_) => "builtin type",
+        }
+    }
+
+    fn article(self) -> &'static str {
+        match self {
+            Res::Def(kind, id) => ResolveRes::Def(kind, id).article(),
+            Res::Primitive(_) => "a",
+        }
+    }
+
+    fn name(self, tcx: ty::TyCtxt<'_>) -> String {
+        match self {
+            Res::Def(_, id) => tcx.item_name(id).to_string(),
+            Res::Primitive(prim) => prim.as_str().to_string(),
+        }
+    }
+
+    fn def_id(self) -> DefId {
+        self.opt_def_id().expect("called def_id() on a primitive")
+    }
+
+    fn opt_def_id(self) -> Option<DefId> {
+        match self {
+            Res::Def(_, id) => Some(id),
+            Res::Primitive(_) => None,
+        }
+    }
+
+    fn as_hir_res(self) -> Option<rustc_hir::def::Res> {
+        match self {
+            Res::Def(kind, id) => Some(rustc_hir::def::Res::Def(kind, id)),
+            // FIXME: maybe this should handle the subset of PrimitiveType that fits into hir::PrimTy?
+            Res::Primitive(_) => None,
+        }
+    }
+}
+
+impl TryFrom<ResolveRes> for Res {
+    type Error = ();
+
+    fn try_from(res: ResolveRes) -> Result<Self, ()> {
+        use rustc_hir::def::Res::*;
+        match res {
+            Def(kind, id) => Ok(Res::Def(kind, id)),
+            PrimTy(prim) => Ok(Res::Primitive(PrimitiveType::from_hir(prim))),
+            // e.g. `#[derive]`
+            NonMacroAttr(..) | Err => Result::Err(()),
+            other => bug!("unrecognized res {:?}", other),
+        }
+    }
+}
+
 #[derive(Debug)]
 /// A link failed to resolve.
 enum ResolutionFailure<'a> {
@@ -168,6 +233,27 @@ enum AnchorFailure {
     RustdocAnchorConflict(Res),
 }
 
+#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+struct ResolutionInfo {
+    module_id: DefId,
+    dis: Option<Disambiguator>,
+    path_str: String,
+    extra_fragment: Option<String>,
+}
+
+struct DiagnosticInfo<'a> {
+    item: &'a Item,
+    dox: &'a str,
+    ori_link: &'a str,
+    link_range: Option<Range<usize>>,
+}
+
+#[derive(Clone, Debug, Hash)]
+struct CachedLink {
+    pub res: (Res, Option<String>),
+    pub side_channel: Option<(DefKind, DefId)>,
+}
+
 struct LinkCollector<'a, 'tcx> {
     cx: &'a DocContext<'tcx>,
     /// A stack of modules used to decide what scope to resolve in.
@@ -179,11 +265,18 @@ struct LinkCollector<'a, 'tcx> {
     /// because `clean` and the disambiguator code expect them to be different.
     /// See the code for associated items on inherent impls for details.
     kind_side_channel: Cell<Option<(DefKind, DefId)>>,
+    /// Cache the resolved links so we can avoid resolving (and emitting errors for) the same link
+    visited_links: FxHashMap<ResolutionInfo, CachedLink>,
 }
 
 impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
     fn new(cx: &'a DocContext<'tcx>) -> Self {
-        LinkCollector { cx, mod_ids: Vec::new(), kind_side_channel: Cell::new(None) }
+        LinkCollector {
+            cx,
+            mod_ids: Vec::new(),
+            kind_side_channel: Cell::new(None),
+            visited_links: FxHashMap::default(),
+        }
     }
 
     /// Given a full link, parse it as an [enum struct variant].
@@ -225,12 +318,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
             .enter_resolver(|resolver| {
                 resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id)
             })
-            .map(|(_, res)| res)
-            .unwrap_or(Res::Err);
-        if let Res::Err = ty_res {
-            return Err(no_res().into());
-        }
-        let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
+            .and_then(|(_, res)| res.try_into())
+            .map_err(|()| no_res())?;
+
         match ty_res {
             Res::Def(DefKind::Enum, did) => {
                 if cx
@@ -281,7 +371,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
     /// lifetimes on `&'path` will work.
     fn resolve_primitive_associated_item(
         &self,
-        prim_ty: hir::PrimTy,
+        prim_ty: PrimitiveType,
         ns: Namespace,
         module_id: DefId,
         item_name: Symbol,
@@ -289,7 +379,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
     ) -> Result<(Res, Option<String>), ErrorKind<'path>> {
         let cx = self.cx;
 
-        PrimitiveType::from_hir(prim_ty)
+        prim_ty
             .impls(cx.tcx)
             .into_iter()
             .find_map(|&impl_| {
@@ -308,21 +398,21 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                     })
                     .map(|out| {
                         (
-                            Res::PrimTy(prim_ty),
-                            Some(format!("{}#{}.{}", prim_ty.name(), out, item_str)),
+                            Res::Primitive(prim_ty),
+                            Some(format!("{}#{}.{}", prim_ty.as_str(), out, item_str)),
                         )
                     })
             })
             .ok_or_else(|| {
                 debug!(
                     "returning primitive error for {}::{} in {} namespace",
-                    prim_ty.name(),
+                    prim_ty.as_str(),
                     item_name,
                     ns.descr()
                 );
                 ResolutionFailure::NotResolved {
                     module_id,
-                    partial_res: Some(Res::PrimTy(prim_ty)),
+                    partial_res: Some(Res::Primitive(prim_ty)),
                     unresolved: item_str.into(),
                 }
                 .into()
@@ -349,19 +439,18 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                 false,
             ) {
                 if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind {
-                    return Ok(res.map_id(|_| panic!("unexpected id")));
+                    return Ok(res.try_into().unwrap());
                 }
             }
-            if let Some(res) = resolver.all_macros().get(&Symbol::intern(path_str)) {
-                return Ok(res.map_id(|_| panic!("unexpected id")));
+            if let Some(&res) = resolver.all_macros().get(&Symbol::intern(path_str)) {
+                return Ok(res.try_into().unwrap());
             }
             debug!("resolving {} as a macro in the module {:?}", path_str, module_id);
             if let Ok((_, res)) =
                 resolver.resolve_str_path_error(DUMMY_SP, path_str, MacroNS, module_id)
             {
                 // don't resolve builtins like `#[derive]`
-                if let Res::Def(..) = res {
-                    let res = res.map_id(|_| panic!("unexpected node_id"));
+                if let Ok(res) = res.try_into() {
                     return Ok(res);
                 }
             }
@@ -380,14 +469,16 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
     /// Associated items will never be resolved by this function.
     fn resolve_path(&self, path_str: &str, ns: Namespace, module_id: DefId) -> Option<Res> {
         let result = self.cx.enter_resolver(|resolver| {
-            resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id)
+            resolver
+                .resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id)
+                .and_then(|(_, res)| res.try_into())
         });
         debug!("{} resolved to {:?} in namespace {:?}", path_str, result, ns);
-        match result.map(|(_, res)| res) {
-            // resolver doesn't know about true and false so we'll have to resolve them
+        match result {
+            // resolver doesn't know about true, false, and types that aren't paths (e.g. `()`)
             // manually as bool
-            Ok(Res::Err) | Err(()) => is_bool_value(path_str, ns).map(|(_, res)| res),
-            Ok(res) => Some(res.map_id(|_| panic!("unexpected node_id"))),
+            Err(()) => resolve_primitive(path_str, ns),
+            Ok(res) => Some(res),
         }
     }
 
@@ -416,13 +507,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                     return handle_variant(cx, res, extra_fragment);
                 }
                 // Not a trait item; just return what we found.
-                Res::PrimTy(ty) => {
+                Res::Primitive(ty) => {
                     if extra_fragment.is_some() {
                         return Err(ErrorKind::AnchorFailure(
                             AnchorFailure::RustdocAnchorConflict(res),
                         ));
                     }
-                    return Ok((res, Some(ty.name_str().to_owned())));
+                    return Ok((res, Some(ty.as_str().to_owned())));
                 }
                 Res::Def(DefKind::Mod, _) => {
                     return Ok((res, extra_fragment.clone()));
@@ -435,8 +526,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
 
         // Try looking for methods and associated items.
         let mut split = path_str.rsplitn(2, "::");
-        // this can be an `unwrap()` because we ensure the link is never empty
-        let (item_str, item_name) = split.next().map(|i| (i, Symbol::intern(i))).unwrap();
+        // NB: `split`'s first element is always defined, even if the delimiter was not present.
+        // NB: `item_str` could be empty when resolving in the root namespace (e.g. `::std`).
+        let item_str = split.next().unwrap();
+        let item_name = Symbol::intern(item_str);
         let path_root = split
             .next()
             .map(|f| f.to_owned())
@@ -453,7 +546,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
 
         // FIXME: are these both necessary?
         let ty_res = if let Some(ty_res) = resolve_primitive(&path_root, TypeNS)
-            .map(|(_, res)| res)
             .or_else(|| self.resolve_path(&path_root, TypeNS, module_id))
         {
             ty_res
@@ -472,7 +564,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
         };
 
         let res = match ty_res {
-            Res::PrimTy(prim) => Some(
+            Res::Primitive(prim) => Some(
                 self.resolve_primitive_associated_item(prim, ns, module_id, item_name, item_str),
             ),
             Res::Def(
@@ -655,78 +747,23 @@ fn resolve_associated_trait_item(
     ns: Namespace,
     cx: &DocContext<'_>,
 ) -> Option<(ty::AssocKind, DefId)> {
-    let ty = cx.tcx.type_of(did);
-    // First consider blanket impls: `impl From<T> for T`
-    let implicit_impls = crate::clean::get_auto_trait_and_blanket_impls(cx, ty, did);
-    let mut candidates: Vec<_> = implicit_impls
-        .flat_map(|impl_outer| {
-            match impl_outer.kind {
-                clean::ImplItem(impl_) => {
-                    debug!("considering auto or blanket impl for trait {:?}", impl_.trait_);
-                    // Give precedence to methods that were overridden
-                    if !impl_.provided_trait_methods.contains(&*item_name.as_str()) {
-                        let mut items = impl_.items.into_iter().filter_map(|assoc| {
-                            if assoc.name.as_deref() != Some(&*item_name.as_str()) {
-                                return None;
-                            }
-                            let kind = assoc
-                                .kind
-                                .as_assoc_kind()
-                                .expect("inner items for a trait should be associated items");
-                            if kind.namespace() != ns {
-                                return None;
-                            }
-
-                            trace!("considering associated item {:?}", assoc.kind);
-                            // We have a slight issue: normal methods come from `clean` types,
-                            // but provided methods come directly from `tcx`.
-                            // Fortunately, we don't need the whole method, we just need to know
-                            // what kind of associated item it is.
-                            Some((kind, assoc.def_id))
-                        });
-                        let assoc = items.next();
-                        debug_assert_eq!(items.count(), 0);
-                        assoc
-                    } else {
-                        // These are provided methods or default types:
-                        // ```
-                        // trait T {
-                        //   type A = usize;
-                        //   fn has_default() -> A { 0 }
-                        // }
-                        // ```
-                        let trait_ = impl_.trait_.unwrap().def_id().unwrap();
-                        cx.tcx
-                            .associated_items(trait_)
-                            .find_by_name_and_namespace(
-                                cx.tcx,
-                                Ident::with_dummy_span(item_name),
-                                ns,
-                                trait_,
-                            )
-                            .map(|assoc| (assoc.kind, assoc.def_id))
-                    }
-                }
-                _ => panic!("get_impls returned something that wasn't an impl"),
-            }
-        })
-        .collect();
+    // FIXME: this should also consider blanket impls (`impl<T> X for T`). Unfortunately
+    // `get_auto_trait_and_blanket_impls` is broken because the caching behavior is wrong. In the
+    // meantime, just don't look for these blanket impls.
 
     // Next consider explicit impls: `impl MyTrait for MyType`
     // Give precedence to inherent impls.
-    if candidates.is_empty() {
-        let traits = traits_implemented_by(cx, did, module);
-        debug!("considering traits {:?}", traits);
-        candidates.extend(traits.iter().filter_map(|&trait_| {
-            cx.tcx
-                .associated_items(trait_)
-                .find_by_name_and_namespace(cx.tcx, Ident::with_dummy_span(item_name), ns, trait_)
-                .map(|assoc| (assoc.kind, assoc.def_id))
-        }));
-    }
+    let traits = traits_implemented_by(cx, did, module);
+    debug!("considering traits {:?}", traits);
+    let mut candidates = traits.iter().filter_map(|&trait_| {
+        cx.tcx
+            .associated_items(trait_)
+            .find_by_name_and_namespace(cx.tcx, Ident::with_dummy_span(item_name), ns, trait_)
+            .map(|assoc| (assoc.kind, assoc.def_id))
+    });
     // FIXME(#74563): warn about ambiguity
-    debug!("the candidates were {:?}", candidates);
-    candidates.pop()
+    debug!("the candidates were {:?}", candidates.clone().collect::<Vec<_>>());
+    candidates.next()
 }
 
 /// Given a type, return all traits in scope in `module` implemented by that type.
@@ -778,11 +815,14 @@ fn traits_implemented_by(cx: &DocContext<'_>, type_: DefId, module: DefId) -> Fx
 ///
 /// These are common and we should just resolve to the trait in that case.
 fn is_derive_trait_collision<T>(ns: &PerNS<Result<(Res, T), ResolutionFailure<'_>>>) -> bool {
-    matches!(*ns, PerNS {
-        type_ns: Ok((Res::Def(DefKind::Trait, _), _)),
-        macro_ns: Ok((Res::Def(DefKind::Macro(MacroKind::Derive), _), _)),
-        ..
-    })
+    matches!(
+        *ns,
+        PerNS {
+            type_ns: Ok((Res::Def(DefKind::Trait, _), _)),
+            macro_ns: Ok((Res::Def(DefKind::Macro(MacroKind::Derive), _), _)),
+            ..
+        }
+    )
 }
 
 impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
@@ -790,31 +830,9 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
         use rustc_middle::ty::DefIdTree;
 
         let parent_node = if item.is_fake() {
-            // FIXME: is this correct?
             None
-        // If we're documenting the crate root itself, it has no parent. Use the root instead.
-        } else if item.def_id.is_top_level_module() {
-            Some(item.def_id)
         } else {
-            let mut current = item.def_id;
-            // The immediate parent might not always be a module.
-            // Find the first parent which is.
-            loop {
-                if let Some(parent) = self.cx.tcx.parent(current) {
-                    if self.cx.tcx.def_kind(parent) == DefKind::Mod {
-                        break Some(parent);
-                    }
-                    current = parent;
-                } else {
-                    debug!(
-                        "{:?} has no parent (kind={:?}, original was {:?})",
-                        current,
-                        self.cx.tcx.def_kind(current),
-                        item.def_id
-                    );
-                    break None;
-                }
-            }
+            find_nearest_parent_module(self.cx.tcx, item.def_id)
         };
 
         if parent_node.is_some() {
@@ -935,7 +953,7 @@ impl LinkCollector<'_, '_> {
     ///
     /// FIXME(jynelson): this is way too many arguments
     fn resolve_link(
-        &self,
+        &mut self,
         item: &Item,
         dox: &str,
         self_name: &Option<String>,
@@ -960,6 +978,7 @@ impl LinkCollector<'_, '_> {
         let link = ori_link.replace("`", "");
         let parts = link.split('#').collect::<Vec<_>>();
         let (link, extra_fragment) = if parts.len() > 2 {
+            // A valid link can't have multiple #'s
             anchor_failure(cx, &item, &link, dox, link_range, AnchorFailure::MultipleAnchors);
             return None;
         } else if parts.len() == 2 {
@@ -979,7 +998,7 @@ impl LinkCollector<'_, '_> {
             (link.trim(), None)
         };
 
-        if path_str.contains(|ch: char| !(ch.is_alphanumeric() || ":_<>, !".contains(ch))) {
+        if path_str.contains(|ch: char| !(ch.is_alphanumeric() || ":_<>, !*&;".contains(ch))) {
             return None;
         }
 
@@ -1010,7 +1029,6 @@ impl LinkCollector<'_, '_> {
         } else {
             // This is a bug.
             debug!("attempting to resolve item without parent module: {}", path_str);
-            let err_kind = ResolutionFailure::NoParentItem.into();
             resolution_failure(
                 self,
                 &item,
@@ -1018,7 +1036,7 @@ impl LinkCollector<'_, '_> {
                 disambiguator,
                 dox,
                 link_range,
-                smallvec![err_kind],
+                smallvec![ResolutionFailure::NoParentItem],
             );
             return None;
         };
@@ -1068,22 +1086,20 @@ impl LinkCollector<'_, '_> {
         // Sanity check to make sure we don't have any angle brackets after stripping generics.
         assert!(!path_str.contains(['<', '>'].as_slice()));
 
-        // The link is not an intra-doc link if it still contains commas or spaces after
-        // stripping generics.
-        if path_str.contains([',', ' '].as_slice()) {
+        // The link is not an intra-doc link if it still contains spaces after stripping generics.
+        if path_str.contains(' ') {
             return None;
         }
 
-        let (mut res, mut fragment) = self.resolve_with_disambiguator(
-            disambiguator,
-            item,
-            dox,
-            path_str,
+        let key = ResolutionInfo {
             module_id,
+            dis: disambiguator,
+            path_str: path_str.to_owned(),
             extra_fragment,
-            &ori_link,
-            link_range.clone(),
-        )?;
+        };
+        let diag =
+            DiagnosticInfo { item, dox, ori_link: &ori_link, link_range: link_range.clone() };
+        let (mut res, mut fragment) = self.resolve_with_disambiguator_cached(key, diag)?;
 
         // Check for a primitive which might conflict with a module
         // Report the ambiguity and require that the user specify which one they meant.
@@ -1091,9 +1107,9 @@ impl LinkCollector<'_, '_> {
         if matches!(
             disambiguator,
             None | Some(Disambiguator::Namespace(Namespace::TypeNS) | Disambiguator::Primitive)
-        ) && !matches!(res, Res::PrimTy(_))
+        ) && !matches!(res, Res::Primitive(_))
         {
-            if let Some((path, prim)) = resolve_primitive(path_str, TypeNS) {
+            if let Some(prim) = resolve_primitive(path_str, TypeNS) {
                 // `prim@char`
                 if matches!(disambiguator, Some(Disambiguator::Primitive)) {
                     if fragment.is_some() {
@@ -1108,7 +1124,7 @@ impl LinkCollector<'_, '_> {
                         return None;
                     }
                     res = prim;
-                    fragment = Some(path.as_str().to_string());
+                    fragment = Some(prim.name(self.cx.tcx));
                 } else {
                     // `[char]` when a `char` module is in scope
                     let candidates = vec![res, prim];
@@ -1134,8 +1150,8 @@ impl LinkCollector<'_, '_> {
             };
             report_diagnostic(cx, BROKEN_INTRA_DOC_LINKS, &msg, &item, dox, &link_range, callback);
         };
-        if let Res::PrimTy(..) = res {
-            match disambiguator {
+        match res {
+            Res::Primitive(_) => match disambiguator {
                 Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => {
                     Some(ItemLink { link: ori_link, link_text, did: None, fragment })
                 }
@@ -1143,12 +1159,11 @@ impl LinkCollector<'_, '_> {
                     report_mismatch(other, Disambiguator::Primitive);
                     None
                 }
-            }
-        } else {
-            debug!("intra-doc link to {} resolved to {:?}", path_str, res);
+            },
+            Res::Def(kind, id) => {
+                debug!("intra-doc link to {} resolved to {:?}", path_str, res);
 
-            // Disallow e.g. linking to enums with `struct@`
-            if let Res::Def(kind, _) = res {
+                // Disallow e.g. linking to enums with `struct@`
                 debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator);
                 match (self.kind_side_channel.take().map(|(kind, _)| kind).unwrap_or(kind), disambiguator) {
                     | (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, Some(Disambiguator::Kind(DefKind::Const)))
@@ -1167,46 +1182,72 @@ impl LinkCollector<'_, '_> {
                         return None;
                     }
                 }
-            }
 
-            // item can be non-local e.g. when using #[doc(primitive = "pointer")]
-            if let Some((src_id, dst_id)) = res
-                .opt_def_id()
-                .and_then(|def_id| def_id.as_local())
-                .and_then(|dst_id| item.def_id.as_local().map(|src_id| (src_id, dst_id)))
-            {
-                use rustc_hir::def_id::LOCAL_CRATE;
+                // item can be non-local e.g. when using #[doc(primitive = "pointer")]
+                if let Some((src_id, dst_id)) = id
+                    .as_local()
+                    .and_then(|dst_id| item.def_id.as_local().map(|src_id| (src_id, dst_id)))
+                {
+                    use rustc_hir::def_id::LOCAL_CRATE;
 
-                let hir_src = self.cx.tcx.hir().local_def_id_to_hir_id(src_id);
-                let hir_dst = self.cx.tcx.hir().local_def_id_to_hir_id(dst_id);
+                    let hir_src = self.cx.tcx.hir().local_def_id_to_hir_id(src_id);
+                    let hir_dst = self.cx.tcx.hir().local_def_id_to_hir_id(dst_id);
 
-                if self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_src)
-                    && !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_dst)
-                {
-                    privacy_error(cx, &item, &path_str, dox, link_range);
+                    if self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_src)
+                        && !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_dst)
+                    {
+                        privacy_error(cx, &item, &path_str, dox, link_range);
+                    }
                 }
+                let id = clean::register_res(cx, rustc_hir::def::Res::Def(kind, id));
+                Some(ItemLink { link: ori_link, link_text, did: Some(id), fragment })
             }
-            let id = clean::register_res(cx, res);
-            Some(ItemLink { link: ori_link, link_text, did: Some(id), fragment })
         }
     }
 
+    fn resolve_with_disambiguator_cached(
+        &mut self,
+        key: ResolutionInfo,
+        diag: DiagnosticInfo<'_>,
+    ) -> Option<(Res, Option<String>)> {
+        // Try to look up both the result and the corresponding side channel value
+        if let Some(ref cached) = self.visited_links.get(&key) {
+            self.kind_side_channel.set(cached.side_channel);
+            return Some(cached.res.clone());
+        }
+
+        let res = self.resolve_with_disambiguator(&key, diag);
+
+        // Cache only if resolved successfully - don't silence duplicate errors
+        if let Some(res) = &res {
+            // Store result for the actual namespace
+            self.visited_links.insert(
+                key,
+                CachedLink {
+                    res: res.clone(),
+                    side_channel: self.kind_side_channel.clone().into_inner(),
+                },
+            );
+        }
+
+        res
+    }
+
     /// After parsing the disambiguator, resolve the main part of the link.
     // FIXME(jynelson): wow this is just so much
     fn resolve_with_disambiguator(
         &self,
-        disambiguator: Option<Disambiguator>,
-        item: &Item,
-        dox: &str,
-        path_str: &str,
-        base_node: DefId,
-        extra_fragment: Option<String>,
-        ori_link: &str,
-        link_range: Option<Range<usize>>,
+        key: &ResolutionInfo,
+        diag: DiagnosticInfo<'_>,
     ) -> Option<(Res, Option<String>)> {
+        let disambiguator = key.dis;
+        let path_str = &key.path_str;
+        let base_node = key.module_id;
+        let extra_fragment = &key.extra_fragment;
+
         match disambiguator.map(Disambiguator::ns) {
             Some(ns @ (ValueNS | TypeNS)) => {
-                match self.resolve(path_str, ns, base_node, &extra_fragment) {
+                match self.resolve(path_str, ns, base_node, extra_fragment) {
                     Ok(res) => Some(res),
                     Err(ErrorKind::Resolve(box mut kind)) => {
                         // We only looked in one namespace. Try to give a better error if possible.
@@ -1215,12 +1256,9 @@ impl LinkCollector<'_, '_> {
                             // FIXME: really it should be `resolution_failure` that does this, not `resolve_with_disambiguator`
                             // See https://github.com/rust-lang/rust/pull/76955#discussion_r493953382 for a good approach
                             for &new_ns in &[other_ns, MacroNS] {
-                                if let Some(res) = self.check_full_res(
-                                    new_ns,
-                                    path_str,
-                                    base_node,
-                                    &extra_fragment,
-                                ) {
+                                if let Some(res) =
+                                    self.check_full_res(new_ns, path_str, base_node, extra_fragment)
+                                {
                                     kind = ResolutionFailure::WrongNamespace(res, ns);
                                     break;
                                 }
@@ -1228,11 +1266,11 @@ impl LinkCollector<'_, '_> {
                         }
                         resolution_failure(
                             self,
-                            &item,
+                            diag.item,
                             path_str,
                             disambiguator,
-                            dox,
-                            link_range,
+                            diag.dox,
+                            diag.link_range,
                             smallvec![kind],
                         );
                         // This could just be a normal link or a broken link
@@ -1241,7 +1279,14 @@ impl LinkCollector<'_, '_> {
                         return None;
                     }
                     Err(ErrorKind::AnchorFailure(msg)) => {
-                        anchor_failure(self.cx, &item, &ori_link, dox, link_range, msg);
+                        anchor_failure(
+                            self.cx,
+                            diag.item,
+                            diag.ori_link,
+                            diag.dox,
+                            diag.link_range,
+                            msg,
+                        );
                         return None;
                     }
                 }
@@ -1252,21 +1297,35 @@ impl LinkCollector<'_, '_> {
                     macro_ns: self
                         .resolve_macro(path_str, base_node)
                         .map(|res| (res, extra_fragment.clone())),
-                    type_ns: match self.resolve(path_str, TypeNS, base_node, &extra_fragment) {
+                    type_ns: match self.resolve(path_str, TypeNS, base_node, extra_fragment) {
                         Ok(res) => {
                             debug!("got res in TypeNS: {:?}", res);
                             Ok(res)
                         }
                         Err(ErrorKind::AnchorFailure(msg)) => {
-                            anchor_failure(self.cx, &item, ori_link, dox, link_range, msg);
+                            anchor_failure(
+                                self.cx,
+                                diag.item,
+                                diag.ori_link,
+                                diag.dox,
+                                diag.link_range,
+                                msg,
+                            );
                             return None;
                         }
                         Err(ErrorKind::Resolve(box kind)) => Err(kind),
                     },
-                    value_ns: match self.resolve(path_str, ValueNS, base_node, &extra_fragment) {
+                    value_ns: match self.resolve(path_str, ValueNS, base_node, extra_fragment) {
                         Ok(res) => Ok(res),
                         Err(ErrorKind::AnchorFailure(msg)) => {
-                            anchor_failure(self.cx, &item, ori_link, dox, link_range, msg);
+                            anchor_failure(
+                                self.cx,
+                                diag.item,
+                                diag.ori_link,
+                                diag.dox,
+                                diag.link_range,
+                                msg,
+                            );
                             return None;
                         }
                         Err(ErrorKind::Resolve(box kind)) => Err(kind),
@@ -1274,16 +1333,18 @@ impl LinkCollector<'_, '_> {
                     .and_then(|(res, fragment)| {
                         // Constructors are picked up in the type namespace.
                         match res {
-                            Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) => {
+                            Res::Def(DefKind::Ctor(..), _) => {
                                 Err(ResolutionFailure::WrongNamespace(res, TypeNS))
                             }
-                            _ => match (fragment, extra_fragment) {
-                                (Some(fragment), Some(_)) => {
-                                    // Shouldn't happen but who knows?
-                                    Ok((res, Some(fragment)))
+                            _ => {
+                                match (fragment, extra_fragment.clone()) {
+                                    (Some(fragment), Some(_)) => {
+                                        // Shouldn't happen but who knows?
+                                        Ok((res, Some(fragment)))
+                                    }
+                                    (fragment, None) | (None, fragment) => Ok((res, fragment)),
                                 }
-                                (fragment, None) | (None, fragment) => Ok((res, fragment)),
-                            },
+                            }
                         }
                     }),
                 };
@@ -1293,11 +1354,11 @@ impl LinkCollector<'_, '_> {
                 if len == 0 {
                     resolution_failure(
                         self,
-                        &item,
+                        diag.item,
                         path_str,
                         disambiguator,
-                        dox,
-                        link_range,
+                        diag.dox,
+                        diag.link_range,
                         candidates.into_iter().filter_map(|res| res.err()).collect(),
                     );
                     // this could just be a normal link
@@ -1316,10 +1377,10 @@ impl LinkCollector<'_, '_> {
                     let candidates = candidates.map(|candidate| candidate.ok().map(|(res, _)| res));
                     ambiguity_error(
                         self.cx,
-                        &item,
+                        diag.item,
                         path_str,
-                        dox,
-                        link_range,
+                        diag.dox,
+                        diag.link_range,
                         candidates.present_items().collect(),
                     );
                     return None;
@@ -1327,12 +1388,12 @@ impl LinkCollector<'_, '_> {
             }
             Some(MacroNS) => {
                 match self.resolve_macro(path_str, base_node) {
-                    Ok(res) => Some((res, extra_fragment)),
+                    Ok(res) => Some((res, extra_fragment.clone())),
                     Err(mut kind) => {
                         // `resolve_macro` only looks in the macro namespace. Try to give a better error if possible.
                         for &ns in &[TypeNS, ValueNS] {
                             if let Some(res) =
-                                self.check_full_res(ns, path_str, base_node, &extra_fragment)
+                                self.check_full_res(ns, path_str, base_node, extra_fragment)
                             {
                                 kind = ResolutionFailure::WrongNamespace(res, MacroNS);
                                 break;
@@ -1340,11 +1401,11 @@ impl LinkCollector<'_, '_> {
                         }
                         resolution_failure(
                             self,
-                            &item,
+                            diag.item,
                             path_str,
                             disambiguator,
-                            dox,
-                            link_range,
+                            diag.dox,
+                            diag.link_range,
                             smallvec![kind],
                         );
                         return None;
@@ -1355,7 +1416,7 @@ impl LinkCollector<'_, '_> {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 /// Disambiguators for a link.
 enum Disambiguator {
     /// `prim@`
@@ -1392,8 +1453,11 @@ impl Disambiguator {
                 ("!", DefKind::Macro(MacroKind::Bang)),
             ];
             for &(suffix, kind) in &suffixes {
-                if link.ends_with(suffix) {
-                    return Ok((Kind(kind), link.trim_end_matches(suffix)));
+                if let Some(link) = link.strip_suffix(suffix) {
+                    // Avoid turning `!` or `()` into an empty string
+                    if !link.is_empty() {
+                        return Ok((Kind(kind), link));
+                    }
                 }
             }
             Err(())
@@ -1423,12 +1487,10 @@ impl Disambiguator {
         }
     }
 
-    /// WARNING: panics on `Res::Err`
     fn from_res(res: Res) -> Self {
         match res {
             Res::Def(kind, _) => Disambiguator::Kind(kind),
-            Res::PrimTy(_) => Disambiguator::Primitive,
-            _ => Disambiguator::Namespace(res.ns().expect("can't call `from_res` on Res::err")),
+            Res::Primitive(_) => Disambiguator::Primitive,
         }
     }
 
@@ -1609,6 +1671,7 @@ fn resolution_failure(
     link_range: Option<Range<usize>>,
     kinds: SmallVec<[ResolutionFailure<'_>; 3]>,
 ) {
+    let tcx = collector.cx.tcx;
     report_diagnostic(
         collector.cx,
         BROKEN_INTRA_DOC_LINKS,
@@ -1617,16 +1680,9 @@ fn resolution_failure(
         dox,
         &link_range,
         |diag, sp| {
-            let item = |res: Res| {
-                format!(
-                    "the {} `{}`",
-                    res.descr(),
-                    collector.cx.tcx.item_name(res.def_id()).to_string()
-                )
-            };
+            let item = |res: Res| format!("the {} `{}`", res.descr(), res.name(tcx),);
             let assoc_item_not_allowed = |res: Res| {
-                let def_id = res.def_id();
-                let name = collector.cx.tcx.item_name(def_id);
+                let name = res.name(tcx);
                 format!(
                     "`{}` is {} {}, not a module or type, and cannot have associated items",
                     name,
@@ -1692,7 +1748,7 @@ fn resolution_failure(
                     if let Some(module) = last_found_module {
                         let note = if partial_res.is_some() {
                             // Part of the link resolved; e.g. `std::io::nonexistent`
-                            let module_name = collector.cx.tcx.item_name(module);
+                            let module_name = tcx.item_name(module);
                             format!("no item named `{}` in module `{}`", unresolved, module_name)
                         } else {
                             // None of the link resolved; e.g. `Notimported`
@@ -1716,14 +1772,10 @@ fn resolution_failure(
 
                     // Otherwise, it must be an associated item or variant
                     let res = partial_res.expect("None case was handled by `last_found_module`");
-                    let diagnostic_name;
-                    let (kind, name) = match res {
-                        Res::Def(kind, def_id) => {
-                            diagnostic_name = collector.cx.tcx.item_name(def_id).as_str();
-                            (Some(kind), &*diagnostic_name)
-                        }
-                        Res::PrimTy(ty) => (None, ty.name_str()),
-                        _ => unreachable!("only ADTs and primitives are in scope at module level"),
+                    let name = res.name(tcx);
+                    let kind = match res {
+                        Res::Def(kind, _) => Some(kind),
+                        Res::Primitive(_) => None,
                     };
                     let path_description = if let Some(kind) = kind {
                         match kind {
@@ -1941,7 +1993,14 @@ fn privacy_error(
     dox: &str,
     link_range: Option<Range<usize>>,
 ) {
-    let item_name = item.name.as_deref().unwrap_or("<unknown>");
+    let sym;
+    let item_name = match item.name {
+        Some(name) => {
+            sym = name.as_str();
+            &*sym
+        }
+        None => "<unknown>",
+    };
     let msg =
         format!("public documentation for `{}` links to private item `{}`", item_name, path_str);
 
@@ -1974,53 +2033,49 @@ fn handle_variant(
         .parent(res.def_id())
         .map(|parent| {
             let parent_def = Res::Def(DefKind::Enum, parent);
-            let variant = cx.tcx.expect_variant_res(res);
+            let variant = cx.tcx.expect_variant_res(res.as_hir_res().unwrap());
             (parent_def, Some(format!("variant.{}", variant.ident.name)))
         })
         .ok_or_else(|| ResolutionFailure::NoParentItem.into())
 }
 
-// FIXME: At this point, this is basically a copy of the PrimitiveTypeTable
-const PRIMITIVES: &[(Symbol, Res)] = &[
-    (sym::u8, Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U8))),
-    (sym::u16, Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U16))),
-    (sym::u32, Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U32))),
-    (sym::u64, Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U64))),
-    (sym::u128, Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::U128))),
-    (sym::usize, Res::PrimTy(hir::PrimTy::Uint(rustc_ast::UintTy::Usize))),
-    (sym::i8, Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I8))),
-    (sym::i16, Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I16))),
-    (sym::i32, Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I32))),
-    (sym::i64, Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I64))),
-    (sym::i128, Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::I128))),
-    (sym::isize, Res::PrimTy(hir::PrimTy::Int(rustc_ast::IntTy::Isize))),
-    (sym::f32, Res::PrimTy(hir::PrimTy::Float(rustc_ast::FloatTy::F32))),
-    (sym::f64, Res::PrimTy(hir::PrimTy::Float(rustc_ast::FloatTy::F64))),
-    (sym::str, Res::PrimTy(hir::PrimTy::Str)),
-    (sym::bool, Res::PrimTy(hir::PrimTy::Bool)),
-    (sym::char, Res::PrimTy(hir::PrimTy::Char)),
-];
-
 /// Resolve a primitive type or value.
-fn resolve_primitive(path_str: &str, ns: Namespace) -> Option<(Symbol, Res)> {
-    is_bool_value(path_str, ns).or_else(|| {
-        if ns == TypeNS {
-            // FIXME: this should be replaced by a lookup in PrimitiveTypeTable
-            let maybe_primitive = Symbol::intern(path_str);
-            PRIMITIVES.iter().find(|x| x.0 == maybe_primitive).copied()
-        } else {
-            None
-        }
-    })
-}
-
-/// Resolve a primitive value.
-fn is_bool_value(path_str: &str, ns: Namespace) -> Option<(Symbol, Res)> {
-    if ns == TypeNS && (path_str == "true" || path_str == "false") {
-        Some((sym::bool, Res::PrimTy(hir::PrimTy::Bool)))
-    } else {
-        None
+fn resolve_primitive(path_str: &str, ns: Namespace) -> Option<Res> {
+    if ns != TypeNS {
+        return None;
     }
+    use PrimitiveType::*;
+    let prim = match path_str {
+        "isize" => Isize,
+        "i8" => I8,
+        "i16" => I16,
+        "i32" => I32,
+        "i64" => I64,
+        "i128" => I128,
+        "usize" => Usize,
+        "u8" => U8,
+        "u16" => U16,
+        "u32" => U32,
+        "u64" => U64,
+        "u128" => U128,
+        "f32" => F32,
+        "f64" => F64,
+        "char" => Char,
+        "bool" | "true" | "false" => Bool,
+        "str" => Str,
+        // See #80181 for why these don't have symbols associated.
+        "slice" => Slice,
+        "array" => Array,
+        "tuple" => Tuple,
+        "unit" => Unit,
+        "pointer" | "*" | "*const" | "*mut" => RawPointer,
+        "reference" | "&" | "&mut" => Reference,
+        "fn" => Fn,
+        "never" | "!" => Never,
+        _ => return None,
+    };
+    debug!("resolved primitives {:?}", prim);
+    Some(Res::Primitive(prim))
 }
 
 fn strip_generics_from_path(path_str: &str) -> Result<String, ResolutionFailure<'static>> {
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 4c3defabc32..9b0ae09cb3f 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -5,6 +5,7 @@ use crate::fold::DocFolder;
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
+use rustc_middle::ty::DefIdTree;
 use rustc_span::symbol::sym;
 
 crate const COLLECT_TRAIT_IMPLS: Pass = Pass {
@@ -15,13 +16,13 @@ crate const COLLECT_TRAIT_IMPLS: Pass = Pass {
 
 crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
     let mut synth = SyntheticImplCollector::new(cx);
-    let mut krate = synth.fold_crate(krate);
+    let mut krate = cx.sess().time("collect_synthetic_impls", || synth.fold_crate(krate));
 
     let prims: FxHashSet<PrimitiveType> = krate.primitives.iter().map(|p| p.1).collect();
 
     let crate_items = {
         let mut coll = ItemCollector::new();
-        krate = coll.fold_crate(krate);
+        krate = cx.sess().time("collect_items_for_trait_impls", || coll.fold_crate(krate));
         coll.items
     };
 
@@ -38,16 +39,18 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
     // Also try to inline primitive impls from other crates.
     for &def_id in PrimitiveType::all_impls(cx.tcx).values().flatten() {
         if !def_id.is_local() {
-            inline::build_impl(cx, None, def_id, None, &mut new_items);
+            cx.sess().time("build_primitive_trait_impl", || {
+                inline::build_impl(cx, None, def_id, None, &mut new_items);
 
-            // FIXME(eddyb) is this `doc(hidden)` check needed?
-            if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) {
-                let self_ty = cx.tcx.type_of(def_id);
-                let impls = get_auto_trait_and_blanket_impls(cx, self_ty, def_id);
-                let mut renderinfo = cx.renderinfo.borrow_mut();
+                // FIXME(eddyb) is this `doc(hidden)` check needed?
+                if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) {
+                    let self_ty = cx.tcx.type_of(def_id);
+                    let impls = get_auto_trait_and_blanket_impls(cx, self_ty, def_id);
+                    let mut renderinfo = cx.renderinfo.borrow_mut();
 
-                new_items.extend(impls.filter(|i| renderinfo.inlined.insert(i.def_id)));
-            }
+                    new_items.extend(impls.filter(|i| renderinfo.inlined.insert(i.def_id)));
+                }
+            })
         }
     }
 
@@ -55,11 +58,11 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
 
     // scan through included items ahead of time to splice in Deref targets to the "valid" sets
     for it in &new_items {
-        if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = it.kind {
+        if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind {
             if cleaner.keep_item(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() {
                 let target = items
                     .iter()
-                    .find_map(|item| match item.kind {
+                    .find_map(|item| match *item.kind {
                         TypedefItem(ref t, true) => Some(&t.type_),
                         _ => None,
                     })
@@ -75,7 +78,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
     }
 
     new_items.retain(|it| {
-        if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = it.kind {
+        if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind {
             cleaner.keep_item(for_)
                 || trait_.as_ref().map_or(false, |t| cleaner.keep_item(t))
                 || blanket_impl.is_some()
@@ -90,13 +93,38 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
         for &impl_node in cx.tcx.hir().trait_impls(trait_did) {
             let impl_did = cx.tcx.hir().local_def_id(impl_node);
             cx.tcx.sess.time("build_local_trait_impl", || {
-                inline::build_impl(cx, None, impl_did.to_def_id(), None, &mut new_items);
+                let mut extra_attrs = Vec::new();
+                let mut parent = cx.tcx.parent(impl_did.to_def_id());
+                while let Some(did) = parent {
+                    extra_attrs.extend(
+                        cx.tcx
+                            .get_attrs(did)
+                            .iter()
+                            .filter(|attr| attr.has_name(sym::doc))
+                            .filter(|attr| {
+                                if let Some([attr]) = attr.meta_item_list().as_deref() {
+                                    attr.has_name(sym::cfg)
+                                } else {
+                                    false
+                                }
+                            })
+                            .cloned(),
+                    );
+                    parent = cx.tcx.parent(did);
+                }
+                inline::build_impl(
+                    cx,
+                    None,
+                    impl_did.to_def_id(),
+                    Some(&extra_attrs),
+                    &mut new_items,
+                );
             });
         }
     }
 
     if let Some(ref mut it) = krate.module {
-        if let ModuleItem(Module { ref mut items, .. }) = it.kind {
+        if let ModuleItem(Module { ref mut items, .. }) = *it.kind {
             items.extend(synth.impls);
             items.extend(new_items);
         } else {
@@ -125,11 +153,13 @@ impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> {
         if i.is_struct() || i.is_enum() || i.is_union() {
             // FIXME(eddyb) is this `doc(hidden)` check needed?
             if !self.cx.tcx.get_attrs(i.def_id).lists(sym::doc).has_word(sym::hidden) {
-                self.impls.extend(get_auto_trait_and_blanket_impls(
-                    self.cx,
-                    self.cx.tcx.type_of(i.def_id),
-                    i.def_id,
-                ));
+                self.cx.sess().time("get_auto_trait_and_blanket_synthetic_impls", || {
+                    self.impls.extend(get_auto_trait_and_blanket_impls(
+                        self.cx,
+                        self.cx.tcx.type_of(i.def_id),
+                        i.def_id,
+                    ));
+                });
             }
         }
 
diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs
index 299a73c8a01..a513c2abc87 100644
--- a/src/librustdoc/passes/doc_test_lints.rs
+++ b/src/librustdoc/passes/doc_test_lints.rs
@@ -9,7 +9,7 @@ use crate::clean::*;
 use crate::core::DocContext;
 use crate::fold::DocFolder;
 use crate::html::markdown::{find_testable_code, ErrorCodes, Ignore, LangString};
-use rustc_middle::lint::LintSource;
+use rustc_middle::lint::LintLevelSource;
 use rustc_session::lint;
 
 crate const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass {
@@ -58,25 +58,26 @@ impl crate::doctest::Tester for Tests {
 }
 
 crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool {
-    if matches!(item.kind,
+    if matches!(
+        *item.kind,
         clean::StructFieldItem(_)
-        | clean::VariantItem(_)
-        | clean::AssocConstItem(_, _)
-        | clean::AssocTypeItem(_, _)
-        | clean::TypedefItem(_, _)
-        | clean::StaticItem(_)
-        | clean::ConstantItem(_)
-        | clean::ExternCrateItem(_, _)
-        | clean::ImportItem(_)
-        | clean::PrimitiveItem(_)
-        | clean::KeywordItem(_)
+            | clean::VariantItem(_)
+            | clean::AssocConstItem(_, _)
+            | clean::AssocTypeItem(_, _)
+            | clean::TypedefItem(_, _)
+            | clean::StaticItem(_)
+            | clean::ConstantItem(_)
+            | clean::ExternCrateItem(_, _)
+            | clean::ImportItem(_)
+            | clean::PrimitiveItem(_)
+            | clean::KeywordItem(_)
     ) {
         return false;
     }
     let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id.expect_local());
     let (level, source) =
         cx.tcx.lint_level_at_node(lint::builtin::MISSING_DOC_CODE_EXAMPLES, hir_id);
-    level != lint::Level::Allow || matches!(source, LintSource::Default)
+    level != lint::Level::Allow || matches!(source, LintLevelSource::Default)
 }
 
 crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index 6b59eb8cf28..01e3d0acaa8 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -41,7 +41,7 @@ impl<'a> DocFolder for Stripper<'a> {
         if i.attrs.lists(sym::doc).has_word(sym::hidden) {
             debug!("strip_hidden: stripping {:?} {:?}", i.type_(), i.name);
             // use a dedicated hidden item for given item type if any
-            match i.kind {
+            match *i.kind {
                 clean::StructFieldItem(..) | clean::ModuleItem(..) => {
                     // We need to recurse into stripped modules to
                     // strip things like impl methods but when doing so
@@ -49,7 +49,7 @@ impl<'a> DocFolder for Stripper<'a> {
                     let old = mem::replace(&mut self.update_retained, false);
                     let ret = StripItem(self.fold_item_recur(i)).strip();
                     self.update_retained = old;
-                    return ret;
+                    return Some(ret);
                 }
                 _ => return None,
             }
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index 444fd593ec9..a1924422f0e 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -13,7 +13,7 @@ crate struct Stripper<'a> {
 
 impl<'a> DocFolder for Stripper<'a> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
-        match i.kind {
+        match *i.kind {
             clean::StrippedItem(..) => {
                 // We need to recurse into stripped modules to strip things
                 // like impl methods but when doing so we must not add any
@@ -51,7 +51,7 @@ impl<'a> DocFolder for Stripper<'a> {
 
             clean::StructFieldItem(..) => {
                 if !i.visibility.is_public() {
-                    return StripItem(i).strip();
+                    return Some(StripItem(i).strip());
                 }
             }
 
@@ -61,7 +61,7 @@ impl<'a> DocFolder for Stripper<'a> {
                     let old = mem::replace(&mut self.update_retained, false);
                     let ret = StripItem(self.fold_item_recur(i)).strip();
                     self.update_retained = old;
-                    return ret;
+                    return Some(ret);
                 }
             }
 
@@ -86,7 +86,7 @@ impl<'a> DocFolder for Stripper<'a> {
             clean::KeywordItem(..) => {}
         }
 
-        let fastreturn = match i.kind {
+        let fastreturn = match *i.kind {
             // nothing left to do for traits (don't want to filter their
             // methods out, visibility controlled by the trait)
             clean::TraitItem(..) => true,
@@ -121,7 +121,7 @@ crate struct ImplStripper<'a> {
 
 impl<'a> DocFolder for ImplStripper<'a> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
-        if let clean::ImplItem(ref imp) = i.kind {
+        if let clean::ImplItem(ref imp) = *i.kind {
             // emptied none trait impls can be stripped
             if imp.trait_.is_none() && imp.items.is_empty() {
                 return None;
@@ -160,7 +160,7 @@ crate struct ImportStripper;
 
 impl DocFolder for ImportStripper {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
-        match i.kind {
+        match *i.kind {
             clean::ExternCrateItem(..) | clean::ImportItem(..) if !i.visibility.is_public() => None,
             _ => Some(self.fold_item_recur(i)),
         }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index f9cb1d586b1..3c0aeaad43e 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -1,7 +1,6 @@
 //! The Rust AST Visitor. Extracts useful information and massages it into a form
 //! usable for `clean`.
 
-use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -64,7 +63,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
     crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> {
         let mut module = self.visit_mod_contents(
             krate.item.span,
-            krate.item.attrs,
             &Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Public },
             hir::CRATE_HIR_ID,
             &krate.item.module,
@@ -82,13 +80,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
     fn visit_mod_contents(
         &mut self,
         span: Span,
-        attrs: &'tcx [ast::Attribute],
         vis: &'tcx hir::Visibility<'_>,
         id: hir::HirId,
         m: &'tcx hir::Mod<'tcx>,
         name: Option<Symbol>,
     ) -> Module<'tcx> {
-        let mut om = Module::new(name, attrs);
+        let mut om = Module::new(name);
         om.where_outer = span;
         om.where_inner = m.inner;
         om.id = id;
@@ -292,7 +289,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             hir::ItemKind::Mod(ref m) => {
                 om.mods.push(self.visit_mod_contents(
                     item.span,
-                    &item.attrs,
                     &item.vis,
                     item.hir_id,
                     m,
diff --git a/src/llvm-project b/src/llvm-project
-Subproject d5c516edf7897b377ac39ccc5d7ca52a9512440
+Subproject fb115ee43b77601b237717c21ab0a8f5b5b9d50
diff --git a/src/stage0.txt b/src/stage0.txt
index 6e05b66c3fe..e853b9b4e41 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: 2020-11-18
+date: 2020-12-30
 rustc: beta
 
 # We use a nightly rustfmt to format the source because it solves some
diff --git a/src/test/codegen/slice-ref-equality.rs b/src/test/codegen/slice-ref-equality.rs
new file mode 100644
index 00000000000..acc7879e7b1
--- /dev/null
+++ b/src/test/codegen/slice-ref-equality.rs
@@ -0,0 +1,16 @@
+// compile-flags: -C opt-level=3
+
+#![crate_type = "lib"]
+
+// #71602: check that slice equality just generates a single bcmp
+
+// CHECK-LABEL: @is_zero_slice
+#[no_mangle]
+pub fn is_zero_slice(data: &[u8; 4]) -> bool {
+    // CHECK: start:
+    // CHECK-NEXT: %{{.+}} = getelementptr {{.+}}
+    // CHECK-NEXT: %[[BCMP:.+]] = tail call i32 @{{bcmp|memcmp}}({{.+}})
+    // CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[BCMP]], 0
+    // CHECK-NEXT: ret i1 %[[EQ]]
+    *data == [0; 4]
+}
diff --git a/src/test/codegen/transmute-scalar.rs b/src/test/codegen/transmute-scalar.rs
new file mode 100644
index 00000000000..78b4aa3fb88
--- /dev/null
+++ b/src/test/codegen/transmute-scalar.rs
@@ -0,0 +1,85 @@
+// compile-flags: -O -C no-prepopulate-passes
+
+#![crate_type = "lib"]
+
+// FIXME(eddyb) all of these tests show memory stores and loads, even after a
+// scalar `bitcast`, more special-casing is required to remove `alloca` usage.
+
+// CHECK: define i32 @f32_to_bits(float %x)
+// CHECK: %2 = bitcast float %x to i32
+// CHECK-NEXT: store i32 %2, i32* %0
+// CHECK-NEXT: %3 = load i32, i32* %0
+// CHECK: ret i32 %3
+#[no_mangle]
+pub fn f32_to_bits(x: f32) -> u32 {
+    unsafe { std::mem::transmute(x) }
+}
+
+// CHECK: define i8 @bool_to_byte(i1 zeroext %b)
+// CHECK: %1 = zext i1 %b to i8
+// CHECK-NEXT: store i8 %1, i8* %0
+// CHECK-NEXT: %2 = load i8, i8* %0
+// CHECK: ret i8 %2
+#[no_mangle]
+pub fn bool_to_byte(b: bool) -> u8 {
+    unsafe { std::mem::transmute(b) }
+}
+
+// CHECK: define zeroext i1 @byte_to_bool(i8 %byte)
+// CHECK: %1 = trunc i8 %byte to i1
+// CHECK-NEXT: %2 = zext i1 %1 to i8
+// CHECK-NEXT: store i8 %2, i8* %0
+// CHECK-NEXT: %3 = load i8, i8* %0
+// CHECK-NEXT: %4 = trunc i8 %3 to i1
+// CHECK: ret i1 %4
+#[no_mangle]
+pub unsafe fn byte_to_bool(byte: u8) -> bool {
+    std::mem::transmute(byte)
+}
+
+// CHECK: define i8* @ptr_to_ptr(i16* %p)
+// CHECK: %2 = bitcast i16* %p to i8*
+// CHECK-NEXT: store i8* %2, i8** %0
+// CHECK-NEXT: %3 = load i8*, i8** %0
+// CHECK: ret i8* %3
+#[no_mangle]
+pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 {
+    unsafe { std::mem::transmute(p) }
+}
+
+// HACK(eddyb) scalar `transmute`s between pointers and non-pointers are
+// currently not special-cased like other scalar `transmute`s, because
+// LLVM requires specifically `ptrtoint`/`inttoptr` instead of `bitcast`.
+//
+// Tests below show the non-special-cased behavior (with the possible
+// future special-cased instructions in the "NOTE(eddyb)" comments).
+
+// CHECK: define [[USIZE:i[0-9]+]] @ptr_to_int(i16* %p)
+
+// NOTE(eddyb) see above, the following two CHECK lines should ideally be this:
+//        %2 = ptrtoint i16* %p to [[USIZE]]
+//             store [[USIZE]] %2, [[USIZE]]* %0
+// CHECK: %2 = bitcast [[USIZE]]* %0 to i16**
+// CHECK-NEXT: store i16* %p, i16** %2
+
+// CHECK-NEXT: %3 = load [[USIZE]], [[USIZE]]* %0
+// CHECK: ret [[USIZE]] %3
+#[no_mangle]
+pub fn ptr_to_int(p: *mut u16) -> usize {
+    unsafe { std::mem::transmute(p) }
+}
+
+// CHECK: define i16* @int_to_ptr([[USIZE]] %i)
+
+// NOTE(eddyb) see above, the following two CHECK lines should ideally be this:
+//        %2 = inttoptr [[USIZE]] %i to i16*
+//             store i16* %2, i16** %0
+// CHECK: %2 = bitcast i16** %0 to [[USIZE]]*
+// CHECK-NEXT: store [[USIZE]] %i, [[USIZE]]* %2
+
+// CHECK-NEXT: %3 = load i16*, i16** %0
+// CHECK: ret i16* %3
+#[no_mangle]
+pub fn int_to_ptr(i: usize) -> *mut u16 {
+    unsafe { std::mem::transmute(i) }
+}
diff --git a/src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs b/src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs
deleted file mode 100644
index b9ef2f32941..00000000000
--- a/src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// no-prefer-dynamic
-
-#![crate_type = "rlib"]
-
-#![no_std]
-#![feature(lang_items)]
-
-use core::panic::PanicInfo;
-
-#[lang = "panic_impl"]
-fn panic_impl(info: &PanicInfo) -> ! { loop {} }
-#[lang = "eh_personality"]
-fn eh_personality() {}
-#[lang = "eh_catch_typeinfo"]
-static EH_CATCH_TYPEINFO: u8 = 0;
diff --git a/src/test/compile-fail/auxiliary/panic-runtime-unwind.rs b/src/test/compile-fail/auxiliary/panic-runtime-unwind.rs
deleted file mode 100644
index 97452a342ab..00000000000
--- a/src/test/compile-fail/auxiliary/panic-runtime-unwind.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// compile-flags:-C panic=unwind
-// no-prefer-dynamic
-
-#![feature(panic_runtime)]
-#![crate_type = "rlib"]
-
-#![no_std]
-#![panic_runtime]
-
-#[no_mangle]
-pub extern fn __rust_maybe_catch_panic() {}
-
-#[no_mangle]
-pub extern fn __rust_start_panic() {}
-
-#[no_mangle]
-pub extern fn rust_eh_personality() {}
diff --git a/src/test/compile-fail/auxiliary/panic-runtime-unwind2.rs b/src/test/compile-fail/auxiliary/panic-runtime-unwind2.rs
deleted file mode 100644
index 97452a342ab..00000000000
--- a/src/test/compile-fail/auxiliary/panic-runtime-unwind2.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// compile-flags:-C panic=unwind
-// no-prefer-dynamic
-
-#![feature(panic_runtime)]
-#![crate_type = "rlib"]
-
-#![no_std]
-#![panic_runtime]
-
-#[no_mangle]
-pub extern fn __rust_maybe_catch_panic() {}
-
-#[no_mangle]
-pub extern fn __rust_start_panic() {}
-
-#[no_mangle]
-pub extern fn rust_eh_personality() {}
diff --git a/src/test/compile-fail/auxiliary/some-panic-impl.rs b/src/test/compile-fail/auxiliary/some-panic-impl.rs
deleted file mode 100644
index 0348b3a2d76..00000000000
--- a/src/test/compile-fail/auxiliary/some-panic-impl.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// no-prefer-dynamic
-
-#![crate_type = "rlib"]
-#![no_std]
-
-use core::panic::PanicInfo;
-
-#[panic_handler]
-fn panic(info: &PanicInfo) -> ! {
-    loop {}
-}
diff --git a/src/test/compile-fail/auxiliary/wants-panic-runtime-unwind.rs b/src/test/compile-fail/auxiliary/wants-panic-runtime-unwind.rs
deleted file mode 100644
index d5f0102196f..00000000000
--- a/src/test/compile-fail/auxiliary/wants-panic-runtime-unwind.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-// no-prefer-dynamic
-
-#![crate_type = "rlib"]
-#![no_std]
-
-extern crate panic_runtime_unwind;
diff --git a/src/test/compile-fail/runtime-depend-on-needs-runtime.stderr b/src/test/compile-fail/runtime-depend-on-needs-runtime.stderr
deleted file mode 100644
index 27e27dda5ef..00000000000
--- a/src/test/compile-fail/runtime-depend-on-needs-runtime.stderr
+++ /dev/null
@@ -1,4 +0,0 @@
-error: the crate `depends` cannot depend on a crate that needs a panic runtime, but it depends on `needs_panic_runtime`
-
-error: aborting due to previous error
-
diff --git a/src/test/debuginfo/pretty-std-collections-hash.rs b/src/test/debuginfo/pretty-std-collections-hash.rs
index 9f59936a92d..7115aec1041 100644
--- a/src/test/debuginfo/pretty-std-collections-hash.rs
+++ b/src/test/debuginfo/pretty-std-collections-hash.rs
@@ -10,8 +10,8 @@
 // cdb-command: g
 
 // cdb-command: dx hash_set,d
-// cdb-check:hash_set,d [...] : { size=15 } [Type: [...]::HashSet<u64, [...]>]
-// cdb-check:    [size]           : 15 [Type: [...]]
+// cdb-check:hash_set,d [...] : { len=15 } [Type: [...]::HashSet<u64, [...]>]
+// cdb-check:    [len]            : 15 [Type: [...]]
 // cdb-check:    [capacity]       : [...]
 // cdb-check:    [[...]] [...]    : 0 [Type: u64]
 // cdb-command: dx hash_set,d
@@ -44,8 +44,8 @@
 // cdb-check:    [[...]] [...]    : 14 [Type: u64]
 
 // cdb-command: dx hash_map,d
-// cdb-check:hash_map,d [...] : { size=15 } [Type: [...]::HashMap<u64, u64, [...]>]
-// cdb-check:    [size]           : 15 [Type: [...]]
+// cdb-check:hash_map,d [...] : { len=15 } [Type: [...]::HashMap<u64, u64, [...]>]
+// cdb-check:    [len]            : 15 [Type: [...]]
 // cdb-check:    [capacity]       : [...]
 // cdb-check:    ["0x0"]          : 0 [Type: unsigned __int64]
 // cdb-command: dx hash_map,d
diff --git a/src/test/debuginfo/pretty-std.rs b/src/test/debuginfo/pretty-std.rs
index 6632488171d..1a99f841250 100644
--- a/src/test/debuginfo/pretty-std.rs
+++ b/src/test/debuginfo/pretty-std.rs
@@ -74,8 +74,8 @@
 // NOTE: While slices have a .natvis entry that works in VS & VS Code, it fails in CDB 10.0.18362.1
 
 // cdb-command: dx vec,d
-// cdb-check:vec,d [...] : { size=4 } [Type: [...]::Vec<u64, alloc::alloc::Global>]
-// cdb-check:    [size]           : 4 [Type: [...]]
+// cdb-check:vec,d [...] : { len=4 } [Type: [...]::Vec<u64, alloc::alloc::Global>]
+// cdb-check:    [len]            : 4 [Type: [...]]
 // cdb-check:    [capacity]       : [...] [Type: [...]]
 // cdb-check:    [0]              : 4 [Type: unsigned __int64]
 // cdb-check:    [1]              : 5 [Type: unsigned __int64]
@@ -89,8 +89,10 @@
 // cdb-command: dx string
 // cdb-check:string           : "IAMA string!" [Type: [...]::String]
 // cdb-check:    [<Raw View>]     [Type: [...]::String]
-// cdb-check:    [size]           : 0xc [Type: [...]]
+// cdb-check:    [len]            : 0xc [Type: [...]]
 // cdb-check:    [capacity]       : 0xc [Type: [...]]
+
+// cdb-command: dx -r2 string
 // cdb-check:    [0]              : 73 'I' [Type: char]
 // cdb-check:    [1]              : 65 'A' [Type: char]
 // cdb-check:    [2]              : 77 'M' [Type: char]
@@ -109,11 +111,11 @@
 // NOTE: OsString doesn't have a .natvis entry yet.
 
 // cdb-command: dx some
-// cdb-check:some             : { Some 8 } [Type: [...]::Option<i16>]
+// cdb-check:some             : Some(8) [Type: [...]::Option<i16>]
 // cdb-command: dx none
-// cdb-check:none             : { None } [Type: [...]::Option<i64>]
+// cdb-check:none             : None [Type: [...]::Option<i64>]
 // cdb-command: dx some_string
-// cdb-check:some_string      : { Some "IAMA optional string!" } [[...]::Option<[...]::String>]
+// cdb-check:some_string      : Some("IAMA optional string!") [[...]::Option<[...]::String>]
 
 #![allow(unused_variables)]
 use std::ffi::OsString;
diff --git a/src/test/incremental/auxiliary/issue-79890.rs b/src/test/incremental/auxiliary/issue-79890.rs
new file mode 100644
index 00000000000..8eaeafa5207
--- /dev/null
+++ b/src/test/incremental/auxiliary/issue-79890.rs
@@ -0,0 +1 @@
+pub trait MyTrait {}
diff --git a/src/test/incremental/issue-79890-imported-crates-changed.rs b/src/test/incremental/issue-79890-imported-crates-changed.rs
new file mode 100644
index 00000000000..93daa5ca935
--- /dev/null
+++ b/src/test/incremental/issue-79890-imported-crates-changed.rs
@@ -0,0 +1,7 @@
+// aux-build:issue-79890.rs
+// revisions:rpass1 rpass2 rpass3
+// compile-flags:--extern issue_79890 --test
+// edition:2018
+
+// Tests that we don't ICE when the set of imported crates changes
+#[cfg(rpass2)] use issue_79890::MyTrait;
diff --git a/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
new file mode 100644
index 00000000000..47c3239b8bf
--- /dev/null
+++ b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
@@ -0,0 +1,115 @@
+- // MIR for `main` before ConstDebugInfo
++ // MIR for `main` after ConstDebugInfo
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/const_debuginfo.rs:8:11: 8:11
+      let _1: u8;                          // in scope 0 at $DIR/const_debuginfo.rs:9:9: 9:10
+      let mut _5: u8;                      // in scope 0 at $DIR/const_debuginfo.rs:12:15: 12:20
+      let mut _6: u8;                      // in scope 0 at $DIR/const_debuginfo.rs:12:15: 12:16
+      let mut _7: u8;                      // in scope 0 at $DIR/const_debuginfo.rs:12:19: 12:20
+      let mut _8: u8;                      // in scope 0 at $DIR/const_debuginfo.rs:12:23: 12:24
+      let mut _14: u32;                    // in scope 0 at $DIR/const_debuginfo.rs:21:13: 21:16
+      let mut _15: u32;                    // in scope 0 at $DIR/const_debuginfo.rs:21:19: 21:22
+      scope 1 {
+-         debug x => _1;                   // in scope 1 at $DIR/const_debuginfo.rs:9:9: 9:10
++         debug x => const 1_u8;           // in scope 1 at $DIR/const_debuginfo.rs:9:9: 9:10
+          let _2: u8;                      // in scope 1 at $DIR/const_debuginfo.rs:10:9: 10:10
+          scope 2 {
+-             debug y => _2;               // in scope 2 at $DIR/const_debuginfo.rs:10:9: 10:10
++             debug y => const 2_u8;       // in scope 2 at $DIR/const_debuginfo.rs:10:9: 10:10
+              let _3: u8;                  // in scope 2 at $DIR/const_debuginfo.rs:11:9: 11:10
+              scope 3 {
+-                 debug z => _3;           // in scope 3 at $DIR/const_debuginfo.rs:11:9: 11:10
++                 debug z => const 3_u8;   // in scope 3 at $DIR/const_debuginfo.rs:11:9: 11:10
+                  let _4: u8;              // in scope 3 at $DIR/const_debuginfo.rs:12:9: 12:12
+                  scope 4 {
+-                     debug sum => _4;     // in scope 4 at $DIR/const_debuginfo.rs:12:9: 12:12
++                     debug sum => const 6_u8; // in scope 4 at $DIR/const_debuginfo.rs:12:9: 12:12
+                      let _9: &str;        // in scope 4 at $DIR/const_debuginfo.rs:14:9: 14:10
+                      scope 5 {
+-                         debug s => _9;   // in scope 5 at $DIR/const_debuginfo.rs:14:9: 14:10
++                         debug s => const "hello, world!"; // in scope 5 at $DIR/const_debuginfo.rs:14:9: 14:10
+                          let _10: (bool, bool, u32); // in scope 5 at $DIR/const_debuginfo.rs:16:9: 16:10
+                          scope 6 {
+                              debug f => _10; // in scope 6 at $DIR/const_debuginfo.rs:16:9: 16:10
+                              let _11: std::option::Option<u16>; // in scope 6 at $DIR/const_debuginfo.rs:18:9: 18:10
+                              scope 7 {
+                                  debug o => _11; // in scope 7 at $DIR/const_debuginfo.rs:18:9: 18:10
+                                  let _12: Point; // in scope 7 at $DIR/const_debuginfo.rs:20:9: 20:10
+                                  scope 8 {
+                                      debug p => _12; // in scope 8 at $DIR/const_debuginfo.rs:20:9: 20:10
+                                      let _13: u32; // in scope 8 at $DIR/const_debuginfo.rs:21:9: 21:10
+                                      scope 9 {
+-                                         debug a => _13; // in scope 9 at $DIR/const_debuginfo.rs:21:9: 21:10
++                                         debug a => const 64_u32; // in scope 9 at $DIR/const_debuginfo.rs:21:9: 21:10
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/const_debuginfo.rs:9:9: 9:10
+          _1 = const 1_u8;                 // scope 0 at $DIR/const_debuginfo.rs:9:13: 9:16
+          StorageLive(_2);                 // scope 1 at $DIR/const_debuginfo.rs:10:9: 10:10
+          _2 = const 2_u8;                 // scope 1 at $DIR/const_debuginfo.rs:10:13: 10:16
+          StorageLive(_3);                 // scope 2 at $DIR/const_debuginfo.rs:11:9: 11:10
+          _3 = const 3_u8;                 // scope 2 at $DIR/const_debuginfo.rs:11:13: 11:16
+          StorageLive(_4);                 // scope 3 at $DIR/const_debuginfo.rs:12:9: 12:12
+          StorageLive(_5);                 // scope 3 at $DIR/const_debuginfo.rs:12:15: 12:20
+          StorageLive(_6);                 // scope 3 at $DIR/const_debuginfo.rs:12:15: 12:16
+          _6 = const 1_u8;                 // scope 3 at $DIR/const_debuginfo.rs:12:15: 12:16
+          StorageLive(_7);                 // scope 3 at $DIR/const_debuginfo.rs:12:19: 12:20
+          _7 = const 2_u8;                 // scope 3 at $DIR/const_debuginfo.rs:12:19: 12:20
+          _5 = const 3_u8;                 // scope 3 at $DIR/const_debuginfo.rs:12:15: 12:20
+          StorageDead(_7);                 // scope 3 at $DIR/const_debuginfo.rs:12:19: 12:20
+          StorageDead(_6);                 // scope 3 at $DIR/const_debuginfo.rs:12:19: 12:20
+          StorageLive(_8);                 // scope 3 at $DIR/const_debuginfo.rs:12:23: 12:24
+          _8 = const 3_u8;                 // scope 3 at $DIR/const_debuginfo.rs:12:23: 12:24
+          _4 = const 6_u8;                 // scope 3 at $DIR/const_debuginfo.rs:12:15: 12:24
+          StorageDead(_8);                 // scope 3 at $DIR/const_debuginfo.rs:12:23: 12:24
+          StorageDead(_5);                 // scope 3 at $DIR/const_debuginfo.rs:12:23: 12:24
+          StorageLive(_9);                 // scope 4 at $DIR/const_debuginfo.rs:14:9: 14:10
+          _9 = const "hello, world!";      // scope 4 at $DIR/const_debuginfo.rs:14:13: 14:28
+                                           // ty::Const
+                                           // + ty: &str
+                                           // + val: Value(Slice { data: Allocation { bytes: [104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [8191], len: Size { raw: 13 } }, size: Size { raw: 13 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 13 })
+                                           // mir::Constant
+                                           // + span: $DIR/const_debuginfo.rs:14:13: 14:28
+                                           // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [8191], len: Size { raw: 13 } }, size: Size { raw: 13 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 13 }) }
+          StorageLive(_10);                // scope 5 at $DIR/const_debuginfo.rs:16:9: 16:10
+          (_10.0: bool) = const true;      // scope 5 at $DIR/const_debuginfo.rs:16:13: 16:34
+          (_10.1: bool) = const false;     // scope 5 at $DIR/const_debuginfo.rs:16:13: 16:34
+          (_10.2: u32) = const 123_u32;    // scope 5 at $DIR/const_debuginfo.rs:16:13: 16:34
+          StorageLive(_11);                // scope 6 at $DIR/const_debuginfo.rs:18:9: 18:10
+          ((_11 as Some).0: u16) = const 99_u16; // scope 6 at $DIR/const_debuginfo.rs:18:13: 18:24
+          discriminant(_11) = 1;           // scope 6 at $DIR/const_debuginfo.rs:18:13: 18:24
+          StorageLive(_12);                // scope 7 at $DIR/const_debuginfo.rs:20:9: 20:10
+          (_12.0: u32) = const 32_u32;     // scope 7 at $DIR/const_debuginfo.rs:20:13: 20:35
+          (_12.1: u32) = const 32_u32;     // scope 7 at $DIR/const_debuginfo.rs:20:13: 20:35
+          StorageLive(_13);                // scope 8 at $DIR/const_debuginfo.rs:21:9: 21:10
+          StorageLive(_14);                // scope 8 at $DIR/const_debuginfo.rs:21:13: 21:16
+          _14 = const 32_u32;              // scope 8 at $DIR/const_debuginfo.rs:21:13: 21:16
+          StorageLive(_15);                // scope 8 at $DIR/const_debuginfo.rs:21:19: 21:22
+          _15 = const 32_u32;              // scope 8 at $DIR/const_debuginfo.rs:21:19: 21:22
+          _13 = const 64_u32;              // scope 8 at $DIR/const_debuginfo.rs:21:13: 21:22
+          StorageDead(_15);                // scope 8 at $DIR/const_debuginfo.rs:21:21: 21:22
+          StorageDead(_14);                // scope 8 at $DIR/const_debuginfo.rs:21:21: 21:22
+          _0 = const ();                   // scope 0 at $DIR/const_debuginfo.rs:8:11: 22:2
+          StorageDead(_13);                // scope 8 at $DIR/const_debuginfo.rs:22:1: 22:2
+          StorageDead(_12);                // scope 7 at $DIR/const_debuginfo.rs:22:1: 22:2
+          StorageDead(_11);                // scope 6 at $DIR/const_debuginfo.rs:22:1: 22:2
+          StorageDead(_10);                // scope 5 at $DIR/const_debuginfo.rs:22:1: 22:2
+          StorageDead(_9);                 // scope 4 at $DIR/const_debuginfo.rs:22:1: 22:2
+          StorageDead(_4);                 // scope 3 at $DIR/const_debuginfo.rs:22:1: 22:2
+          StorageDead(_3);                 // scope 2 at $DIR/const_debuginfo.rs:22:1: 22:2
+          StorageDead(_2);                 // scope 1 at $DIR/const_debuginfo.rs:22:1: 22:2
+          StorageDead(_1);                 // scope 0 at $DIR/const_debuginfo.rs:22:1: 22:2
+          return;                          // scope 0 at $DIR/const_debuginfo.rs:22:2: 22:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/const_debuginfo.rs b/src/test/mir-opt/const_debuginfo.rs
new file mode 100644
index 00000000000..a188da38526
--- /dev/null
+++ b/src/test/mir-opt/const_debuginfo.rs
@@ -0,0 +1,24 @@
+// compile-flags: -C overflow-checks=no -Zunsound-mir-opts
+
+struct Point {
+    x: u32,
+    y: u32,
+}
+
+fn main() {
+    let x = 1u8;
+    let y = 2u8;
+    let z = 3u8;
+    let sum = x + y + z;
+
+    let s = "hello, world!";
+
+    let f = (true, false, 123u32);
+
+    let o = Some(99u16);
+
+    let p = Point { x: 32, y: 32 };
+    let a = p.x + p.y;
+}
+
+// EMIT_MIR const_debuginfo.main.ConstDebugInfo.diff
diff --git a/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff
index f01676b6da8..3397ef95856 100644
--- a/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/checked_add.main.ConstProp.diff
@@ -14,9 +14,6 @@
 -         _2 = CheckedAdd(const 1_u32, const 1_u32); // scope 0 at $DIR/checked_add.rs:5:18: 5:23
 -         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> bb1; // scope 0 at $DIR/checked_add.rs:5:18: 5:23
 +         _2 = const (2_u32, false);       // scope 0 at $DIR/checked_add.rs:5:18: 5:23
-+                                          // ty::Const
-+                                          // + ty: (u32, bool)
-+                                          // + val: Value(ByRef { alloc: Allocation { bytes: [2, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
 +                                          // mir::Constant
 +                                          // + span: $DIR/checked_add.rs:5:18: 5:23
 +                                          // + literal: Const { ty: (u32, bool), val: Value(ByRef { alloc: Allocation { bytes: [2, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
diff --git a/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff
index 8c7b35887c9..9ddb34e58e5 100644
--- a/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/indirect.main.ConstProp.diff
@@ -18,9 +18,6 @@
 -         assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> bb1; // scope 0 at $DIR/indirect.rs:5:13: 5:29
 +         _2 = const 2_u8;                 // scope 0 at $DIR/indirect.rs:5:13: 5:25
 +         _3 = const (3_u8, false);        // scope 0 at $DIR/indirect.rs:5:13: 5:29
-+                                          // ty::Const
-+                                          // + ty: (u8, bool)
-+                                          // + val: Value(ByRef { alloc: Allocation { bytes: [3, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
 +                                          // mir::Constant
 +                                          // + span: $DIR/indirect.rs:5:13: 5:29
 +                                          // + literal: Const { ty: (u8, bool), val: Value(ByRef { alloc: Allocation { bytes: [3, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
diff --git a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
index 492938fc206..da35bf18c71 100644
--- a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
@@ -15,9 +15,6 @@
           (_3.1: u8) = const 2_u8;         // scope 0 at $DIR/issue-67019.rs:11:11: 11:17
 -         (_2.0: (u8, u8)) = move _3;      // scope 0 at $DIR/issue-67019.rs:11:10: 11:19
 +         (_2.0: (u8, u8)) = const (1_u8, 2_u8); // scope 0 at $DIR/issue-67019.rs:11:10: 11:19
-+                                          // ty::Const
-+                                          // + ty: (u8, u8)
-+                                          // + val: Value(ByRef { alloc: Allocation { bytes: [1, 2], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
 +                                          // mir::Constant
 +                                          // + span: $DIR/issue-67019.rs:11:10: 11:19
 +                                          // + literal: Const { ty: (u8, u8), val: Value(ByRef { alloc: Allocation { bytes: [1, 2], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff
index 204c1acecf5..12b02e90345 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff
@@ -20,9 +20,6 @@
           StorageLive(_2);                 // scope 1 at $DIR/mutable_variable_aggregate.rs:7:9: 7:10
 -         _2 = _1;                         // scope 1 at $DIR/mutable_variable_aggregate.rs:7:13: 7:14
 +         _2 = const (42_i32, 99_i32);     // scope 1 at $DIR/mutable_variable_aggregate.rs:7:13: 7:14
-+                                          // ty::Const
-+                                          // + ty: (i32, i32)
-+                                          // + val: Value(ByRef { alloc: Allocation { bytes: [42, 0, 0, 0, 99, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
 +                                          // mir::Constant
 +                                          // + span: $DIR/mutable_variable_aggregate.rs:7:13: 7:14
 +                                          // + literal: Const { ty: (i32, i32), val: Value(ByRef { alloc: Allocation { bytes: [42, 0, 0, 0, 99, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff
index 53ffc01ccaf..a10bac4f3ea 100644
--- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff
@@ -27,9 +27,6 @@
 -         _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
 -         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
 +         _2 = const (4_i32, false);       // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
-+                                          // ty::Const
-+                                          // + ty: (i32, bool)
-+                                          // + val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
 +                                          // mir::Constant
 +                                          // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
 +                                          // + literal: Const { ty: (i32, bool), val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff
index 53ffc01ccaf..a10bac4f3ea 100644
--- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff
@@ -27,9 +27,6 @@
 -         _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
 -         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
 +         _2 = const (4_i32, false);       // scope 0 at $DIR/optimizes_into_variable.rs:12:13: 12:18
-+                                          // ty::Const
-+                                          // + ty: (i32, bool)
-+                                          // + val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
 +                                          // mir::Constant
 +                                          // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18
 +                                          // + literal: Const { ty: (i32, bool), val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
diff --git a/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff b/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff
index fc8a5437232..f0e9916e630 100644
--- a/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/return_place.add.ConstProp.diff
@@ -9,9 +9,6 @@
 -         _1 = CheckedAdd(const 2_u32, const 2_u32); // scope 0 at $DIR/return_place.rs:6:5: 6:10
 -         assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> bb1; // scope 0 at $DIR/return_place.rs:6:5: 6:10
 +         _1 = const (4_u32, false);       // scope 0 at $DIR/return_place.rs:6:5: 6:10
-+                                          // ty::Const
-+                                          // + ty: (u32, bool)
-+                                          // + val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
 +                                          // mir::Constant
 +                                          // + span: $DIR/return_place.rs:6:5: 6:10
 +                                          // + literal: Const { ty: (u32, bool), val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [31], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
diff --git a/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff
index 2de1ab19b7c..da4b135d4c6 100644
--- a/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff
@@ -18,9 +18,6 @@
           StorageLive(_3);                 // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14
 -         _3 = _1;                         // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14
 +         _3 = const (1_u32, 2_u32);       // scope 1 at $DIR/tuple_literal_propagation.rs:5:13: 5:14
-+                                          // ty::Const
-+                                          // + ty: (u32, u32)
-+                                          // + val: Value(ByRef { alloc: Allocation { bytes: [1, 0, 0, 0, 2, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } })
 +                                          // mir::Constant
 +                                          // + span: $DIR/tuple_literal_propagation.rs:5:13: 5:14
 +                                          // + literal: Const { ty: (u32, u32), val: Value(ByRef { alloc: Allocation { bytes: [1, 0, 0, 0, 2, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) }
diff --git a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot
index 124f2d8b97a..c00eae96e08 100644
--- a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot
+++ b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot
@@ -2,5 +2,5 @@ digraph Cov_0_4 {
     graph [fontname="Courier, monospace"];
     node [fontname="Courier, monospace"];
     edge [fontname="Courier, monospace"];
-    bcb0__Cov_0_4 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 18:1-20:2<br/>    19:5-19:9: @0[0]: _0 = const true<br/>    20:2-20:2: @0.Return: return</td></tr><tr><td align="left" balign="left">bb0: Return</td></tr></table>>];
+    bcb0__Cov_0_4 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 18:1-20:2<br/>    19:5-19:9: @0[0]: Coverage::Counter(1) for $DIR/coverage_graphviz.rs:18:1 - 20:2<br/>    20:2-20:2: @0.Return: return</td></tr><tr><td align="left" balign="left">bb0: Return</td></tr></table>>];
 }
diff --git a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot
index d88193da4fb..5b6d73a7dee 100644
--- a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot
+++ b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot
@@ -2,7 +2,7 @@ digraph Cov_0_3 {
     graph [fontname="Courier, monospace"];
     node [fontname="Courier, monospace"];
     edge [fontname="Courier, monospace"];
-    bcb2__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb2</td></tr><tr><td align="left" balign="left">Expression(bcb0 - bcb1) at 13:10-13:10<br/>    13:10-13:10: @4[0]: _1 = const ()</td></tr><tr><td align="left" balign="left">bb4: Goto</td></tr></table>>];
+    bcb2__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb2</td></tr><tr><td align="left" balign="left">Expression(bcb0 - bcb1) at 13:10-13:10<br/>    13:10-13:10: @4[0]: Coverage::Expression(4294967295) = 1 - 2 for $DIR/coverage_graphviz.rs:13:10 - 13:11</td></tr><tr><td align="left" balign="left">bb4: Goto</td></tr></table>>];
     bcb1__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb1</td></tr><tr><td align="left" balign="left">Counter(bcb1) at 12:13-12:18<br/>    12:13-12:18: @5[0]: _0 = const ()<br/>Expression(bcb1 + 0) at 15:2-15:2<br/>    15:2-15:2: @5.Return: return</td></tr><tr><td align="left" balign="left">bb3: FalseEdge</td></tr><tr><td align="left" balign="left">bb5: Return</td></tr></table>>];
     bcb0__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 9:1-11:17<br/>    11:12-11:17: @1.Call: _2 = bar() -&gt; [return: bb2, unwind: bb6]<br/>    11:12-11:17: @2[0]: FakeRead(ForMatchedPlace, _2)</td></tr><tr><td align="left" balign="left">bb0: FalseUnwind<br/>bb1: Call</td></tr><tr><td align="left" balign="left">bb2: SwitchInt</td></tr></table>>];
     bcb2__Cov_0_3 -> bcb0__Cov_0_3 [label=<>];
diff --git a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
index 112a6983092..fef696df770 100644
--- a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
+++ b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
@@ -5,8 +5,8 @@
       let mut _0: bool;                    // return place in scope 0 at /the/src/instrument_coverage.rs:19:13: 19:17
   
       bb0: {
-          _0 = const true;                 // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9
 +         Coverage::Counter(1) for /the/src/instrument_coverage.rs:19:1 - 21:2; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2
+          _0 = const true;                 // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9
           return;                          // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2
       }
   }
diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
index 83dee7efa6d..9bd8c9cf613 100644
--- a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
+++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
@@ -8,6 +8,7 @@
       let mut _3: !;                       // in scope 0 at /the/src/instrument_coverage.rs:12:18: 14:10
   
       bb0: {
++         Coverage::Counter(1) for /the/src/instrument_coverage.rs:10:1 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
           falseUnwind -> [real: bb1, cleanup: bb6]; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
       }
   
@@ -21,26 +22,25 @@
   
       bb2: {
           FakeRead(ForMatchedPlace, _2);   // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17
-+         Coverage::Counter(1) for /the/src/instrument_coverage.rs:10:1 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
           switchInt(_2) -> [false: bb4, otherwise: bb3]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
       }
   
       bb3: {
++         Coverage::Expression(4294967294) = 2 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
++         Coverage::Counter(2) for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
           falseEdge -> [real: bb5, imaginary: bb4]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
       }
   
       bb4: {
++         Coverage::Expression(4294967295) = 1 - 2 for /the/src/instrument_coverage.rs:14:10 - 14:11; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
           _1 = const ();                   // scope 0 at /the/src/instrument_coverage.rs:14:10: 14:10
           StorageDead(_2);                 // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6
-+         Coverage::Expression(4294967295) = 1 - 2 for /the/src/instrument_coverage.rs:14:10 - 14:11; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
           goto -> bb0;                     // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
       }
   
       bb5: {
           _0 = const ();                   // scope 0 at /the/src/instrument_coverage.rs:13:13: 13:18
           StorageDead(_2);                 // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6
-+         Coverage::Counter(2) for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2
-+         Coverage::Expression(4294967294) = 2 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2
           return;                          // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2
       }
   
diff --git a/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
new file mode 100644
index 00000000000..7da2ff02006
--- /dev/null
+++ b/src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
@@ -0,0 +1,128 @@
+- // MIR for `discriminant` before LowerIntrinsics
++ // MIR for `discriminant` after LowerIntrinsics
+  
+  fn discriminant(_1: T) -> () {
+      debug t => _1;                       // in scope 0 at $DIR/lower_intrinsics.rs:68:24: 68:25
+      let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:68:30: 68:30
+      let _2: <T as std::marker::DiscriminantKind>::Discriminant; // in scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45
+      let mut _3: &T;                      // in scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44
+      let _4: &T;                          // in scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44
+      let _5: u8;                          // in scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45
+      let mut _6: &i32;                    // in scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
+      let _7: &i32;                        // in scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
+      let _8: i32;                         // in scope 0 at $DIR/lower_intrinsics.rs:70:43: 70:44
+      let _9: u8;                          // in scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46
+      let mut _10: &();                    // in scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
+      let _11: &();                        // in scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
+      let _12: ();                         // in scope 0 at $DIR/lower_intrinsics.rs:71:43: 71:45
+      let _13: isize;                      // in scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48
+      let mut _14: &E;                     // in scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
+      let _15: &E;                         // in scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
+      let _16: E;                          // in scope 0 at $DIR/lower_intrinsics.rs:72:43: 72:47
+      let mut _17: &E;                     // in scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
+      let mut _18: &();                    // in scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
+      let mut _19: &i32;                   // in scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45
+          StorageLive(_3);                 // scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44
+          StorageLive(_4);                 // scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44
+          _4 = &_1;                        // scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44
+          _3 = &(*_4);                     // scope 0 at $DIR/lower_intrinsics.rs:69:42: 69:44
+-         _2 = discriminant_value::<T>(move _3) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45
+-                                          // mir::Constant
+-                                          // + span: $DIR/lower_intrinsics.rs:69:5: 69:41
+-                                          // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r T) -> <T as std::marker::DiscriminantKind>::Discriminant {std::intrinsics::discriminant_value::<T>}, val: Value(Scalar(<ZST>)) }
++         _2 = discriminant((*_3));        // scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45
++         goto -> bb1;                     // scope 0 at $DIR/lower_intrinsics.rs:69:5: 69:45
+      }
+  
+      bb1: {
+          StorageDead(_3);                 // scope 0 at $DIR/lower_intrinsics.rs:69:44: 69:45
+          StorageDead(_4);                 // scope 0 at $DIR/lower_intrinsics.rs:69:45: 69:46
+          StorageDead(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:69:45: 69:46
+          StorageLive(_5);                 // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45
+          StorageLive(_6);                 // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
+          StorageLive(_7);                 // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
+          _19 = const discriminant::<T>::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
+                                           // ty::Const
+                                           // + ty: &i32
+                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[2]))
+                                           // mir::Constant
+                                           // + span: $DIR/lower_intrinsics.rs:70:42: 70:44
+                                           // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[2])) }
+          _7 = &(*_19);                    // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
+          _6 = &(*_7);                     // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
+-         _5 = discriminant_value::<i32>(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45
+-                                          // mir::Constant
+-                                          // + span: $DIR/lower_intrinsics.rs:70:5: 70:41
+-                                          // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r i32) -> <i32 as std::marker::DiscriminantKind>::Discriminant {std::intrinsics::discriminant_value::<i32>}, val: Value(Scalar(<ZST>)) }
++         _5 = discriminant((*_6));        // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45
++         goto -> bb2;                     // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45
+      }
+  
+      bb2: {
+          StorageDead(_6);                 // scope 0 at $DIR/lower_intrinsics.rs:70:44: 70:45
+          StorageDead(_7);                 // scope 0 at $DIR/lower_intrinsics.rs:70:45: 70:46
+          StorageDead(_5);                 // scope 0 at $DIR/lower_intrinsics.rs:70:45: 70:46
+          StorageLive(_9);                 // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46
+          StorageLive(_10);                // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
+          StorageLive(_11);                // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
+          _18 = const discriminant::<T>::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
+                                           // ty::Const
+                                           // + ty: &()
+                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[1]))
+                                           // mir::Constant
+                                           // + span: $DIR/lower_intrinsics.rs:71:42: 71:45
+                                           // + literal: Const { ty: &(), val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[1])) }
+          _11 = &(*_18);                   // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
+          _10 = &(*_11);                   // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
+-         _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46
+-                                          // mir::Constant
+-                                          // + span: $DIR/lower_intrinsics.rs:71:5: 71:41
+-                                          // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r ()) -> <() as std::marker::DiscriminantKind>::Discriminant {std::intrinsics::discriminant_value::<()>}, val: Value(Scalar(<ZST>)) }
++         _9 = discriminant((*_10));       // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46
++         goto -> bb3;                     // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46
+      }
+  
+      bb3: {
+          StorageDead(_10);                // scope 0 at $DIR/lower_intrinsics.rs:71:45: 71:46
+          StorageDead(_11);                // scope 0 at $DIR/lower_intrinsics.rs:71:46: 71:47
+          StorageDead(_9);                 // scope 0 at $DIR/lower_intrinsics.rs:71:46: 71:47
+          StorageLive(_13);                // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48
+          StorageLive(_14);                // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
+          StorageLive(_15);                // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
+          _17 = const discriminant::<T>::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
+                                           // ty::Const
+                                           // + ty: &E
+                                           // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[0]))
+                                           // mir::Constant
+                                           // + span: $DIR/lower_intrinsics.rs:72:42: 72:47
+                                           // + literal: Const { ty: &E, val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[0])) }
+          _15 = &(*_17);                   // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
+          _14 = &(*_15);                   // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
+-         _13 = discriminant_value::<E>(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48
+-                                          // mir::Constant
+-                                          // + span: $DIR/lower_intrinsics.rs:72:5: 72:41
+-                                          // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r E) -> <E as std::marker::DiscriminantKind>::Discriminant {std::intrinsics::discriminant_value::<E>}, val: Value(Scalar(<ZST>)) }
++         _13 = discriminant((*_14));      // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48
++         goto -> bb4;                     // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48
+      }
+  
+      bb4: {
+          StorageDead(_14);                // scope 0 at $DIR/lower_intrinsics.rs:72:47: 72:48
+          StorageDead(_15);                // scope 0 at $DIR/lower_intrinsics.rs:72:48: 72:49
+          StorageDead(_13);                // scope 0 at $DIR/lower_intrinsics.rs:72:48: 72:49
+          _0 = const ();                   // scope 0 at $DIR/lower_intrinsics.rs:68:30: 73:2
+          drop(_1) -> bb5;                 // scope 0 at $DIR/lower_intrinsics.rs:73:1: 73:2
+      }
+  
+      bb5: {
+          return;                          // scope 0 at $DIR/lower_intrinsics.rs:73:2: 73:2
+      }
+  
+      bb6 (cleanup): {
+          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:68:1: 73:2
+      }
+  }
+  
diff --git a/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff
index 6b2d3833c2f..096bba64c0b 100644
--- a/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.forget.LowerIntrinsics.diff
@@ -4,28 +4,30 @@
   fn forget(_1: T) -> () {
       debug t => _1;                       // in scope 0 at $DIR/lower_intrinsics.rs:18:18: 18:19
       let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:18:24: 18:24
-      let _2: ();                          // in scope 0 at $DIR/lower_intrinsics.rs:19:14: 19:41
-      let mut _3: T;                       // in scope 0 at $DIR/lower_intrinsics.rs:19:39: 19:40
-      scope 1 {
-      }
+      let mut _2: T;                       // in scope 0 at $DIR/lower_intrinsics.rs:19:30: 19:31
   
       bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:43
-          StorageLive(_3);                 // scope 1 at $DIR/lower_intrinsics.rs:19:39: 19:40
-          _3 = move _1;                    // scope 1 at $DIR/lower_intrinsics.rs:19:39: 19:40
--         _2 = std::intrinsics::forget::<T>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:19:14: 19:41
+          StorageLive(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:19:30: 19:31
+          _2 = move _1;                    // scope 0 at $DIR/lower_intrinsics.rs:19:30: 19:31
+-         _0 = std::intrinsics::forget::<T>(move _2) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:32
 -                                          // mir::Constant
--                                          // + span: $DIR/lower_intrinsics.rs:19:14: 19:38
--                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(T) {std::intrinsics::forget::<T>}, val: Value(Scalar(<ZST>)) }
-+         _2 = const ();                   // scope 1 at $DIR/lower_intrinsics.rs:19:14: 19:41
-+         goto -> bb1;                     // scope 1 at $DIR/lower_intrinsics.rs:19:14: 19:41
+-                                          // + span: $DIR/lower_intrinsics.rs:19:5: 19:29
+-                                          // + literal: Const { ty: extern "rust-intrinsic" fn(T) {std::intrinsics::forget::<T>}, val: Value(Scalar(<ZST>)) }
++         _0 = const ();                   // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:32
++         goto -> bb1;                     // scope 0 at $DIR/lower_intrinsics.rs:19:5: 19:32
       }
   
       bb1: {
-          StorageDead(_3);                 // scope 1 at $DIR/lower_intrinsics.rs:19:40: 19:41
-          StorageDead(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:19:43: 19:44
-          _0 = const ();                   // scope 0 at $DIR/lower_intrinsics.rs:18:24: 20:2
+          StorageDead(_2);                 // scope 0 at $DIR/lower_intrinsics.rs:19:31: 19:32
+          goto -> bb2;                     // scope 0 at $DIR/lower_intrinsics.rs:20:1: 20:2
+      }
+  
+      bb2: {
           return;                          // scope 0 at $DIR/lower_intrinsics.rs:20:2: 20:2
       }
+  
+      bb3 (cleanup): {
+          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:18:1: 20:2
+      }
   }
   
diff --git a/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff
index e973014c40d..218b1c96433 100644
--- a/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.non_const.LowerIntrinsics.diff
@@ -27,5 +27,9 @@
           StorageDead(_1);                 // scope 0 at $DIR/lower_intrinsics.rs:59:1: 59:2
           return;                          // scope 0 at $DIR/lower_intrinsics.rs:59:2: 59:2
       }
+  
+      bb2 (cleanup): {
+          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:55:1: 59:2
+      }
   }
   
diff --git a/src/test/mir-opt/lower_intrinsics.rs b/src/test/mir-opt/lower_intrinsics.rs
index de5f692b7da..d9891465dab 100644
--- a/src/test/mir-opt/lower_intrinsics.rs
+++ b/src/test/mir-opt/lower_intrinsics.rs
@@ -16,7 +16,7 @@ pub fn size_of<T>() -> usize {
 
 // EMIT_MIR lower_intrinsics.forget.LowerIntrinsics.diff
 pub fn forget<T>(t: T) {
-    unsafe { core::intrinsics::forget(t) };
+    core::intrinsics::forget(t)
 }
 
 // EMIT_MIR lower_intrinsics.unreachable.LowerIntrinsics.diff
@@ -45,11 +45,11 @@ pub fn f_dispatch<T>(t: T) {
 }
 
 #[inline(never)]
-pub fn f_zst<T>(t: T) {
+pub fn f_zst<T>(_t: T) {
 }
 
 #[inline(never)]
-pub fn f_non_zst<T>(t: T) {}
+pub fn f_non_zst<T>(_t: T) {}
 
 // EMIT_MIR lower_intrinsics.non_const.LowerIntrinsics.diff
 pub fn non_const<T>() -> usize {
@@ -57,3 +57,17 @@ pub fn non_const<T>() -> usize {
     let size_of_t = core::intrinsics::size_of::<T>;
     size_of_t()
 }
+
+pub enum E {
+    A,
+    B,
+    C,
+}
+
+// EMIT_MIR lower_intrinsics.discriminant.LowerIntrinsics.diff
+pub fn discriminant<T>(t: T) {
+    core::intrinsics::discriminant_value(&t);
+    core::intrinsics::discriminant_value(&0);
+    core::intrinsics::discriminant_value(&());
+    core::intrinsics::discriminant_value(&E::B);
+}
diff --git a/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff
index 262385e9f5e..b5a77702a8e 100644
--- a/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.size_of.LowerIntrinsics.diff
@@ -16,5 +16,9 @@
       bb1: {
           return;                          // scope 0 at $DIR/lower_intrinsics.rs:15:2: 15:2
       }
+  
+      bb2 (cleanup): {
+          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:13:1: 15:2
+      }
   }
   
diff --git a/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
index b58cb333244..a04b79d47d4 100644
--- a/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.diff
@@ -18,5 +18,9 @@
 -                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value(Scalar(<ZST>)) }
 +         unreachable;                     // scope 1 at $DIR/lower_intrinsics.rs:24:14: 24:45
       }
+  
+      bb1 (cleanup): {
+          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:23:1: 25:2
+      }
   }
   
diff --git a/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff
index ce03ce90e52..badfef30e6f 100644
--- a/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff
+++ b/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff
@@ -79,5 +79,9 @@
           StorageDead(_3);                 // scope 0 at $DIR/lower_intrinsics.rs:10:1: 10:2
           return;                          // scope 0 at $DIR/lower_intrinsics.rs:10:2: 10:2
       }
+  
+      bb4 (cleanup): {
+          resume;                          // scope 0 at $DIR/lower_intrinsics.rs:6:1: 10:2
+      }
   }
   
diff --git a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff
index 3064e92f900..34f8ca870cd 100644
--- a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff
@@ -42,9 +42,6 @@
                                            // mir::Constant
                                            // + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:12
                                            // + literal: Const { ty: fn(((), ())) {use_zst}, val: Value(Scalar(<ZST>)) }
-                                           // ty::Const
-                                           // + ty: ((), ())
-                                           // + val: Value(Scalar(<ZST>))
                                            // mir::Constant
                                            // + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22
                                            // + literal: Const { ty: ((), ()), val: Value(Scalar(<ZST>)) }
diff --git a/src/test/run-make-fulldeps/coverage-reports/Makefile b/src/test/run-make-fulldeps/coverage-reports/Makefile
index a5d6970009a..c4700b317ef 100644
--- a/src/test/run-make-fulldeps/coverage-reports/Makefile
+++ b/src/test/run-make-fulldeps/coverage-reports/Makefile
@@ -9,11 +9,13 @@
 BASEDIR=../coverage-reports
 SOURCEDIR=../coverage
 
-# The `llvm-cov show` flag `--debug`, used to generate the `counters` output files, is only enabled
-# if LLVM assertions are enabled. Requires Rust config `llvm/optimize` and not
+# The `llvm-cov show` flag `--debug`, used to generate the `counters` output files, is only
+# enabled if LLVM assertions are enabled. This requires Rust config `llvm/optimize` and not
 # `llvm/release_debuginfo`. Note that some CI builds disable debug assertions (by setting
-# `NO_LLVM_ASSERTIONS=1`), so it is not OK to fail the test, but `bless`ed test results cannot be
-# generated without debug assertions.
+# `NO_LLVM_ASSERTIONS=1`), so the tests must still pass even if the `--debug` flag is
+# not supported. (Note that `counters` files are only produced in the `$(TMPDIR)`
+# directory, for inspection and debugging support. They are *not* copied to `expected_*`
+# files when `--bless`ed.)
 LLVM_COV_DEBUG := $(shell \
 		"$(LLVM_BIN_DIR)"/llvm-cov show --debug 2>&1 | \
 		grep -q "Unknown command line argument '--debug'"; \
@@ -51,11 +53,10 @@ endif
 # Yes these `--ignore-filename-regex=` options are included in all invocations of `llvm-cov show`
 # for now, but it is effectively ignored for all tests that don't include this file anyway.
 #
-# Note that it's also possible the `_counters.<test>.txt` and `<test>.json` files may order
-# results from multiple files inconsistently, which might also have to be accomodated if and when
-# we allow `llvm-cov` to produce results for multiple files. (The path separators appear to be
-# normalized to `/` in those files, thankfully.) But since we are ignoring results for all but one
-# file, this workaround addresses those potential issues as well.
+# (Note that it's also possible the `_counters.<test>.txt` and `<test>.json` files (if generated)
+# may order results from multiple files inconsistently, which might also have to be accomodated
+# if and when we allow `llvm-cov` to produce results for multiple files. Note, the path separators
+# appear to be normalized to `/` in those files, thankfully.)
 LLVM_COV_IGNORE_FILES=\
 	--ignore-filename-regex=uses_crate.rs
 
@@ -77,9 +78,7 @@ endif
 .PHONY: clear_expected_if_blessed
 clear_expected_if_blessed:
 ifdef RUSTC_BLESS_TEST
-	rm -f expected_export_coverage.*.json
-	rm -f expected_show_coverage.*.txt
-	rm -f expected_show_coverage_counters.*.txt
+	rm -f expected_*
 endif
 
 -include clear_expected_if_blessed
@@ -99,7 +98,7 @@ endif
 	# Run it in order to generate some profiling data,
 	# with `LLVM_PROFILE_FILE=<profdata_file>` environment variable set to
 	# output the coverage stats for this run.
-	LLVM_PROFILE_FILE="$(TMPDIR)"/$@.profraw \
+	LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p.profraw \
 			$(call RUN,$@) || \
 			( \
 				status=$$?; \
@@ -109,9 +108,16 @@ endif
 				) \
 			)
 
+	# Run it through rustdoc as well to cover doctests
+	LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p.profraw \
+			$(RUSTDOC) --crate-name workaround_for_79771 --test $(SOURCEDIR)/$@.rs \
+			$$( grep -q '^\/\/ require-rust-edition-2018' $(SOURCEDIR)/$@.rs && echo "--edition=2018" ) \
+			-L "$(TMPDIR)" -Zinstrument-coverage \
+			-Z unstable-options --persist-doctests=$(TMPDIR)/rustdoc-$@
+
 	# Postprocess the profiling data so it can be used by the llvm-cov tool
 	"$(LLVM_BIN_DIR)"/llvm-profdata merge --sparse \
-			"$(TMPDIR)"/$@.profraw \
+			"$(TMPDIR)"/$@-*.profraw \
 			-o "$(TMPDIR)"/$@.profdata
 
 	# Generate a coverage report using `llvm-cov show`.
@@ -122,8 +128,15 @@ endif
 			--show-line-counts-or-regions \
 			--instr-profile="$(TMPDIR)"/$@.profdata \
 			$(call BIN,"$(TMPDIR)"/$@) \
-		> "$(TMPDIR)"/actual_show_coverage.$@.txt \
-		2> "$(TMPDIR)"/show_coverage_stderr.$@.txt || \
+			$$( \
+				for file in $(TMPDIR)/rustdoc-$@/*/rust_out; \
+				do \
+				[[ -x $$file ]] && printf "%s %s " -object $$file; \
+				done \
+			) \
+		2> "$(TMPDIR)"/show_coverage_stderr.$@.txt \
+		| "$(PYTHON)" $(BASEDIR)/normalize_paths.py \
+		> "$(TMPDIR)"/actual_show_coverage.$@.txt || \
 	( status=$$? ; \
 		>&2 cat "$(TMPDIR)"/show_coverage_stderr.$@.txt ; \
 		exit $$status \
@@ -140,12 +153,8 @@ endif
 ifdef RUSTC_BLESS_TEST
 	cp "$(TMPDIR)"/actual_show_coverage.$@.txt \
 			expected_show_coverage.$@.txt
-	cp "$(TMPDIR)"/actual_show_coverage_counters.$@.txt \
-			expected_show_coverage_counters.$@.txt
 else
-	# Compare the show coverage output (`--bless` refreshes `typical` files)
-	# Note `llvm-cov show` output for some programs can vary, but can be ignored
-	# by inserting `// ignore-llvm-cov-show-diffs` at the top of the source file.
+	# Compare the show coverage output (`--bless` refreshes `typical` files).
 	#
 	# FIXME(richkadel): None of the Rust test source samples have the
 	# `// ignore-llvm-cov-show-diffs` anymore. This directive exists to work around a limitation
@@ -158,8 +167,10 @@ else
 	#
 	# This workaround only works if the coverage counts are identical across all reported
 	# instantiations. If there is no way to ensure this, you may need to apply the
-	# `// ignore-llvm-cov-show-diffs` directive, and rely on the `.json` and counter
-	# files for validating results have not changed.
+	# `// ignore-llvm-cov-show-diffs` directive, and check for differences using the
+	# `.json` files to validate that results have not changed. (Until then, the JSON
+	# files are redundant, so there is no need to generate `expected_*.json` files or
+	# compare actual JSON results.)
 
 	$(DIFF) --ignore-matching-lines='::<.*>.*:$$' \
 		expected_show_coverage.$@.txt "$(TMPDIR)"/actual_show_coverage.$@.txt || \
@@ -169,37 +180,77 @@ else
 		( >&2 echo 'diff failed, and not suppressed without `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs'; \
 			false \
 		)
-
-ifdef DEBUG_FLAG
-	$(DIFF) expected_show_coverage_counters.$@.txt "$(TMPDIR)"/actual_show_coverage_counters.$@.txt || \
-		( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \
-			>&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \
-		) || \
-		( >&2 echo 'diff failed, and not suppressed without `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs'; \
-			>&2 echo '(Ignore anyway until mangled function names in "counters" files are demangled.)' \
-		)
-
-		# FIXME(richkadel): Apply the demangler to the `*_show_coverage_counters.*.txt` files,
-		# so the crate disambiguator differences will be stripped away. At that point, these files
-		# will be less likely to vary, and the last `echo` above (starting with "Ignore anyway")
-		# can be replaced with `false` to fail the test.
 endif
 
-endif
+####################################################################################################
 
-	# Generate a coverage report in JSON, using `llvm-cov export`, and fail if
-	# there are differences from the expected output.
-	"$(LLVM_BIN_DIR)"/llvm-cov export \
-			$(LLVM_COV_IGNORE_FILES) \
-			--summary-only \
-			--instr-profile="$(TMPDIR)"/$@.profdata \
-			$(call BIN,"$(TMPDIR)"/$@) \
-		| "$(PYTHON)" $(BASEDIR)/prettify_json.py \
-		> "$(TMPDIR)"/actual_export_coverage.$@.json
+# The following Makefile content was used to copy the generated `counters` files
+# to `expected_` files (when `--bless`ed) and to compare them via `diff`; but for
+# multiple reasons, these files cannot easily be used for test validation:
+#
+#   * Output lines can be produced in non-deterministic order (depending on the
+#     target platform, and sometimes on unrelated codegen changes).
+#   * Some lines include demangled function names, making them more challenging
+#     to interpret and compare.
+#
+# The files are still generated (in `$(TMPDIR)`) to support developers wanting
+# to inspect the counters, for debugging purposes.
+#
+# ifdef RUSTC_BLESS_TEST
+# 	cp "$(TMPDIR)"/actual_show_coverage_counters.$@.txt \
+# 			expected_show_coverage_counters.$@.txt
+# else
+#
+# ifdef DEBUG_FLAG
+# 	$(DIFF) expected_show_coverage_counters.$@.txt "$(TMPDIR)"/actual_show_coverage_counters.$@.txt || \
+# 		( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \
+# 			>&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \
+# 		) || \
+# 		( >&2 echo 'diff failed, and not suppressed without `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs'; \
+# 			>&2 echo '(Ignore anyway until mangled function names in "counters" files are demangled.)' \
+# 		)
+# endif
+#
+# endif
 
-ifdef RUSTC_BLESS_TEST
-	cp "$(TMPDIR)"/actual_export_coverage.$@.json expected_export_coverage.$@.json
-else
-	# Check that exported JSON coverage data matches what we expect (`--bless` refreshes `expected`)
-	$(DIFF) expected_export_coverage.$@.json "$(TMPDIR)"/actual_export_coverage.$@.json
-endif
+####################################################################################################
+
+# The following Makefile content, and short JSON script, were used to generate
+# coverage reports in JSON when the `llvm-cov show` reports were less reliable for
+# testing. At the present time, however, the `llvm-cov show` results, and methods
+# for comparing them, are working for all tests, making the JSON reports redundant.
+#
+# If this changes in the future, the scripts are left here, commented out, but can
+# be resurrected if desired. This could be used to compare *only* the JSON files;
+# and in that case, the `llvm-cov show` reports can be ignored by inserting
+# `// ignore-llvm-cov-show-diffs` at the top of the source file.
+#
+# 	# Generate a coverage report in JSON, using `llvm-cov export`, and fail if
+# 	# there are differences from the expected output.
+# 	"$(LLVM_BIN_DIR)"/llvm-cov export \
+# 			$(LLVM_COV_IGNORE_FILES) \
+# 			--summary-only \
+# 			--instr-profile="$(TMPDIR)"/$@.profdata \
+# 			$(call BIN,"$(TMPDIR)"/$@) \
+# 		| "$(PYTHON)" $(BASEDIR)/prettify_json.py \
+# 		> "$(TMPDIR)"/actual_export_coverage.$@.json
+#
+# ifdef RUSTC_BLESS_TEST
+# 	cp "$(TMPDIR)"/actual_export_coverage.$@.json expected_export_coverage.$@.json
+# else
+# 	# Check that exported JSON coverage data matches what we expect (`--bless` refreshes `expected`)
+# 	$(DIFF) expected_export_coverage.$@.json "$(TMPDIR)"/actual_export_coverage.$@.json
+# endif
+#
+# # # If generating coverage reports in JSON, this Makefile is accompanied by
+# # # a Python script, `prettify_json.py`, which is defined:
+# #
+# # #!/usr/bin/env python
+# #
+# # import sys
+# # import json
+# #
+# # # Try to decode line in order to ensure it is a valid JSON document
+# # for line in sys.stdin:
+# #     parsed = json.loads(line)
+# #     print (json.dumps(parsed, indent=2, separators=(',', ': '), sort_keys=True))
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.abort.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.abort.json
deleted file mode 100644
index db7dd0b15e9..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.abort.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/abort.rs",
-          "summary": {
-            "functions": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "lines": {
-              "count": 19,
-              "covered": 17,
-              "percent": 89.47368421052632
-            },
-            "regions": {
-              "count": 17,
-              "covered": 16,
-              "notcovered": 1,
-              "percent": 94.11764705882352
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "lines": {
-          "count": 19,
-          "covered": 17,
-          "percent": 89.47368421052632
-        },
-        "regions": {
-          "count": 17,
-          "covered": 16,
-          "notcovered": 1,
-          "percent": 94.11764705882352
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json
deleted file mode 100644
index 024b5f11179..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/assert.rs",
-          "summary": {
-            "functions": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "lines": {
-              "count": 15,
-              "covered": 12,
-              "percent": 80
-            },
-            "regions": {
-              "count": 14,
-              "covered": 12,
-              "notcovered": 2,
-              "percent": 85.71428571428571
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "lines": {
-          "count": 15,
-          "covered": 12,
-          "percent": 80
-        },
-        "regions": {
-          "count": 14,
-          "covered": 12,
-          "notcovered": 2,
-          "percent": 85.71428571428571
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.async.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.async.json
deleted file mode 100644
index 794a2e38253..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.async.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/async.rs",
-          "summary": {
-            "functions": {
-              "count": 17,
-              "covered": 16,
-              "percent": 94.11764705882352
-            },
-            "instantiations": {
-              "count": 17,
-              "covered": 16,
-              "percent": 94.11764705882352
-            },
-            "lines": {
-              "count": 105,
-              "covered": 77,
-              "percent": 73.33333333333333
-            },
-            "regions": {
-              "count": 78,
-              "covered": 36,
-              "notcovered": 42,
-              "percent": 46.15384615384615
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 17,
-          "covered": 16,
-          "percent": 94.11764705882352
-        },
-        "instantiations": {
-          "count": 17,
-          "covered": 16,
-          "percent": 94.11764705882352
-        },
-        "lines": {
-          "count": 105,
-          "covered": 77,
-          "percent": 73.33333333333333
-        },
-        "regions": {
-          "count": 78,
-          "covered": 36,
-          "notcovered": 42,
-          "percent": 46.15384615384615
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.closure.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.closure.json
deleted file mode 100644
index 39e1dea66f9..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.closure.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/closure.rs",
-          "summary": {
-            "functions": {
-              "count": 6,
-              "covered": 4,
-              "percent": 66.66666666666666
-            },
-            "instantiations": {
-              "count": 6,
-              "covered": 4,
-              "percent": 66.66666666666666
-            },
-            "lines": {
-              "count": 161,
-              "covered": 131,
-              "percent": 81.36645962732919
-            },
-            "regions": {
-              "count": 42,
-              "covered": 22,
-              "notcovered": 20,
-              "percent": 52.38095238095239
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 6,
-          "covered": 4,
-          "percent": 66.66666666666666
-        },
-        "instantiations": {
-          "count": 6,
-          "covered": 4,
-          "percent": 66.66666666666666
-        },
-        "lines": {
-          "count": 161,
-          "covered": 131,
-          "percent": 81.36645962732919
-        },
-        "regions": {
-          "count": 42,
-          "covered": 22,
-          "notcovered": 20,
-          "percent": 52.38095238095239
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.conditions.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.conditions.json
deleted file mode 100644
index 69356604856..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.conditions.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/conditions.rs",
-          "summary": {
-            "functions": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "lines": {
-              "count": 64,
-              "covered": 33,
-              "percent": 51.5625
-            },
-            "regions": {
-              "count": 64,
-              "covered": 21,
-              "notcovered": 43,
-              "percent": 32.8125
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "lines": {
-          "count": 64,
-          "covered": 33,
-          "percent": 51.5625
-        },
-        "regions": {
-          "count": 64,
-          "covered": 21,
-          "notcovered": 43,
-          "percent": 32.8125
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.dead_code.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.dead_code.json
deleted file mode 100644
index 6588ba90274..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.dead_code.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/dead_code.rs",
-          "summary": {
-            "functions": {
-              "count": 1,
-              "covered": 0,
-              "percent": 0
-            },
-            "instantiations": {
-              "count": 1,
-              "covered": 0,
-              "percent": 0
-            },
-            "lines": {
-              "count": 33,
-              "covered": 11,
-              "percent": 33.33333333333333
-            },
-            "regions": {
-              "count": 12,
-              "covered": 3,
-              "notcovered": 9,
-              "percent": 25
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 1,
-          "covered": 0,
-          "percent": 0
-        },
-        "instantiations": {
-          "count": 1,
-          "covered": 0,
-          "percent": 0
-        },
-        "lines": {
-          "count": 33,
-          "covered": 11,
-          "percent": 33.33333333333333
-        },
-        "regions": {
-          "count": 12,
-          "covered": 3,
-          "notcovered": 9,
-          "percent": 25
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.drop_trait.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.drop_trait.json
deleted file mode 100644
index e303d3802f5..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.drop_trait.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/drop_trait.rs",
-          "summary": {
-            "functions": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "lines": {
-              "count": 12,
-              "covered": 12,
-              "percent": 100
-            },
-            "regions": {
-              "count": 4,
-              "covered": 4,
-              "notcovered": 0,
-              "percent": 100
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "lines": {
-          "count": 12,
-          "covered": 12,
-          "percent": 100
-        },
-        "regions": {
-          "count": 4,
-          "covered": 4,
-          "notcovered": 0,
-          "percent": 100
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.generics.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.generics.json
deleted file mode 100644
index bfae69d7ac4..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.generics.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/generics.rs",
-          "summary": {
-            "functions": {
-              "count": 3,
-              "covered": 3,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 5,
-              "covered": 5,
-              "percent": 100
-            },
-            "lines": {
-              "count": 18,
-              "covered": 18,
-              "percent": 100
-            },
-            "regions": {
-              "count": 5,
-              "covered": 5,
-              "notcovered": 0,
-              "percent": 100
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 3,
-          "covered": 3,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 5,
-          "covered": 5,
-          "percent": 100
-        },
-        "lines": {
-          "count": 18,
-          "covered": 18,
-          "percent": 100
-        },
-        "regions": {
-          "count": 5,
-          "covered": 5,
-          "notcovered": 0,
-          "percent": 100
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if.json
deleted file mode 100644
index 8f233f8bfc5..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/if.rs",
-          "summary": {
-            "functions": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "lines": {
-              "count": 26,
-              "covered": 26,
-              "percent": 100
-            },
-            "regions": {
-              "count": 4,
-              "covered": 3,
-              "notcovered": 1,
-              "percent": 75
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "lines": {
-          "count": 26,
-          "covered": 26,
-          "percent": 100
-        },
-        "regions": {
-          "count": 4,
-          "covered": 3,
-          "notcovered": 1,
-          "percent": 75
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if_else.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if_else.json
deleted file mode 100644
index 5c0454e1ecb..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.if_else.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/if_else.rs",
-          "summary": {
-            "functions": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "lines": {
-              "count": 32,
-              "covered": 23,
-              "percent": 71.875
-            },
-            "regions": {
-              "count": 7,
-              "covered": 5,
-              "notcovered": 2,
-              "percent": 71.42857142857143
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "lines": {
-          "count": 32,
-          "covered": 23,
-          "percent": 71.875
-        },
-        "regions": {
-          "count": 7,
-          "covered": 5,
-          "notcovered": 2,
-          "percent": 71.42857142857143
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.inner_items.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.inner_items.json
deleted file mode 100644
index 07ef9a9ab33..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.inner_items.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/inner_items.rs",
-          "summary": {
-            "functions": {
-              "count": 4,
-              "covered": 4,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 4,
-              "covered": 4,
-              "percent": 100
-            },
-            "lines": {
-              "count": 29,
-              "covered": 29,
-              "percent": 100
-            },
-            "regions": {
-              "count": 11,
-              "covered": 9,
-              "notcovered": 2,
-              "percent": 81.81818181818183
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 4,
-          "covered": 4,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 4,
-          "covered": 4,
-          "percent": 100
-        },
-        "lines": {
-          "count": 29,
-          "covered": 29,
-          "percent": 100
-        },
-        "regions": {
-          "count": 11,
-          "covered": 9,
-          "notcovered": 2,
-          "percent": 81.81818181818183
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.lazy_boolean.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.lazy_boolean.json
deleted file mode 100644
index c3a96b08e6a..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.lazy_boolean.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/lazy_boolean.rs",
-          "summary": {
-            "functions": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "lines": {
-              "count": 44,
-              "covered": 33,
-              "percent": 75
-            },
-            "regions": {
-              "count": 28,
-              "covered": 21,
-              "notcovered": 7,
-              "percent": 75
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "lines": {
-          "count": 44,
-          "covered": 33,
-          "percent": 75
-        },
-        "regions": {
-          "count": 28,
-          "covered": 21,
-          "notcovered": 7,
-          "percent": 75
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loop_break_value.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loop_break_value.json
deleted file mode 100644
index 6cb1465c818..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loop_break_value.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/loop_break_value.rs",
-          "summary": {
-            "functions": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "lines": {
-              "count": 11,
-              "covered": 11,
-              "percent": 100
-            },
-            "regions": {
-              "count": 1,
-              "covered": 1,
-              "notcovered": 0,
-              "percent": 100
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "lines": {
-          "count": 11,
-          "covered": 11,
-          "percent": 100
-        },
-        "regions": {
-          "count": 1,
-          "covered": 1,
-          "notcovered": 0,
-          "percent": 100
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loops_branches.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loops_branches.json
deleted file mode 100644
index 6d566f2b818..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.loops_branches.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/loops_branches.rs",
-          "summary": {
-            "functions": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "lines": {
-              "count": 11,
-              "covered": 11,
-              "percent": 100
-            },
-            "regions": {
-              "count": 8,
-              "covered": 7,
-              "notcovered": 1,
-              "percent": 87.5
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "lines": {
-          "count": 11,
-          "covered": 11,
-          "percent": 100
-        },
-        "regions": {
-          "count": 8,
-          "covered": 7,
-          "notcovered": 1,
-          "percent": 87.5
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.nested_loops.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.nested_loops.json
deleted file mode 100644
index bf3b5cb031b..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.nested_loops.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/nested_loops.rs",
-          "summary": {
-            "functions": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "lines": {
-              "count": 22,
-              "covered": 17,
-              "percent": 77.27272727272727
-            },
-            "regions": {
-              "count": 14,
-              "covered": 11,
-              "notcovered": 3,
-              "percent": 78.57142857142857
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "lines": {
-          "count": 22,
-          "covered": 17,
-          "percent": 77.27272727272727
-        },
-        "regions": {
-          "count": 14,
-          "covered": 11,
-          "notcovered": 3,
-          "percent": 78.57142857142857
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json
deleted file mode 100644
index 030d7b033f0..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/overflow.rs",
-          "summary": {
-            "functions": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "lines": {
-              "count": 23,
-              "covered": 19,
-              "percent": 82.6086956521739
-            },
-            "regions": {
-              "count": 13,
-              "covered": 11,
-              "notcovered": 2,
-              "percent": 84.61538461538461
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "lines": {
-          "count": 23,
-          "covered": 19,
-          "percent": 82.6086956521739
-        },
-        "regions": {
-          "count": 13,
-          "covered": 11,
-          "notcovered": 2,
-          "percent": 84.61538461538461
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json
deleted file mode 100644
index b1d44fdfeac..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/panic_unwind.rs",
-          "summary": {
-            "functions": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "lines": {
-              "count": 19,
-              "covered": 16,
-              "percent": 84.21052631578947
-            },
-            "regions": {
-              "count": 13,
-              "covered": 11,
-              "notcovered": 2,
-              "percent": 84.61538461538461
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "lines": {
-          "count": 19,
-          "covered": 16,
-          "percent": 84.21052631578947
-        },
-        "regions": {
-          "count": 13,
-          "covered": 11,
-          "notcovered": 2,
-          "percent": 84.61538461538461
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.partial_eq.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.partial_eq.json
deleted file mode 100644
index 6a0d83a6d0e..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.partial_eq.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/partial_eq.rs",
-          "summary": {
-            "functions": {
-              "count": 5,
-              "covered": 4,
-              "percent": 80
-            },
-            "instantiations": {
-              "count": 5,
-              "covered": 4,
-              "percent": 80
-            },
-            "lines": {
-              "count": 18,
-              "covered": 16,
-              "percent": 88.88888888888889
-            },
-            "regions": {
-              "count": 24,
-              "covered": 5,
-              "notcovered": 19,
-              "percent": 20.833333333333336
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 5,
-          "covered": 4,
-          "percent": 80
-        },
-        "instantiations": {
-          "count": 5,
-          "covered": 4,
-          "percent": 80
-        },
-        "lines": {
-          "count": 18,
-          "covered": 16,
-          "percent": 88.88888888888889
-        },
-        "regions": {
-          "count": 24,
-          "covered": 5,
-          "notcovered": 19,
-          "percent": 20.833333333333336
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_loop.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_loop.json
deleted file mode 100644
index 4c849692a03..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_loop.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/simple_loop.rs",
-          "summary": {
-            "functions": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "lines": {
-              "count": 25,
-              "covered": 25,
-              "percent": 100
-            },
-            "regions": {
-              "count": 7,
-              "covered": 6,
-              "notcovered": 1,
-              "percent": 85.71428571428571
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "lines": {
-          "count": 25,
-          "covered": 25,
-          "percent": 100
-        },
-        "regions": {
-          "count": 7,
-          "covered": 6,
-          "notcovered": 1,
-          "percent": 85.71428571428571
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_match.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_match.json
deleted file mode 100644
index 41bc4d57d59..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.simple_match.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/simple_match.rs",
-          "summary": {
-            "functions": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "lines": {
-              "count": 27,
-              "covered": 27,
-              "percent": 100
-            },
-            "regions": {
-              "count": 11,
-              "covered": 10,
-              "notcovered": 1,
-              "percent": 90.9090909090909
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "lines": {
-          "count": 27,
-          "covered": 27,
-          "percent": 100
-        },
-        "regions": {
-          "count": 11,
-          "covered": 10,
-          "notcovered": 1,
-          "percent": 90.9090909090909
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.tight_inf_loop.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.tight_inf_loop.json
deleted file mode 100644
index 7f6c90b92d2..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.tight_inf_loop.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/tight_inf_loop.rs",
-          "summary": {
-            "functions": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "lines": {
-              "count": 4,
-              "covered": 4,
-              "percent": 100
-            },
-            "regions": {
-              "count": 2,
-              "covered": 2,
-              "notcovered": 0,
-              "percent": 100
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "lines": {
-          "count": 4,
-          "covered": 4,
-          "percent": 100
-        },
-        "regions": {
-          "count": 2,
-          "covered": 2,
-          "notcovered": 0,
-          "percent": 100
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.try_error_result.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.try_error_result.json
deleted file mode 100644
index df4de9dc54b..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.try_error_result.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/try_error_result.rs",
-          "summary": {
-            "functions": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 2,
-              "covered": 2,
-              "percent": 100
-            },
-            "lines": {
-              "count": 20,
-              "covered": 18,
-              "percent": 90
-            },
-            "regions": {
-              "count": 16,
-              "covered": 12,
-              "notcovered": 4,
-              "percent": 75
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 2,
-          "covered": 2,
-          "percent": 100
-        },
-        "lines": {
-          "count": 20,
-          "covered": 18,
-          "percent": 90
-        },
-        "regions": {
-          "count": 16,
-          "covered": 12,
-          "notcovered": 4,
-          "percent": 75
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.uses_crate.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.uses_crate.json
deleted file mode 100644
index 35ddd58fc43..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.uses_crate.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/lib/used_crate.rs",
-          "summary": {
-            "functions": {
-              "count": 6,
-              "covered": 5,
-              "percent": 83.33333333333334
-            },
-            "instantiations": {
-              "count": 10,
-              "covered": 8,
-              "percent": 80
-            },
-            "lines": {
-              "count": 46,
-              "covered": 26,
-              "percent": 56.52173913043478
-            },
-            "regions": {
-              "count": 19,
-              "covered": 8,
-              "notcovered": 11,
-              "percent": 42.10526315789473
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 6,
-          "covered": 5,
-          "percent": 83.33333333333334
-        },
-        "instantiations": {
-          "count": 10,
-          "covered": 8,
-          "percent": 80
-        },
-        "lines": {
-          "count": 46,
-          "covered": 26,
-          "percent": 56.52173913043478
-        },
-        "regions": {
-          "count": 19,
-          "covered": 8,
-          "notcovered": 11,
-          "percent": 42.10526315789473
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while.json
deleted file mode 100644
index 339c533ada6..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/while.rs",
-          "summary": {
-            "functions": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "lines": {
-              "count": 5,
-              "covered": 4,
-              "percent": 80
-            },
-            "regions": {
-              "count": 4,
-              "covered": 3,
-              "notcovered": 1,
-              "percent": 75
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "lines": {
-          "count": 5,
-          "covered": 4,
-          "percent": 80
-        },
-        "regions": {
-          "count": 4,
-          "covered": 3,
-          "notcovered": 1,
-          "percent": 75
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while_early_ret.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while_early_ret.json
deleted file mode 100644
index b7fe2a0fb47..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.while_early_ret.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/while_early_ret.rs",
-          "summary": {
-            "functions": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 1,
-              "covered": 1,
-              "percent": 100
-            },
-            "lines": {
-              "count": 19,
-              "covered": 17,
-              "percent": 89.47368421052632
-            },
-            "regions": {
-              "count": 9,
-              "covered": 7,
-              "notcovered": 2,
-              "percent": 77.77777777777779
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 1,
-          "covered": 1,
-          "percent": 100
-        },
-        "lines": {
-          "count": 19,
-          "covered": 17,
-          "percent": 89.47368421052632
-        },
-        "regions": {
-          "count": 9,
-          "covered": 7,
-          "notcovered": 2,
-          "percent": 77.77777777777779
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.yield.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.yield.json
deleted file mode 100644
index 6fc41212bc0..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.yield.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "data": [
-    {
-      "files": [
-        {
-          "filename": "../coverage/yield.rs",
-          "summary": {
-            "functions": {
-              "count": 3,
-              "covered": 3,
-              "percent": 100
-            },
-            "instantiations": {
-              "count": 3,
-              "covered": 3,
-              "percent": 100
-            },
-            "lines": {
-              "count": 26,
-              "covered": 19,
-              "percent": 73.07692307692307
-            },
-            "regions": {
-              "count": 23,
-              "covered": 17,
-              "notcovered": 6,
-              "percent": 73.91304347826086
-            }
-          }
-        }
-      ],
-      "totals": {
-        "functions": {
-          "count": 3,
-          "covered": 3,
-          "percent": 100
-        },
-        "instantiations": {
-          "count": 3,
-          "covered": 3,
-          "percent": 100
-        },
-        "lines": {
-          "count": 26,
-          "covered": 19,
-          "percent": 73.07692307692307
-        },
-        "regions": {
-          "count": 23,
-          "covered": 17,
-          "notcovered": 6,
-          "percent": 73.91304347826086
-        }
-      }
-    }
-  ],
-  "type": "llvm.coverage.json.export",
-  "version": "2.0.1"
-}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt
index 355b53f7f3b..405688806ea 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt
@@ -9,13 +9,13 @@
     8|       |
     9|      1|fn main() -> Result<(),u8> {
    10|      1|    let mut countdown = 10;
-   11|     10|    while countdown > 0 {
-   12|     10|        if countdown == 1 {
-   13|      0|            might_fail_assert(3);
+   11|     11|    while countdown > 0 {
+   12|     11|        if countdown == 1 {
+   13|      1|            might_fail_assert(3);
    14|     10|        } else if countdown < 5 {
    15|      3|            might_fail_assert(2);
    16|      6|        }
-   17|      9|        countdown -= 1;
+   17|     10|        countdown -= 1;
    18|       |    }
    19|      0|    Ok(())
    20|      0|}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt
new file mode 100644
index 00000000000..e1731c7223c
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.doctest.txt
@@ -0,0 +1,79 @@
+../coverage/doctest.rs:
+    1|       |//! This test ensures that code from doctests is properly re-mapped.
+    2|       |//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
+    3|       |//!
+    4|       |//! Just some random code:
+    5|      1|//! ```
+    6|      1|//! if true {
+    7|       |//!     // this is executed!
+    8|      1|//!     assert_eq!(1, 1);
+    9|       |//! } else {
+   10|       |//!     // this is not!
+   11|       |//!     assert_eq!(1, 2);
+   12|       |//! }
+   13|      1|//! ```
+   14|       |//!
+   15|       |//! doctest testing external code:
+   16|       |//! ```
+   17|      1|//! extern crate doctest_crate;
+   18|      1|//! doctest_crate::fn_run_in_doctests(1);
+   19|      1|//! ```
+   20|       |//!
+   21|       |//! doctest returning a result:
+   22|      1|//! ```
+   23|      1|//! #[derive(Debug)]
+   24|      1|//! struct SomeError;
+   25|      1|//! let mut res = Err(SomeError);
+   26|      1|//! if res.is_ok() {
+   27|      0|//!   res?;
+   28|      1|//! } else {
+   29|      1|//!   res = Ok(0);
+   30|      1|//! }
+   31|       |//! // need to be explicit because rustdoc cant infer the return type
+   32|      1|//! Ok::<(), SomeError>(())
+   33|      1|//! ```
+   34|       |//!
+   35|       |//! doctest with custom main:
+   36|       |//! ```
+   37|       |//! #[derive(Debug)]
+   38|       |//! struct SomeError;
+   39|       |//!
+   40|       |//! extern crate doctest_crate;
+   41|       |//!
+   42|      1|//! fn doctest_main() -> Result<(), SomeError> {
+   43|      1|//!     doctest_crate::fn_run_in_doctests(2);
+   44|      1|//!     Ok(())
+   45|      1|//! }
+   46|       |//!
+   47|       |//! // this `main` is not shown as covered, as it clashes with all the other
+   48|       |//! // `main` functions that were automatically generated for doctests
+   49|       |//! fn main() -> Result<(), SomeError> {
+   50|       |//!     doctest_main()
+   51|       |//! }
+   52|       |//! ```
+   53|       |
+   54|       |/// doctest attached to fn testing external code:
+   55|       |/// ```
+   56|      1|/// extern crate doctest_crate;
+   57|      1|/// doctest_crate::fn_run_in_doctests(3);
+   58|      1|/// ```
+   59|       |///
+   60|      1|fn main() {
+   61|      1|    if true {
+   62|      1|        assert_eq!(1, 1);
+   63|       |    } else {
+   64|       |        assert_eq!(1, 2);
+   65|       |    }
+   66|      1|}
+
+../coverage/lib/doctest_crate.rs:
+    1|       |/// A function run only from within doctests
+    2|      3|pub fn fn_run_in_doctests(conditional: usize) {
+    3|      3|    match conditional {
+    4|      1|        1 => assert_eq!(1, 1), // this is run,
+    5|      1|        2 => assert_eq!(1, 1), // this,
+    6|      1|        3 => assert_eq!(1, 1), // and this too
+    7|      0|        _ => assert_eq!(1, 2), // however this is not
+    8|       |    }
+    9|      3|}
+
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt
new file mode 100644
index 00000000000..a0fccb24f99
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.match_or_pattern.txt
@@ -0,0 +1,50 @@
+    1|       |#![feature(or_patterns)]
+    2|       |
+    3|      1|fn main() {
+    4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    6|      1|    // dependent conditions.
+    7|      1|    let is_true = std::env::args().len() == 1;
+    8|      1|
+    9|      1|    let mut a: u8 = 0;
+   10|      1|    let mut b: u8 = 0;
+   11|      1|    if is_true {
+   12|      1|        a = 2;
+   13|      1|        b = 0;
+   14|      1|    }
+                   ^0
+   15|      1|    match (a, b) {
+   16|       |        // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`.
+   17|       |        // This test confirms a fix for Issue #79569.
+   18|      0|        (0 | 1, 2 | 3) => {}
+   19|      1|        _ => {}
+   20|       |    }
+   21|      1|    if is_true {
+   22|      1|        a = 0;
+   23|      1|        b = 0;
+   24|      1|    }
+                   ^0
+   25|      1|    match (a, b) {
+   26|      0|        (0 | 1, 2 | 3) => {}
+   27|      1|        _ => {}
+   28|       |    }
+   29|      1|    if is_true {
+   30|      1|        a = 2;
+   31|      1|        b = 2;
+   32|      1|    }
+                   ^0
+   33|      1|    match (a, b) {
+   34|      0|        (0 | 1, 2 | 3) => {}
+   35|      1|        _ => {}
+   36|       |    }
+   37|      1|    if is_true {
+   38|      1|        a = 0;
+   39|      1|        b = 2;
+   40|      1|    }
+                   ^0
+   41|      1|    match (a, b) {
+   42|      1|        (0 | 1, 2 | 3) => {}
+   43|      0|        _ => {}
+   44|       |    }
+   45|      1|}
+
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt
index 4dccb3413ea..25e822bffd1 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt
@@ -14,15 +14,15 @@
    14|       |
    15|      1|fn main() -> Result<(),u8> {
    16|      1|    let mut countdown = 10;
-   17|     10|    while countdown > 0 {
-   18|     10|        if countdown == 1 {
-   19|      0|            let result = might_overflow(10);
-   20|      0|            println!("Result: {}", result);
+   17|     11|    while countdown > 0 {
+   18|     11|        if countdown == 1 {
+   19|      1|            let result = might_overflow(10);
+   20|      1|            println!("Result: {}", result);
    21|     10|        } else if countdown < 5 {
    22|      3|            let result = might_overflow(1);
    23|      3|            println!("Result: {}", result);
    24|      6|        }
-   25|      9|        countdown -= 1;
+   25|     10|        countdown -= 1;
    26|       |    }
    27|      0|    Ok(())
    28|      0|}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt
index 9ae78fee4b5..c77ee5ddc20 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt
@@ -12,13 +12,13 @@
    12|       |
    13|      1|fn main() -> Result<(), u8> {
    14|      1|    let mut countdown = 10;
-   15|     10|    while countdown > 0 {
-   16|     10|        if countdown == 1 {
-   17|      0|            might_panic(true);
+   15|     11|    while countdown > 0 {
+   16|     11|        if countdown == 1 {
+   17|      1|            might_panic(true);
    18|     10|        } else if countdown < 5 {
    19|      3|            might_panic(false);
    20|      6|        }
-   21|      9|        countdown -= 1;
+   21|     10|        countdown -= 1;
    22|       |    }
    23|      0|    Ok(())
    24|      0|}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt
index e14e733fff6..4c03e950af0 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt
@@ -19,12 +19,12 @@
    18|      2|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
    19|      2|}
   ------------------
-  | used_crate::used_only_from_bin_crate_generic_function::<&str>:
+  | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
   |   17|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
   |   18|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
   |   19|      1|}
   ------------------
-  | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
+  | used_crate::used_only_from_bin_crate_generic_function::<&str>:
   |   17|      1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
   |   18|      1|    println!("used_only_from_bin_crate_generic_function with {:?}", arg);
   |   19|      1|}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.abort.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.abort.txt
deleted file mode 100644
index cbf7462eba5..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.abort.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-Counter in file 0 14:1 -> 15:27, #1
-Counter in file 0 16:11 -> 16:24, (#1 + (#2 + #3))
-Counter in file 0 17:12 -> 17:25, ((#1 + (#2 + #3)) - #4)
-Counter in file 0 17:26 -> 19:10, #5
-Counter in file 0 19:10 -> 19:11, (((#1 + (#2 + #3)) - #4) - #5)
-Counter in file 0 21:12 -> 21:25, (#5 + (((#1 + (#2 + #3)) - #4) - #5))
-Counter in file 0 21:26 -> 21:49, #6
-Counter in file 0 21:49 -> 21:50, ((#5 + (((#1 + (#2 + #3)) - #4) - #5)) - #6)
-Counter in file 0 25:12 -> 25:25, (#6 + ((#5 + (((#1 + (#2 + #3)) - #4) - #5)) - #6))
-Counter in file 0 25:26 -> 25:49, #2
-Counter in file 0 25:49 -> 25:50, #3
-Counter in file 0 26:9 -> 26:23, (#2 + #3)
-Counter in file 0 28:5 -> 29:2, #4
-Counter in file 0 5:1 -> 5:36, #1
-Counter in file 0 6:8 -> 6:20, (#1 + 0)
-Counter in file 0 7:9 -> 8:37, #2
-Counter in file 0 9:12 -> 12:2, (#1 - #2)
-Emitting segments for file: ../coverage/abort.rs
-Combined regions:
-  5:1 -> 5:36 (count=12)
-  6:8 -> 6:20 (count=12)
-  7:9 -> 8:37 (count=0)
-  9:12 -> 12:2 (count=12)
-  14:1 -> 15:27 (count=1)
-  16:11 -> 16:24 (count=11)
-  17:12 -> 17:25 (count=10)
-  17:26 -> 19:10 (count=4)
-  19:10 -> 19:11 (count=6)
-  21:12 -> 21:25 (count=10)
-  21:26 -> 21:49 (count=4)
-  21:49 -> 21:50 (count=6)
-  25:12 -> 25:25 (count=10)
-  25:26 -> 25:49 (count=4)
-  25:49 -> 25:50 (count=6)
-  26:9 -> 26:23 (count=10)
-  28:5 -> 29:2 (count=1)
-Segment at 5:1 (count = 12), RegionEntry
-Segment at 5:36 (count = 0), Skipped
-Segment at 6:8 (count = 12), RegionEntry
-Segment at 6:20 (count = 0), Skipped
-Segment at 7:9 (count = 0), RegionEntry
-Segment at 8:37 (count = 0), Skipped
-Segment at 9:12 (count = 12), RegionEntry
-Segment at 12:2 (count = 0), Skipped
-Segment at 14:1 (count = 1), RegionEntry
-Segment at 15:27 (count = 0), Skipped
-Segment at 16:11 (count = 11), RegionEntry
-Segment at 16:24 (count = 0), Skipped
-Segment at 17:12 (count = 10), RegionEntry
-Segment at 17:25 (count = 0), Skipped
-Segment at 17:26 (count = 4), RegionEntry
-Segment at 19:10 (count = 6), RegionEntry
-Segment at 19:11 (count = 0), Skipped
-Segment at 21:12 (count = 10), RegionEntry
-Segment at 21:25 (count = 0), Skipped
-Segment at 21:26 (count = 4), RegionEntry
-Segment at 21:49 (count = 6), RegionEntry
-Segment at 21:50 (count = 0), Skipped
-Segment at 25:12 (count = 10), RegionEntry
-Segment at 25:25 (count = 0), Skipped
-Segment at 25:26 (count = 4), RegionEntry
-Segment at 25:49 (count = 6), RegionEntry
-Segment at 25:50 (count = 0), Skipped
-Segment at 26:9 (count = 10), RegionEntry
-Segment at 26:23 (count = 0), Skipped
-Segment at 28:5 (count = 1), RegionEntry
-Segment at 29:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt
deleted file mode 100644
index 916ebbbcc29..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-Counter in file 0 9:1 -> 10:27, #1
-Counter in file 0 11:11 -> 11:24, (#1 + (#2 + (#3 + #4)))
-Counter in file 0 12:12 -> 12:26, ((#1 + (#2 + (#3 + #4))) - #5)
-Counter in file 0 12:27 -> 14:10, #2
-Counter in file 0 14:19 -> 14:32, (((#1 + (#2 + (#3 + #4))) - #5) - #2)
-Counter in file 0 14:33 -> 16:10, #3
-Counter in file 0 16:10 -> 16:11, #4
-Counter in file 0 17:9 -> 17:23, (#2 + (#3 + #4))
-Counter in file 0 19:5 -> 20:2, #5
-Counter in file 0 4:1 -> 4:41, #1
-Counter in file 0 5:5 -> 5:48, (#1 + 0)
-Counter in file 0 6:16 -> 6:21, (#1 + 0)
-Counter in file 0 6:37 -> 6:61, #2
-Counter in file 0 7:1 -> 7:2, (#1 - #2)
-Emitting segments for file: ../coverage/assert.rs
-Combined regions:
-  4:1 -> 4:41 (count=4)
-  5:5 -> 5:48 (count=4)
-  6:16 -> 6:21 (count=4)
-  6:37 -> 6:61 (count=1)
-  7:1 -> 7:2 (count=3)
-  9:1 -> 10:27 (count=1)
-  11:11 -> 11:24 (count=10)
-  12:12 -> 12:26 (count=10)
-  12:27 -> 14:10 (count=0)
-  14:19 -> 14:32 (count=10)
-  14:33 -> 16:10 (count=3)
-  16:10 -> 16:11 (count=6)
-  17:9 -> 17:23 (count=9)
-  19:5 -> 20:2 (count=0)
-Segment at 4:1 (count = 4), RegionEntry
-Segment at 4:41 (count = 0), Skipped
-Segment at 5:5 (count = 4), RegionEntry
-Segment at 5:48 (count = 0), Skipped
-Segment at 6:16 (count = 4), RegionEntry
-Segment at 6:21 (count = 0), Skipped
-Segment at 6:37 (count = 1), RegionEntry
-Segment at 6:61 (count = 0), Skipped
-Segment at 7:1 (count = 3), RegionEntry
-Segment at 7:2 (count = 0), Skipped
-Segment at 9:1 (count = 1), RegionEntry
-Segment at 10:27 (count = 0), Skipped
-Segment at 11:11 (count = 10), RegionEntry
-Segment at 11:24 (count = 0), Skipped
-Segment at 12:12 (count = 10), RegionEntry
-Segment at 12:26 (count = 0), Skipped
-Segment at 12:27 (count = 0), RegionEntry
-Segment at 14:10 (count = 0), Skipped
-Segment at 14:19 (count = 10), RegionEntry
-Segment at 14:32 (count = 0), Skipped
-Segment at 14:33 (count = 3), RegionEntry
-Segment at 16:10 (count = 6), RegionEntry
-Segment at 16:11 (count = 0), Skipped
-Segment at 17:9 (count = 9), RegionEntry
-Segment at 17:23 (count = 0), Skipped
-Segment at 19:5 (count = 0), RegionEntry
-Segment at 20:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt
deleted file mode 100644
index ed91e8898ee..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.async.txt
+++ /dev/null
@@ -1,311 +0,0 @@
-Counter in file 0 13:1 -> 13:20, #1
-Counter in file 0 15:1 -> 15:20, 0
-Counter in file 0 15:20 -> 15:21, 0
-Counter in file 0 19:1 -> 19:30, 0
-Counter in file 0 19:30 -> 19:31, 0
-Counter in file 0 21:23 -> 22:12, 0
-Counter in file 0 23:9 -> 23:10, 0
-Counter in file 0 23:14 -> 23:17, 0
-Counter in file 0 23:27 -> 23:28, 0
-Counter in file 0 23:32 -> 23:34, 0
-Counter in file 0 24:9 -> 24:10, 0
-Counter in file 0 24:14 -> 24:17, 0
-Counter in file 0 24:27 -> 24:28, 0
-Counter in file 0 24:32 -> 24:34, 0
-Counter in file 0 25:14 -> 25:16, 0
-Counter in file 0 27:1 -> 27:2, 0
-Counter in file 0 29:22 -> 32:12, 0
-Counter in file 0 33:9 -> 33:10, 0
-Counter in file 0 33:14 -> 33:19, 0
-Counter in file 0 33:26 -> 33:27, 0
-Counter in file 0 33:32 -> 33:34, 0
-Counter in file 0 34:14 -> 34:16, 0
-Counter in file 0 36:1 -> 36:2, 0
-Counter in file 0 75:1 -> 76:12, 0
-Counter in file 0 77:14 -> 77:16, 0
-Counter in file 0 78:14 -> 78:16, 0
-Counter in file 0 79:14 -> 79:16, 0
-Counter in file 0 81:1 -> 81:2, 0
-Counter in file 0 91:25 -> 91:34, 0
-Counter in file 0 5:1 -> 5:25, #1
-Counter in file 0 5:25 -> 6:14, #1
-Counter in file 0 7:9 -> 7:10, #2
-Counter in file 0 9:9 -> 9:10, (#1 - #2)
-Counter in file 0 11:1 -> 11:2, (#2 + (#1 - #2))
-Counter in file 0 21:1 -> 21:23, #1
-Counter in file 0 67:5 -> 67:23, #1
-Counter in file 0 38:1 -> 38:19, #1
-Counter in file 0 38:19 -> 42:12, #1
-Counter in file 0 43:9 -> 43:10, #3
-Counter in file 0 43:14 -> 43:18, (#1 + 0)
-Counter in file 0 43:28 -> 43:33, #2
-Counter in file 0 43:39 -> 43:42, (#3 + 0)
-Counter in file 0 44:9 -> 44:10, #6
-Counter in file 0 44:14 -> 44:17, #4
-Counter in file 0 44:27 -> 44:32, #8
-Counter in file 0 44:36 -> 44:38, (#6 + 0)
-Counter in file 0 45:14 -> 45:16, #7
-Counter in file 0 47:1 -> 47:2, (#5 + (#6 + #7))
-Counter in file 0 29:1 -> 29:22, #1
-Counter in file 0 93:1 -> 101:2, #1
-Counter in file 0 91:1 -> 91:25, #1
-Counter in file 0 51:5 -> 52:18, #1
-Counter in file 0 53:13 -> 53:14, #2
-Counter in file 0 63:13 -> 63:14, (#1 - #2)
-Counter in file 0 65:5 -> 65:6, (#2 + (#1 - #2))
-Counter in file 0 17:20 -> 17:21, #1
-Counter in file 0 49:1 -> 68:12, #1
-Counter in file 0 69:9 -> 69:10, #2
-Counter in file 0 69:14 -> 69:27, (#1 + 0)
-Counter in file 0 69:31 -> 69:39, (#2 + 0)
-Counter in file 0 70:9 -> 70:10, #3
-Counter in file 0 70:14 -> 70:26, #5
-Counter in file 0 70:30 -> 70:32, (#3 + 0)
-Counter in file 0 71:14 -> 71:16, #4
-Counter in file 0 73:1 -> 73:2, (#2 + (#3 + #4))
-Counter in file 0 83:1 -> 84:12, #1
-Counter in file 0 85:14 -> 85:16, (#1 - (#3 + #2))
-Counter in file 0 86:14 -> 86:16, #2
-Counter in file 0 87:14 -> 87:16, #3
-Counter in file 0 89:1 -> 89:2, (#3 + (#2 + (#1 - (#3 + #2))))
-Counter in file 0 17:1 -> 17:20, #1
-Counter in file 0 66:5 -> 66:23, #1
-Counter in file 0 13:20 -> 13:21, #1
-Counter in file 0 17:9 -> 17:10, #1
-Counter in file 0 17:9 -> 17:10, #1
-Counter in file 0 117:17 -> 117:19, #1
-Counter in file 0 17:9 -> 17:10, #1
-Counter in file 0 110:5 -> 120:54, #1
-Counter in file 0 123:32 -> 123:35, ((#1 + #2) - #2)
-Counter in file 0 123:39 -> 123:73, (#1 + #2)
-Counter in file 0 124:23 -> 124:26, (((#1 + #2) - #2) + 0)
-Counter in file 0 125:14 -> 125:15, #2
-Counter in file 0 127:5 -> 127:6, (((#1 + #2) - #2) + 0)
-Emitting segments for file: ../coverage/async.rs
-Combined regions:
-  5:1 -> 5:25 (count=1)
-  5:25 -> 6:14 (count=1)
-  7:9 -> 7:10 (count=1)
-  9:9 -> 9:10 (count=0)
-  11:1 -> 11:2 (count=1)
-  13:1 -> 13:20 (count=0)
-  15:1 -> 15:20 (count=0)
-  15:20 -> 15:21 (count=0)
-  17:1 -> 17:20 (count=1)
-  17:20 -> 17:21 (count=1)
-  19:1 -> 19:30 (count=0)
-  19:30 -> 19:31 (count=0)
-  21:1 -> 21:23 (count=1)
-  21:23 -> 22:12 (count=0)
-  23:9 -> 23:10 (count=0)
-  23:14 -> 23:17 (count=0)
-  23:27 -> 23:28 (count=0)
-  23:32 -> 23:34 (count=0)
-  24:9 -> 24:10 (count=0)
-  24:14 -> 24:17 (count=0)
-  24:27 -> 24:28 (count=0)
-  24:32 -> 24:34 (count=0)
-  25:14 -> 25:16 (count=0)
-  27:1 -> 27:2 (count=0)
-  29:1 -> 29:22 (count=1)
-  29:22 -> 32:12 (count=0)
-  33:9 -> 33:10 (count=0)
-  33:14 -> 33:19 (count=0)
-  33:26 -> 33:27 (count=0)
-  33:32 -> 33:34 (count=0)
-  34:14 -> 34:16 (count=0)
-  36:1 -> 36:2 (count=0)
-  38:1 -> 38:19 (count=1)
-  38:19 -> 42:12 (count=1)
-  43:9 -> 43:10 (count=0)
-  43:14 -> 43:18 (count=1)
-  43:28 -> 43:33 (count=1)
-  43:39 -> 43:42 (count=0)
-  44:9 -> 44:10 (count=0)
-  44:14 -> 44:17 (count=1)
-  44:27 -> 44:32 (count=1)
-  44:36 -> 44:38 (count=0)
-  45:14 -> 45:16 (count=1)
-  47:1 -> 47:2 (count=1)
-  49:1 -> 68:12 (count=1)
-  51:5 -> 52:18 (count=1)
-  53:13 -> 53:14 (count=0)
-  63:13 -> 63:14 (count=1)
-  65:5 -> 65:6 (count=1)
-  67:5 -> 67:23 (count=1)
-  69:9 -> 69:10 (count=0)
-  69:14 -> 69:27 (count=1)
-  69:31 -> 69:39 (count=0)
-  70:9 -> 70:10 (count=0)
-  70:14 -> 70:26 (count=1)
-  70:30 -> 70:32 (count=0)
-  71:14 -> 71:16 (count=1)
-  73:1 -> 73:2 (count=1)
-  75:1 -> 76:12 (count=0)
-  77:14 -> 77:16 (count=0)
-  78:14 -> 78:16 (count=0)
-  79:14 -> 79:16 (count=0)
-  81:1 -> 81:2 (count=0)
-  83:1 -> 84:12 (count=1)
-  85:14 -> 85:16 (count=0)
-  86:14 -> 86:16 (count=0)
-  87:14 -> 87:16 (count=1)
-  89:1 -> 89:2 (count=1)
-  91:1 -> 91:25 (count=1)
-  91:25 -> 91:34 (count=0)
-  93:1 -> 101:2 (count=1)
-  110:5 -> 120:54 (count=1)
-  117:17 -> 117:19 (count=1)
-  123:32 -> 123:35 (count=1)
-  123:39 -> 123:73 (count=1)
-  124:23 -> 124:26 (count=1)
-  125:14 -> 125:15 (count=0)
-  127:5 -> 127:6 (count=1)
-Segment at 5:1 (count = 1), RegionEntry
-Segment at 5:25 (count = 1), RegionEntry
-Segment at 6:14 (count = 0), Skipped
-Segment at 7:9 (count = 1), RegionEntry
-Segment at 7:10 (count = 0), Skipped
-Segment at 9:9 (count = 0), RegionEntry
-Segment at 9:10 (count = 0), Skipped
-Segment at 11:1 (count = 1), RegionEntry
-Segment at 11:2 (count = 0), Skipped
-Segment at 13:1 (count = 0), RegionEntry
-Segment at 13:20 (count = 0), Skipped
-Segment at 15:1 (count = 0), RegionEntry
-Segment at 15:20 (count = 0), RegionEntry
-Segment at 15:21 (count = 0), Skipped
-Segment at 17:1 (count = 1), RegionEntry
-Segment at 17:20 (count = 1), RegionEntry
-Segment at 17:21 (count = 0), Skipped
-Segment at 19:1 (count = 0), RegionEntry
-Segment at 19:30 (count = 0), RegionEntry
-Segment at 19:31 (count = 0), Skipped
-Segment at 21:1 (count = 1), RegionEntry
-Segment at 21:23 (count = 0), RegionEntry
-Segment at 22:12 (count = 0), Skipped
-Segment at 23:9 (count = 0), RegionEntry
-Segment at 23:10 (count = 0), Skipped
-Segment at 23:14 (count = 0), RegionEntry
-Segment at 23:17 (count = 0), Skipped
-Segment at 23:27 (count = 0), RegionEntry
-Segment at 23:28 (count = 0), Skipped
-Segment at 23:32 (count = 0), RegionEntry
-Segment at 23:34 (count = 0), Skipped
-Segment at 24:9 (count = 0), RegionEntry
-Segment at 24:10 (count = 0), Skipped
-Segment at 24:14 (count = 0), RegionEntry
-Segment at 24:17 (count = 0), Skipped
-Segment at 24:27 (count = 0), RegionEntry
-Segment at 24:28 (count = 0), Skipped
-Segment at 24:32 (count = 0), RegionEntry
-Segment at 24:34 (count = 0), Skipped
-Segment at 25:14 (count = 0), RegionEntry
-Segment at 25:16 (count = 0), Skipped
-Segment at 27:1 (count = 0), RegionEntry
-Segment at 27:2 (count = 0), Skipped
-Segment at 29:1 (count = 1), RegionEntry
-Segment at 29:22 (count = 0), RegionEntry
-Segment at 32:12 (count = 0), Skipped
-Segment at 33:9 (count = 0), RegionEntry
-Segment at 33:10 (count = 0), Skipped
-Segment at 33:14 (count = 0), RegionEntry
-Segment at 33:19 (count = 0), Skipped
-Segment at 33:26 (count = 0), RegionEntry
-Segment at 33:27 (count = 0), Skipped
-Segment at 33:32 (count = 0), RegionEntry
-Segment at 33:34 (count = 0), Skipped
-Segment at 34:14 (count = 0), RegionEntry
-Segment at 34:16 (count = 0), Skipped
-Segment at 36:1 (count = 0), RegionEntry
-Segment at 36:2 (count = 0), Skipped
-Segment at 38:1 (count = 1), RegionEntry
-Segment at 38:19 (count = 1), RegionEntry
-Segment at 42:12 (count = 0), Skipped
-Segment at 43:9 (count = 0), RegionEntry
-Segment at 43:10 (count = 0), Skipped
-Segment at 43:14 (count = 1), RegionEntry
-Segment at 43:18 (count = 0), Skipped
-Segment at 43:28 (count = 1), RegionEntry
-Segment at 43:33 (count = 0), Skipped
-Segment at 43:39 (count = 0), RegionEntry
-Segment at 43:42 (count = 0), Skipped
-Segment at 44:9 (count = 0), RegionEntry
-Segment at 44:10 (count = 0), Skipped
-Segment at 44:14 (count = 1), RegionEntry
-Segment at 44:17 (count = 0), Skipped
-Segment at 44:27 (count = 1), RegionEntry
-Segment at 44:32 (count = 0), Skipped
-Segment at 44:36 (count = 0), RegionEntry
-Segment at 44:38 (count = 0), Skipped
-Segment at 45:14 (count = 1), RegionEntry
-Segment at 45:16 (count = 0), Skipped
-Segment at 47:1 (count = 1), RegionEntry
-Segment at 47:2 (count = 0), Skipped
-Segment at 49:1 (count = 1), RegionEntry
-Segment at 51:5 (count = 1), RegionEntry
-Segment at 52:18 (count = 1)
-Segment at 53:13 (count = 0), RegionEntry
-Segment at 53:14 (count = 1)
-Segment at 63:13 (count = 1), RegionEntry
-Segment at 63:14 (count = 1)
-Segment at 65:5 (count = 1), RegionEntry
-Segment at 65:6 (count = 1)
-Segment at 67:5 (count = 1), RegionEntry
-Segment at 67:23 (count = 1)
-Segment at 68:12 (count = 0), Skipped
-Segment at 69:9 (count = 0), RegionEntry
-Segment at 69:10 (count = 0), Skipped
-Segment at 69:14 (count = 1), RegionEntry
-Segment at 69:27 (count = 0), Skipped
-Segment at 69:31 (count = 0), RegionEntry
-Segment at 69:39 (count = 0), Skipped
-Segment at 70:9 (count = 0), RegionEntry
-Segment at 70:10 (count = 0), Skipped
-Segment at 70:14 (count = 1), RegionEntry
-Segment at 70:26 (count = 0), Skipped
-Segment at 70:30 (count = 0), RegionEntry
-Segment at 70:32 (count = 0), Skipped
-Segment at 71:14 (count = 1), RegionEntry
-Segment at 71:16 (count = 0), Skipped
-Segment at 73:1 (count = 1), RegionEntry
-Segment at 73:2 (count = 0), Skipped
-Segment at 75:1 (count = 0), RegionEntry
-Segment at 76:12 (count = 0), Skipped
-Segment at 77:14 (count = 0), RegionEntry
-Segment at 77:16 (count = 0), Skipped
-Segment at 78:14 (count = 0), RegionEntry
-Segment at 78:16 (count = 0), Skipped
-Segment at 79:14 (count = 0), RegionEntry
-Segment at 79:16 (count = 0), Skipped
-Segment at 81:1 (count = 0), RegionEntry
-Segment at 81:2 (count = 0), Skipped
-Segment at 83:1 (count = 1), RegionEntry
-Segment at 84:12 (count = 0), Skipped
-Segment at 85:14 (count = 0), RegionEntry
-Segment at 85:16 (count = 0), Skipped
-Segment at 86:14 (count = 0), RegionEntry
-Segment at 86:16 (count = 0), Skipped
-Segment at 87:14 (count = 1), RegionEntry
-Segment at 87:16 (count = 0), Skipped
-Segment at 89:1 (count = 1), RegionEntry
-Segment at 89:2 (count = 0), Skipped
-Segment at 91:1 (count = 1), RegionEntry
-Segment at 91:25 (count = 0), RegionEntry
-Segment at 91:34 (count = 0), Skipped
-Segment at 93:1 (count = 1), RegionEntry
-Segment at 101:2 (count = 0), Skipped
-Segment at 110:5 (count = 1), RegionEntry
-Segment at 117:17 (count = 1), RegionEntry
-Segment at 117:19 (count = 1)
-Segment at 120:54 (count = 0), Skipped
-Segment at 123:32 (count = 1), RegionEntry
-Segment at 123:35 (count = 0), Skipped
-Segment at 123:39 (count = 1), RegionEntry
-Segment at 123:73 (count = 0), Skipped
-Segment at 124:23 (count = 1), RegionEntry
-Segment at 124:26 (count = 0), Skipped
-Segment at 125:14 (count = 0), RegionEntry
-Segment at 125:15 (count = 0), Skipped
-Segment at 127:5 (count = 1), RegionEntry
-Segment at 127:6 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.closure.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.closure.txt
deleted file mode 100644
index 1aacac0ed25..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.closure.txt
+++ /dev/null
@@ -1,153 +0,0 @@
-Counter in file 0 98:5 -> 100:20, #1
-Counter in file 0 100:21 -> 102:10, #2
-Counter in file 0 102:10 -> 102:11, (#1 - #2)
-Counter in file 0 103:9 -> 104:6, (#2 + (#1 - #2))
-Counter in file 0 123:5 -> 124:20, 0
-Counter in file 0 124:21 -> 126:10, 0
-Counter in file 0 126:10 -> 126:11, 0
-Counter in file 0 127:9 -> 128:6, 0
-Counter in file 0 131:53 -> 131:67, 0
-Counter in file 0 141:59 -> 141:85, 0
-Counter in file 0 143:56 -> 145:6, 0
-Counter in file 0 149:7 -> 149:33, 0
-Counter in file 0 153:7 -> 153:33, 0
-Counter in file 0 3:1 -> 18:13, #1
-Counter in file 0 25:14 -> 33:9, (#1 + 0)
-Counter in file 0 40:6 -> 60:13, (#1 + 0)
-Counter in file 0 67:14 -> 75:9, (#1 + 0)
-Counter in file 0 82:6 -> 97:9, (#1 + 0)
-Counter in file 0 104:6 -> 120:9, (#1 + 0)
-Counter in file 0 128:6 -> 131:33, (#1 + 0)
-Counter in file 0 131:67 -> 136:33, (#1 + 0)
-Counter in file 0 136:75 -> 141:39, (#1 + 0)
-Counter in file 0 141:85 -> 143:36, (#1 + 0)
-Counter in file 0 145:6 -> 147:36, (#1 + 0)
-Counter in file 0 149:33 -> 151:43, (#1 + 0)
-Counter in file 0 153:33 -> 155:2, (#1 + 0)
-Counter in file 0 61:13 -> 63:28, #1
-Counter in file 0 63:29 -> 65:18, #2
-Counter in file 0 65:18 -> 65:19, (#1 - #2)
-Counter in file 0 66:17 -> 67:14, (#2 + (#1 - #2))
-Counter in file 0 76:5 -> 78:20, #1
-Counter in file 0 78:21 -> 80:10, #2
-Counter in file 0 80:10 -> 80:11, (#1 - #2)
-Counter in file 0 81:9 -> 82:6, (#2 + (#1 - #2))
-Counter in file 0 34:5 -> 36:20, #1
-Counter in file 0 36:21 -> 38:10, #2
-Counter in file 0 38:10 -> 38:11, (#1 - #2)
-Counter in file 0 39:9 -> 40:6, (#2 + (#1 - #2))
-Counter in file 0 19:13 -> 21:28, #1
-Counter in file 0 21:29 -> 23:18, #2
-Counter in file 0 23:18 -> 23:19, (#1 - #2)
-Counter in file 0 24:17 -> 25:14, (#2 + (#1 - #2))
-Emitting segments for file: ../coverage/closure.rs
-Combined regions:
-  3:1 -> 18:13 (count=1)
-  19:13 -> 21:28 (count=0)
-  21:29 -> 23:18 (count=0)
-  23:18 -> 23:19 (count=0)
-  24:17 -> 25:14 (count=0)
-  25:14 -> 33:9 (count=1)
-  34:5 -> 36:20 (count=0)
-  36:21 -> 38:10 (count=0)
-  38:10 -> 38:11 (count=0)
-  39:9 -> 40:6 (count=0)
-  40:6 -> 60:13 (count=1)
-  61:13 -> 63:28 (count=1)
-  63:29 -> 65:18 (count=0)
-  65:18 -> 65:19 (count=1)
-  66:17 -> 67:14 (count=1)
-  67:14 -> 75:9 (count=1)
-  76:5 -> 78:20 (count=1)
-  78:21 -> 80:10 (count=0)
-  80:10 -> 80:11 (count=1)
-  81:9 -> 82:6 (count=1)
-  82:6 -> 97:9 (count=1)
-  98:5 -> 100:20 (count=5)
-  100:21 -> 102:10 (count=0)
-  102:10 -> 102:11 (count=5)
-  103:9 -> 104:6 (count=5)
-  104:6 -> 120:9 (count=1)
-  123:5 -> 124:20 (count=0)
-  124:21 -> 126:10 (count=0)
-  126:10 -> 126:11 (count=0)
-  127:9 -> 128:6 (count=0)
-  128:6 -> 131:33 (count=1)
-  131:53 -> 131:67 (count=0)
-  131:67 -> 136:33 (count=1)
-  136:75 -> 141:39 (count=1)
-  141:59 -> 141:85 (count=0)
-  141:85 -> 143:36 (count=1)
-  143:56 -> 145:6 (count=0)
-  145:6 -> 147:36 (count=1)
-  149:7 -> 149:33 (count=0)
-  149:33 -> 151:43 (count=1)
-  153:7 -> 153:33 (count=0)
-  153:33 -> 155:2 (count=1)
-Segment at 3:1 (count = 1), RegionEntry
-Segment at 18:13 (count = 0), Skipped
-Segment at 19:13 (count = 0), RegionEntry
-Segment at 21:28 (count = 0), Skipped
-Segment at 21:29 (count = 0), RegionEntry
-Segment at 23:18 (count = 0), RegionEntry
-Segment at 23:19 (count = 0), Skipped
-Segment at 24:17 (count = 0), RegionEntry
-Segment at 25:14 (count = 1), RegionEntry
-Segment at 33:9 (count = 0), Skipped
-Segment at 34:5 (count = 0), RegionEntry
-Segment at 36:20 (count = 0), Skipped
-Segment at 36:21 (count = 0), RegionEntry
-Segment at 38:10 (count = 0), RegionEntry
-Segment at 38:11 (count = 0), Skipped
-Segment at 39:9 (count = 0), RegionEntry
-Segment at 40:6 (count = 1), RegionEntry
-Segment at 60:13 (count = 0), Skipped
-Segment at 61:13 (count = 1), RegionEntry
-Segment at 63:28 (count = 0), Skipped
-Segment at 63:29 (count = 0), RegionEntry
-Segment at 65:18 (count = 1), RegionEntry
-Segment at 65:19 (count = 0), Skipped
-Segment at 66:17 (count = 1), RegionEntry
-Segment at 67:14 (count = 1), RegionEntry
-Segment at 75:9 (count = 0), Skipped
-Segment at 76:5 (count = 1), RegionEntry
-Segment at 78:20 (count = 0), Skipped
-Segment at 78:21 (count = 0), RegionEntry
-Segment at 80:10 (count = 1), RegionEntry
-Segment at 80:11 (count = 0), Skipped
-Segment at 81:9 (count = 1), RegionEntry
-Segment at 82:6 (count = 1), RegionEntry
-Segment at 97:9 (count = 0), Skipped
-Segment at 98:5 (count = 5), RegionEntry
-Segment at 100:20 (count = 0), Skipped
-Segment at 100:21 (count = 0), RegionEntry
-Segment at 102:10 (count = 5), RegionEntry
-Segment at 102:11 (count = 0), Skipped
-Segment at 103:9 (count = 5), RegionEntry
-Segment at 104:6 (count = 1), RegionEntry
-Segment at 120:9 (count = 0), Skipped
-Segment at 123:5 (count = 0), RegionEntry
-Segment at 124:20 (count = 0), Skipped
-Segment at 124:21 (count = 0), RegionEntry
-Segment at 126:10 (count = 0), RegionEntry
-Segment at 126:11 (count = 0), Skipped
-Segment at 127:9 (count = 0), RegionEntry
-Segment at 128:6 (count = 1), RegionEntry
-Segment at 131:33 (count = 0), Skipped
-Segment at 131:53 (count = 0), RegionEntry
-Segment at 131:67 (count = 1), RegionEntry
-Segment at 136:33 (count = 0), Skipped
-Segment at 136:75 (count = 1), RegionEntry
-Segment at 141:39 (count = 0), Skipped
-Segment at 141:59 (count = 0), RegionEntry
-Segment at 141:85 (count = 1), RegionEntry
-Segment at 143:36 (count = 0), Skipped
-Segment at 143:56 (count = 0), RegionEntry
-Segment at 145:6 (count = 1), RegionEntry
-Segment at 147:36 (count = 0), Skipped
-Segment at 149:7 (count = 0), RegionEntry
-Segment at 149:33 (count = 1), RegionEntry
-Segment at 151:43 (count = 0), Skipped
-Segment at 153:7 (count = 0), RegionEntry
-Segment at 153:33 (count = 1), RegionEntry
-Segment at 155:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.conditions.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.conditions.txt
deleted file mode 100644
index 3a9c6a9b92e..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.conditions.txt
+++ /dev/null
@@ -1,253 +0,0 @@
-Counter in file 0 3:1 -> 3:11, #1
-Counter in file 0 4:9 -> 5:12, (#1 + 0)
-Counter in file 0 5:13 -> 7:6, #2
-Counter in file 0 10:9 -> 10:10, (#3 + (#12 + #13))
-Counter in file 0 10:16 -> 10:29, (#2 + 0)
-Counter in file 0 11:9 -> 12:10, #3
-Counter in file 0 13:15 -> 13:28, ((#2 + 0) - #3)
-Counter in file 0 14:12 -> 14:25, #4
-Counter in file 0 14:29 -> 14:42, (#4 - #15)
-Counter in file 0 14:46 -> 14:60, #21
-Counter in file 0 14:61 -> 16:10, #12
-Counter in file 0 16:10 -> 16:11, #13
-Counter in file 0 17:9 -> 18:18, (#12 + #13)
-Counter in file 0 20:9 -> 20:15, (((#2 + 0) - #3) - #4)
-Counter in file 0 23:9 -> 24:12, ((#3 + (#12 + #13)) + 0)
-Counter in file 0 24:13 -> 26:6, #14
-Counter in file 0 28:8 -> 28:21, (#14 + 0)
-Counter in file 0 28:22 -> 30:6, #16
-Counter in file 0 30:15 -> 30:28, ((#14 + 0) - #16)
-Counter in file 0 31:12 -> 31:25, (((#14 + 0) - #16) - #11)
-Counter in file 0 31:29 -> 31:42, ((((#14 + 0) - #16) - #11) - #23)
-Counter in file 0 31:46 -> 31:60, #31
-Counter in file 0 31:61 -> 33:10, #18
-Counter in file 0 33:10 -> 33:11, #19
-Counter in file 0 34:9 -> 34:23, (#18 + #19)
-Counter in file 0 36:9 -> 36:15, #11
-Counter in file 0 39:8 -> 39:12, (#16 + (#18 + #19))
-Counter in file 0 40:13 -> 41:16, #20
-Counter in file 0 41:17 -> 43:10, #24
-Counter in file 0 45:12 -> 45:25, (#24 + 0)
-Counter in file 0 45:26 -> 47:10, #25
-Counter in file 0 48:17 -> 48:30, ((#24 + 0) - #25)
-Counter in file 0 49:16 -> 49:29, (((#24 + 0) - #25) - #10)
-Counter in file 0 49:33 -> 49:46, ((((#24 + 0) - #25) - #10) - #35)
-Counter in file 0 49:50 -> 49:64, #40
-Counter in file 0 49:65 -> 51:14, #26
-Counter in file 0 51:14 -> 51:15, #27
-Counter in file 0 52:13 -> 52:27, (#26 + #27)
-Counter in file 0 54:13 -> 54:19, #10
-Counter in file 0 59:9 -> 60:12, ((#25 + (#26 + #27)) + 0)
-Counter in file 0 60:13 -> 62:6, #28
-Counter in file 0 64:9 -> 64:10, (#30 + (#33 + #34))
-Counter in file 0 64:16 -> 64:29, (#28 + 0)
-Counter in file 0 64:30 -> 66:6, #30
-Counter in file 0 66:15 -> 66:28, ((#28 + 0) - #30)
-Counter in file 0 67:12 -> 67:25, (((#28 + 0) - #30) - #9)
-Counter in file 0 67:29 -> 67:42, ((((#28 + 0) - #30) - #9) - #36)
-Counter in file 0 67:46 -> 67:60, #42
-Counter in file 0 67:61 -> 69:10, #33
-Counter in file 0 69:10 -> 69:11, #34
-Counter in file 0 70:9 -> 70:23, (#33 + #34)
-Counter in file 0 72:13 -> 74:15, #9
-Counter in file 0 77:9 -> 77:10, (#5 + (#6 + #7))
-Counter in file 0 77:16 -> 77:29, ((#30 + (#33 + #34)) + 0)
-Counter in file 0 77:30 -> 79:6, #5
-Counter in file 0 79:15 -> 79:28, ((#30 + (#33 + #34)) - #5)
-Counter in file 0 80:12 -> 80:25, (((#30 + (#33 + #34)) - #5) - #8)
-Counter in file 0 80:29 -> 80:42, ((((#30 + (#33 + #34)) - #5) - #8) - #39)
-Counter in file 0 80:46 -> 80:60, #45
-Counter in file 0 80:61 -> 82:10, #6
-Counter in file 0 82:10 -> 82:11, #7
-Counter in file 0 83:9 -> 83:23, (#6 + #7)
-Counter in file 0 85:9 -> 85:15, #8
-Counter in file 0 87:1 -> 87:2, ((#5 + (#6 + #7)) + (((#8 + #9) + (#10 + #11)) + (((#2 + 0) - #3) - #4)))
-Emitting segments for file: ../coverage/conditions.rs
-Combined regions:
-  3:1 -> 3:11 (count=1)
-  4:9 -> 5:12 (count=1)
-  5:13 -> 7:6 (count=1)
-  10:9 -> 10:10 (count=1)
-  10:16 -> 10:29 (count=1)
-  11:9 -> 12:10 (count=1)
-  13:15 -> 13:28 (count=0)
-  14:12 -> 14:25 (count=0)
-  14:29 -> 14:42 (count=0)
-  14:46 -> 14:60 (count=0)
-  14:61 -> 16:10 (count=0)
-  16:10 -> 16:11 (count=0)
-  17:9 -> 18:18 (count=0)
-  20:9 -> 20:15 (count=0)
-  23:9 -> 24:12 (count=1)
-  24:13 -> 26:6 (count=1)
-  28:8 -> 28:21 (count=1)
-  28:22 -> 30:6 (count=1)
-  30:15 -> 30:28 (count=0)
-  31:12 -> 31:25 (count=0)
-  31:29 -> 31:42 (count=0)
-  31:46 -> 31:60 (count=0)
-  31:61 -> 33:10 (count=0)
-  33:10 -> 33:11 (count=0)
-  34:9 -> 34:23 (count=0)
-  36:9 -> 36:15 (count=0)
-  39:8 -> 39:12 (count=1)
-  40:13 -> 41:16 (count=1)
-  41:17 -> 43:10 (count=1)
-  45:12 -> 45:25 (count=1)
-  45:26 -> 47:10 (count=1)
-  48:17 -> 48:30 (count=0)
-  49:16 -> 49:29 (count=0)
-  49:33 -> 49:46 (count=0)
-  49:50 -> 49:64 (count=0)
-  49:65 -> 51:14 (count=0)
-  51:14 -> 51:15 (count=0)
-  52:13 -> 52:27 (count=0)
-  54:13 -> 54:19 (count=0)
-  59:9 -> 60:12 (count=1)
-  60:13 -> 62:6 (count=1)
-  64:9 -> 64:10 (count=0)
-  64:16 -> 64:29 (count=1)
-  64:30 -> 66:6 (count=0)
-  66:15 -> 66:28 (count=1)
-  67:12 -> 67:25 (count=0)
-  67:29 -> 67:42 (count=0)
-  67:46 -> 67:60 (count=0)
-  67:61 -> 69:10 (count=0)
-  69:10 -> 69:11 (count=0)
-  70:9 -> 70:23 (count=0)
-  72:13 -> 74:15 (count=1)
-  77:9 -> 77:10 (count=0)
-  77:16 -> 77:29 (count=0)
-  77:30 -> 79:6 (count=0)
-  79:15 -> 79:28 (count=0)
-  80:12 -> 80:25 (count=0)
-  80:29 -> 80:42 (count=0)
-  80:46 -> 80:60 (count=0)
-  80:61 -> 82:10 (count=0)
-  82:10 -> 82:11 (count=0)
-  83:9 -> 83:23 (count=0)
-  85:9 -> 85:15 (count=0)
-  87:1 -> 87:2 (count=1)
-Segment at 3:1 (count = 1), RegionEntry
-Segment at 3:11 (count = 0), Skipped
-Segment at 4:9 (count = 1), RegionEntry
-Segment at 5:12 (count = 0), Skipped
-Segment at 5:13 (count = 1), RegionEntry
-Segment at 7:6 (count = 0), Skipped
-Segment at 10:9 (count = 1), RegionEntry
-Segment at 10:10 (count = 0), Skipped
-Segment at 10:16 (count = 1), RegionEntry
-Segment at 10:29 (count = 0), Skipped
-Segment at 11:9 (count = 1), RegionEntry
-Segment at 12:10 (count = 0), Skipped
-Segment at 13:15 (count = 0), RegionEntry
-Segment at 13:28 (count = 0), Skipped
-Segment at 14:12 (count = 0), RegionEntry
-Segment at 14:25 (count = 0), Skipped
-Segment at 14:29 (count = 0), RegionEntry
-Segment at 14:42 (count = 0), Skipped
-Segment at 14:46 (count = 0), RegionEntry
-Segment at 14:60 (count = 0), Skipped
-Segment at 14:61 (count = 0), RegionEntry
-Segment at 16:10 (count = 0), RegionEntry
-Segment at 16:11 (count = 0), Skipped
-Segment at 17:9 (count = 0), RegionEntry
-Segment at 18:18 (count = 0), Skipped
-Segment at 20:9 (count = 0), RegionEntry
-Segment at 20:15 (count = 0), Skipped
-Segment at 23:9 (count = 1), RegionEntry
-Segment at 24:12 (count = 0), Skipped
-Segment at 24:13 (count = 1), RegionEntry
-Segment at 26:6 (count = 0), Skipped
-Segment at 28:8 (count = 1), RegionEntry
-Segment at 28:21 (count = 0), Skipped
-Segment at 28:22 (count = 1), RegionEntry
-Segment at 30:6 (count = 0), Skipped
-Segment at 30:15 (count = 0), RegionEntry
-Segment at 30:28 (count = 0), Skipped
-Segment at 31:12 (count = 0), RegionEntry
-Segment at 31:25 (count = 0), Skipped
-Segment at 31:29 (count = 0), RegionEntry
-Segment at 31:42 (count = 0), Skipped
-Segment at 31:46 (count = 0), RegionEntry
-Segment at 31:60 (count = 0), Skipped
-Segment at 31:61 (count = 0), RegionEntry
-Segment at 33:10 (count = 0), RegionEntry
-Segment at 33:11 (count = 0), Skipped
-Segment at 34:9 (count = 0), RegionEntry
-Segment at 34:23 (count = 0), Skipped
-Segment at 36:9 (count = 0), RegionEntry
-Segment at 36:15 (count = 0), Skipped
-Segment at 39:8 (count = 1), RegionEntry
-Segment at 39:12 (count = 0), Skipped
-Segment at 40:13 (count = 1), RegionEntry
-Segment at 41:16 (count = 0), Skipped
-Segment at 41:17 (count = 1), RegionEntry
-Segment at 43:10 (count = 0), Skipped
-Segment at 45:12 (count = 1), RegionEntry
-Segment at 45:25 (count = 0), Skipped
-Segment at 45:26 (count = 1), RegionEntry
-Segment at 47:10 (count = 0), Skipped
-Segment at 48:17 (count = 0), RegionEntry
-Segment at 48:30 (count = 0), Skipped
-Segment at 49:16 (count = 0), RegionEntry
-Segment at 49:29 (count = 0), Skipped
-Segment at 49:33 (count = 0), RegionEntry
-Segment at 49:46 (count = 0), Skipped
-Segment at 49:50 (count = 0), RegionEntry
-Segment at 49:64 (count = 0), Skipped
-Segment at 49:65 (count = 0), RegionEntry
-Segment at 51:14 (count = 0), RegionEntry
-Segment at 51:15 (count = 0), Skipped
-Segment at 52:13 (count = 0), RegionEntry
-Segment at 52:27 (count = 0), Skipped
-Segment at 54:13 (count = 0), RegionEntry
-Segment at 54:19 (count = 0), Skipped
-Segment at 59:9 (count = 1), RegionEntry
-Segment at 60:12 (count = 0), Skipped
-Segment at 60:13 (count = 1), RegionEntry
-Segment at 62:6 (count = 0), Skipped
-Segment at 64:9 (count = 0), RegionEntry
-Segment at 64:10 (count = 0), Skipped
-Segment at 64:16 (count = 1), RegionEntry
-Segment at 64:29 (count = 0), Skipped
-Segment at 64:30 (count = 0), RegionEntry
-Segment at 66:6 (count = 0), Skipped
-Segment at 66:15 (count = 1), RegionEntry
-Segment at 66:28 (count = 0), Skipped
-Segment at 67:12 (count = 0), RegionEntry
-Segment at 67:25 (count = 0), Skipped
-Segment at 67:29 (count = 0), RegionEntry
-Segment at 67:42 (count = 0), Skipped
-Segment at 67:46 (count = 0), RegionEntry
-Segment at 67:60 (count = 0), Skipped
-Segment at 67:61 (count = 0), RegionEntry
-Segment at 69:10 (count = 0), RegionEntry
-Segment at 69:11 (count = 0), Skipped
-Segment at 70:9 (count = 0), RegionEntry
-Segment at 70:23 (count = 0), Skipped
-Segment at 72:13 (count = 1), RegionEntry
-Segment at 74:15 (count = 0), Skipped
-Segment at 77:9 (count = 0), RegionEntry
-Segment at 77:10 (count = 0), Skipped
-Segment at 77:16 (count = 0), RegionEntry
-Segment at 77:29 (count = 0), Skipped
-Segment at 77:30 (count = 0), RegionEntry
-Segment at 79:6 (count = 0), Skipped
-Segment at 79:15 (count = 0), RegionEntry
-Segment at 79:28 (count = 0), Skipped
-Segment at 80:12 (count = 0), RegionEntry
-Segment at 80:25 (count = 0), Skipped
-Segment at 80:29 (count = 0), RegionEntry
-Segment at 80:42 (count = 0), Skipped
-Segment at 80:46 (count = 0), RegionEntry
-Segment at 80:60 (count = 0), Skipped
-Segment at 80:61 (count = 0), RegionEntry
-Segment at 82:10 (count = 0), RegionEntry
-Segment at 82:11 (count = 0), Skipped
-Segment at 83:9 (count = 0), RegionEntry
-Segment at 83:23 (count = 0), Skipped
-Segment at 85:9 (count = 0), RegionEntry
-Segment at 85:15 (count = 0), Skipped
-Segment at 87:1 (count = 1), RegionEntry
-Segment at 87:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.dead_code.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.dead_code.txt
deleted file mode 100644
index a2187d477c8..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.dead_code.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-Counter in file 0 3:1 -> 10:15, 0
-Counter in file 0 10:16 -> 12:6, 0
-Counter in file 0 12:6 -> 12:7, 0
-Counter in file 0 13:1 -> 13:2, 0
-Counter in file 0 15:1 -> 22:15, 0
-Counter in file 0 22:16 -> 24:6, 0
-Counter in file 0 24:6 -> 24:7, 0
-Counter in file 0 25:1 -> 25:2, 0
-Counter in file 0 27:1 -> 34:15, #1
-Counter in file 0 34:16 -> 36:6, #2
-Counter in file 0 36:6 -> 36:7, (#1 - #2)
-Counter in file 0 37:1 -> 37:2, (#2 + (#1 - #2))
-Emitting segments for file: ../coverage/dead_code.rs
-Combined regions:
-  3:1 -> 10:15 (count=0)
-  10:16 -> 12:6 (count=0)
-  12:6 -> 12:7 (count=0)
-  13:1 -> 13:2 (count=0)
-  15:1 -> 22:15 (count=0)
-  22:16 -> 24:6 (count=0)
-  24:6 -> 24:7 (count=0)
-  25:1 -> 25:2 (count=0)
-  27:1 -> 34:15 (count=1)
-  34:16 -> 36:6 (count=1)
-  36:6 -> 36:7 (count=0)
-  37:1 -> 37:2 (count=1)
-Segment at 3:1 (count = 0), RegionEntry
-Segment at 10:15 (count = 0), Skipped
-Segment at 10:16 (count = 0), RegionEntry
-Segment at 12:6 (count = 0), RegionEntry
-Segment at 12:7 (count = 0), Skipped
-Segment at 13:1 (count = 0), RegionEntry
-Segment at 13:2 (count = 0), Skipped
-Segment at 15:1 (count = 0), RegionEntry
-Segment at 22:15 (count = 0), Skipped
-Segment at 22:16 (count = 0), RegionEntry
-Segment at 24:6 (count = 0), RegionEntry
-Segment at 24:7 (count = 0), Skipped
-Segment at 25:1 (count = 0), RegionEntry
-Segment at 25:2 (count = 0), Skipped
-Segment at 27:1 (count = 1), RegionEntry
-Segment at 34:15 (count = 0), Skipped
-Segment at 34:16 (count = 1), RegionEntry
-Segment at 36:6 (count = 0), RegionEntry
-Segment at 36:7 (count = 0), Skipped
-Segment at 37:1 (count = 1), RegionEntry
-Segment at 37:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.drop_trait.txt
deleted file mode 100644
index 66c51e3a298..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.drop_trait.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-Counter in file 0 9:5 -> 11:6, #1
-Counter in file 0 14:1 -> 19:12, #1
-Counter in file 0 20:9 -> 21:22, #2
-Counter in file 0 27:1 -> 27:2, (#2 + 0)
-Emitting segments for file: ../coverage/drop_trait.rs
-Combined regions:
-  9:5 -> 11:6 (count=2)
-  14:1 -> 19:12 (count=1)
-  20:9 -> 21:22 (count=1)
-  27:1 -> 27:2 (count=1)
-Segment at 9:5 (count = 2), RegionEntry
-Segment at 11:6 (count = 0), Skipped
-Segment at 14:1 (count = 1), RegionEntry
-Segment at 19:12 (count = 0), Skipped
-Segment at 20:9 (count = 1), RegionEntry
-Segment at 21:22 (count = 0), Skipped
-Segment at 27:1 (count = 1), RegionEntry
-Segment at 27:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.generics.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.generics.txt
deleted file mode 100644
index e2cbf6f709e..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.generics.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-Counter in file 0 17:5 -> 19:6, #1
-Counter in file 0 17:5 -> 19:6, #1
-Counter in file 0 22:1 -> 30:12, #1
-Counter in file 0 31:9 -> 32:22, #2
-Counter in file 0 42:1 -> 42:2, (#2 + 0)
-Counter in file 0 10:5 -> 12:6, #1
-Counter in file 0 10:5 -> 12:6, #1
-Emitting segments for file: ../coverage/generics.rs
-Combined regions:
-  10:5 -> 12:6 (count=3)
-  17:5 -> 19:6 (count=2)
-  22:1 -> 30:12 (count=1)
-  31:9 -> 32:22 (count=1)
-  42:1 -> 42:2 (count=1)
-Segment at 10:5 (count = 3), RegionEntry
-Segment at 12:6 (count = 0), Skipped
-Segment at 17:5 (count = 2), RegionEntry
-Segment at 19:6 (count = 0), Skipped
-Segment at 22:1 (count = 1), RegionEntry
-Segment at 30:12 (count = 0), Skipped
-Segment at 31:9 (count = 1), RegionEntry
-Segment at 32:22 (count = 0), Skipped
-Segment at 42:1 (count = 1), RegionEntry
-Segment at 42:2 (count = 0), Skipped
-Emitting segments for function: _RNvMCs4fqI2P2rA04_8genericsINtB2_8FireworkdE12set_strengthB2_
-Combined regions:
-  10:5 -> 12:6 (count=2)
-Segment at 10:5 (count = 2), RegionEntry
-Segment at 12:6 (count = 0), Skipped
-Emitting segments for function: _RNvMCs4fqI2P2rA04_8genericsINtB2_8FireworklE12set_strengthB2_
-Combined regions:
-  10:5 -> 12:6 (count=1)
-Segment at 10:5 (count = 1), RegionEntry
-Segment at 12:6 (count = 0), Skipped
-Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworklENtNtNtCs3rFBWs28XFJ_4core3ops4drop4Drop4dropB4_
-Combined regions:
-  17:5 -> 19:6 (count=1)
-Segment at 17:5 (count = 1), RegionEntry
-Segment at 19:6 (count = 0), Skipped
-Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworkdENtNtNtCs3rFBWs28XFJ_4core3ops4drop4Drop4dropB4_
-Combined regions:
-  17:5 -> 19:6 (count=1)
-Segment at 17:5 (count = 1), RegionEntry
-Segment at 19:6 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if.txt
deleted file mode 100644
index 2e802a462ea..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Counter in file 0 3:1 -> 21:16, #1
-Counter in file 0 22:5 -> 27:6, #2
-Counter in file 0 27:6 -> 27:7, (#1 - #2)
-Counter in file 0 28:1 -> 28:2, (#2 + (#1 - #2))
-Emitting segments for file: ../coverage/if.rs
-Combined regions:
-  3:1 -> 21:16 (count=1)
-  22:5 -> 27:6 (count=1)
-  27:6 -> 27:7 (count=0)
-  28:1 -> 28:2 (count=1)
-Segment at 3:1 (count = 1), RegionEntry
-Segment at 21:16 (count = 0), Skipped
-Segment at 22:5 (count = 1), RegionEntry
-Segment at 27:6 (count = 0), RegionEntry
-Segment at 27:7 (count = 0), Skipped
-Segment at 28:1 (count = 1), RegionEntry
-Segment at 28:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if_else.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if_else.txt
deleted file mode 100644
index 03b35b0f009..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.if_else.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Counter in file 0 3:1 -> 11:16, #1
-Counter in file 0 12:5 -> 17:6, #2
-Counter in file 0 20:9 -> 22:16, (#1 - #2)
-Counter in file 0 26:9 -> 26:16, (#2 + (#1 - #2))
-Counter in file 0 27:5 -> 32:6, #3
-Counter in file 0 34:5 -> 39:6, ((#2 + (#1 - #2)) - #3)
-Counter in file 0 40:1 -> 40:2, (#3 + ((#2 + (#1 - #2)) - #3))
-Emitting segments for file: ../coverage/if_else.rs
-Combined regions:
-  3:1 -> 11:16 (count=1)
-  12:5 -> 17:6 (count=1)
-  20:9 -> 22:16 (count=0)
-  26:9 -> 26:16 (count=1)
-  27:5 -> 32:6 (count=1)
-  34:5 -> 39:6 (count=0)
-  40:1 -> 40:2 (count=1)
-Segment at 3:1 (count = 1), RegionEntry
-Segment at 11:16 (count = 0), Skipped
-Segment at 12:5 (count = 1), RegionEntry
-Segment at 17:6 (count = 0), Skipped
-Segment at 20:9 (count = 0), RegionEntry
-Segment at 22:16 (count = 0), Skipped
-Segment at 26:9 (count = 1), RegionEntry
-Segment at 26:16 (count = 0), Skipped
-Segment at 27:5 (count = 1), RegionEntry
-Segment at 32:6 (count = 0), Skipped
-Segment at 34:5 (count = 0), RegionEntry
-Segment at 39:6 (count = 0), Skipped
-Segment at 40:1 (count = 1), RegionEntry
-Segment at 40:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.inner_items.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.inner_items.txt
deleted file mode 100644
index 5dc704d6149..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.inner_items.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-Counter in file 0 18:5 -> 22:6, #1
-Counter in file 0 3:1 -> 3:11, #1
-Counter in file 0 7:9 -> 10:15, (#1 + 0)
-Counter in file 0 10:16 -> 12:6, #2
-Counter in file 0 12:6 -> 12:7, (#1 - #2)
-Counter in file 0 48:8 -> 48:15, (#2 + (#1 - #2))
-Counter in file 0 48:16 -> 50:6, #3
-Counter in file 0 50:6 -> 50:7, ((#2 + (#1 - #2)) - #3)
-Counter in file 0 52:9 -> 57:2, (#3 + ((#2 + (#1 - #2)) - #3))
-Counter in file 0 33:9 -> 36:10, #1
-Counter in file 0 40:9 -> 43:10, #1
-Emitting segments for file: ../coverage/inner_items.rs
-Combined regions:
-  3:1 -> 3:11 (count=1)
-  7:9 -> 10:15 (count=1)
-  10:16 -> 12:6 (count=1)
-  12:6 -> 12:7 (count=0)
-  18:5 -> 22:6 (count=3)
-  33:9 -> 36:10 (count=1)
-  40:9 -> 43:10 (count=1)
-  48:8 -> 48:15 (count=1)
-  48:16 -> 50:6 (count=1)
-  50:6 -> 50:7 (count=0)
-  52:9 -> 57:2 (count=1)
-Segment at 3:1 (count = 1), RegionEntry
-Segment at 3:11 (count = 0), Skipped
-Segment at 7:9 (count = 1), RegionEntry
-Segment at 10:15 (count = 0), Skipped
-Segment at 10:16 (count = 1), RegionEntry
-Segment at 12:6 (count = 0), RegionEntry
-Segment at 12:7 (count = 0), Skipped
-Segment at 18:5 (count = 3), RegionEntry
-Segment at 22:6 (count = 0), Skipped
-Segment at 33:9 (count = 1), RegionEntry
-Segment at 36:10 (count = 0), Skipped
-Segment at 40:9 (count = 1), RegionEntry
-Segment at 43:10 (count = 0), Skipped
-Segment at 48:8 (count = 1), RegionEntry
-Segment at 48:15 (count = 0), Skipped
-Segment at 48:16 (count = 1), RegionEntry
-Segment at 50:6 (count = 0), RegionEntry
-Segment at 50:7 (count = 0), Skipped
-Segment at 52:9 (count = 1), RegionEntry
-Segment at 57:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.lazy_boolean.txt
deleted file mode 100644
index d5667fb861e..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.lazy_boolean.txt
+++ /dev/null
@@ -1,111 +0,0 @@
-Counter in file 0 3:1 -> 10:15, #1
-Counter in file 0 10:16 -> 14:6, #2
-Counter in file 0 14:6 -> 14:7, (#1 - #2)
-Counter in file 0 16:9 -> 16:17, ((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4))
-Counter in file 0 18:13 -> 18:18, (#2 + (#1 - #2))
-Counter in file 0 20:13 -> 20:18, ((#2 + (#1 - #2)) - #3)
-Counter in file 0 23:9 -> 23:17, ((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6))
-Counter in file 0 25:13 -> 25:18, (((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) + 0)
-Counter in file 0 27:13 -> 27:18, (((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5)
-Counter in file 0 29:9 -> 29:17, (#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8)))
-Counter in file 0 29:20 -> 29:25, (((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) + 0)
-Counter in file 0 29:29 -> 29:34, #7
-Counter in file 0 30:9 -> 30:17, (#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10)))
-Counter in file 0 30:20 -> 30:25, ((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) + 0)
-Counter in file 0 30:29 -> 30:34, #9
-Counter in file 0 33:9 -> 34:16, ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) + 0)
-Counter in file 0 35:5 -> 38:6, #11
-Counter in file 0 38:6 -> 38:7, ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)
-Counter in file 0 41:9 -> 41:16, (#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11))
-Counter in file 0 42:5 -> 45:6, #12
-Counter in file 0 47:5 -> 50:6, ((#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) - #12)
-Counter in file 0 52:8 -> 52:16, (#12 + ((#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) - #12))
-Counter in file 0 52:17 -> 54:6, #13
-Counter in file 0 54:6 -> 54:7, ((#12 + ((#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) - #12)) - #13)
-Counter in file 0 56:8 -> 56:15, (#13 + ((#12 + ((#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) - #12)) - #13))
-Counter in file 0 56:16 -> 58:6, #14
-Counter in file 0 58:12 -> 60:6, ((#13 + ((#12 + ((#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) - #12)) - #13)) - #14)
-Counter in file 0 61:1 -> 61:2, (#14 + ((#13 + ((#12 + ((#11 + ((#10 + (((#8 + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + (#7 - #8))) - #9) + (#9 - #10))) - #11)) - #12)) - #13)) - #14))
-Emitting segments for file: ../coverage/lazy_boolean.rs
-Combined regions:
-  3:1 -> 10:15 (count=1)
-  10:16 -> 14:6 (count=1)
-  14:6 -> 14:7 (count=0)
-  16:9 -> 16:17 (count=1)
-  18:13 -> 18:18 (count=1)
-  20:13 -> 20:18 (count=0)
-  23:9 -> 23:17 (count=1)
-  25:13 -> 25:18 (count=1)
-  27:13 -> 27:18 (count=1)
-  29:9 -> 29:17 (count=1)
-  29:20 -> 29:25 (count=1)
-  29:29 -> 29:34 (count=1)
-  30:9 -> 30:17 (count=1)
-  30:20 -> 30:25 (count=1)
-  30:29 -> 30:34 (count=0)
-  33:9 -> 34:16 (count=1)
-  35:5 -> 38:6 (count=0)
-  38:6 -> 38:7 (count=1)
-  41:9 -> 41:16 (count=1)
-  42:5 -> 45:6 (count=1)
-  47:5 -> 50:6 (count=0)
-  52:8 -> 52:16 (count=1)
-  52:17 -> 54:6 (count=0)
-  54:6 -> 54:7 (count=1)
-  56:8 -> 56:15 (count=1)
-  56:16 -> 58:6 (count=1)
-  58:12 -> 60:6 (count=0)
-  61:1 -> 61:2 (count=1)
-Segment at 3:1 (count = 1), RegionEntry
-Segment at 10:15 (count = 0), Skipped
-Segment at 10:16 (count = 1), RegionEntry
-Segment at 14:6 (count = 0), RegionEntry
-Segment at 14:7 (count = 0), Skipped
-Segment at 16:9 (count = 1), RegionEntry
-Segment at 16:17 (count = 0), Skipped
-Segment at 18:13 (count = 1), RegionEntry
-Segment at 18:18 (count = 0), Skipped
-Segment at 20:13 (count = 0), RegionEntry
-Segment at 20:18 (count = 0), Skipped
-Segment at 23:9 (count = 1), RegionEntry
-Segment at 23:17 (count = 0), Skipped
-Segment at 25:13 (count = 1), RegionEntry
-Segment at 25:18 (count = 0), Skipped
-Segment at 27:13 (count = 1), RegionEntry
-Segment at 27:18 (count = 0), Skipped
-Segment at 29:9 (count = 1), RegionEntry
-Segment at 29:17 (count = 0), Skipped
-Segment at 29:20 (count = 1), RegionEntry
-Segment at 29:25 (count = 0), Skipped
-Segment at 29:29 (count = 1), RegionEntry
-Segment at 29:34 (count = 0), Skipped
-Segment at 30:9 (count = 1), RegionEntry
-Segment at 30:17 (count = 0), Skipped
-Segment at 30:20 (count = 1), RegionEntry
-Segment at 30:25 (count = 0), Skipped
-Segment at 30:29 (count = 0), RegionEntry
-Segment at 30:34 (count = 0), Skipped
-Segment at 33:9 (count = 1), RegionEntry
-Segment at 34:16 (count = 0), Skipped
-Segment at 35:5 (count = 0), RegionEntry
-Segment at 38:6 (count = 1), RegionEntry
-Segment at 38:7 (count = 0), Skipped
-Segment at 41:9 (count = 1), RegionEntry
-Segment at 41:16 (count = 0), Skipped
-Segment at 42:5 (count = 1), RegionEntry
-Segment at 45:6 (count = 0), Skipped
-Segment at 47:5 (count = 0), RegionEntry
-Segment at 50:6 (count = 0), Skipped
-Segment at 52:8 (count = 1), RegionEntry
-Segment at 52:16 (count = 0), Skipped
-Segment at 52:17 (count = 0), RegionEntry
-Segment at 54:6 (count = 1), RegionEntry
-Segment at 54:7 (count = 0), Skipped
-Segment at 56:8 (count = 1), RegionEntry
-Segment at 56:15 (count = 0), Skipped
-Segment at 56:16 (count = 1), RegionEntry
-Segment at 58:6 (count = 0), Skipped
-Segment at 58:12 (count = 0), RegionEntry
-Segment at 60:6 (count = 0), Skipped
-Segment at 61:1 (count = 1), RegionEntry
-Segment at 61:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loop_break_value.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loop_break_value.txt
deleted file mode 100644
index 17bd5c2ff31..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loop_break_value.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Counter in file 0 3:1 -> 13:2, #1
-Emitting segments for file: ../coverage/loop_break_value.rs
-Combined regions:
-  3:1 -> 13:2 (count=1)
-Segment at 3:1 (count = 1), RegionEntry
-Segment at 13:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loops_branches.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loops_branches.txt
deleted file mode 100644
index d1da50b1529..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.loops_branches.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Counter in file 0 9:5 -> 10:16, #1
-Counter in file 0 11:16 -> 11:21, #2
-Counter in file 0 14:14 -> 14:15, (#2 - #5)
-Counter in file 0 15:13 -> 15:31, ((0 - #6) + (#2 - #5))
-Counter in file 0 15:31 -> 15:32, #4
-Counter in file 0 18:9 -> 18:15, (#3 + 0)
-Counter in file 0 19:5 -> 19:6, (#4 + (#3 + 0))
-Counter in file 0 22:1 -> 25:2, #1
-Emitting segments for file: ../coverage/loops_branches.rs
-Combined regions:
-  9:5 -> 10:16 (count=1)
-  11:16 -> 11:21 (count=1)
-  14:14 -> 14:15 (count=1)
-  15:13 -> 15:31 (count=1)
-  15:31 -> 15:32 (count=0)
-  18:9 -> 18:15 (count=1)
-  19:5 -> 19:6 (count=1)
-  22:1 -> 25:2 (count=1)
-Segment at 9:5 (count = 1), RegionEntry
-Segment at 10:16 (count = 0), Skipped
-Segment at 11:16 (count = 1), RegionEntry
-Segment at 11:21 (count = 0), Skipped
-Segment at 14:14 (count = 1), RegionEntry
-Segment at 14:15 (count = 0), Skipped
-Segment at 15:13 (count = 1), RegionEntry
-Segment at 15:31 (count = 0), RegionEntry
-Segment at 15:32 (count = 0), Skipped
-Segment at 18:9 (count = 1), RegionEntry
-Segment at 18:15 (count = 0), Skipped
-Segment at 19:5 (count = 1), RegionEntry
-Segment at 19:6 (count = 0), Skipped
-Segment at 22:1 (count = 1), RegionEntry
-Segment at 25:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.nested_loops.txt
deleted file mode 100644
index f30dd9e3716..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.nested_loops.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-Counter in file 0 1:1 -> 3:27, #1
-Counter in file 0 5:19 -> 5:32, (#1 + (#2 + #3))
-Counter in file 0 6:13 -> 7:24, ((#1 + (#2 + #3)) - #4)
-Counter in file 0 8:13 -> 8:14, ((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3)
-Counter in file 0 8:18 -> 8:23, (((#1 + (#2 + #3)) - #4) + (#6 + #7))
-Counter in file 0 9:16 -> 9:22, (((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3) + 0)
-Counter in file 0 10:17 -> 10:22, #2
-Counter in file 0 11:14 -> 14:22, (((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3) - #2)
-Counter in file 0 15:17 -> 16:27, ((((((#1 + (#2 + #3)) - #4) + (#6 + #7)) - #3) - #2) - #7)
-Counter in file 0 17:21 -> 17:33, #5
-Counter in file 0 18:24 -> 20:18, #6
-Counter in file 0 21:14 -> 21:15, #7
-Counter in file 0 23:9 -> 23:23, (#2 + #3)
-Counter in file 0 25:1 -> 25:2, (#5 + #4)
-Emitting segments for file: ../coverage/nested_loops.rs
-Combined regions:
-  1:1 -> 3:27 (count=1)
-  5:19 -> 5:32 (count=1)
-  6:13 -> 7:24 (count=1)
-  8:13 -> 8:14 (count=3)
-  8:18 -> 8:23 (count=3)
-  9:16 -> 9:22 (count=3)
-  10:17 -> 10:22 (count=0)
-  11:14 -> 14:22 (count=3)
-  15:17 -> 16:27 (count=1)
-  17:21 -> 17:33 (count=1)
-  18:24 -> 20:18 (count=0)
-  21:14 -> 21:15 (count=2)
-  23:9 -> 23:23 (count=0)
-  25:1 -> 25:2 (count=1)
-Segment at 1:1 (count = 1), RegionEntry
-Segment at 3:27 (count = 0), Skipped
-Segment at 5:19 (count = 1), RegionEntry
-Segment at 5:32 (count = 0), Skipped
-Segment at 6:13 (count = 1), RegionEntry
-Segment at 7:24 (count = 0), Skipped
-Segment at 8:13 (count = 3), RegionEntry
-Segment at 8:14 (count = 0), Skipped
-Segment at 8:18 (count = 3), RegionEntry
-Segment at 8:23 (count = 0), Skipped
-Segment at 9:16 (count = 3), RegionEntry
-Segment at 9:22 (count = 0), Skipped
-Segment at 10:17 (count = 0), RegionEntry
-Segment at 10:22 (count = 0), Skipped
-Segment at 11:14 (count = 3), RegionEntry
-Segment at 14:22 (count = 0), Skipped
-Segment at 15:17 (count = 1), RegionEntry
-Segment at 16:27 (count = 0), Skipped
-Segment at 17:21 (count = 1), RegionEntry
-Segment at 17:33 (count = 0), Skipped
-Segment at 18:24 (count = 0), RegionEntry
-Segment at 20:18 (count = 0), Skipped
-Segment at 21:14 (count = 2), RegionEntry
-Segment at 21:15 (count = 0), Skipped
-Segment at 23:9 (count = 0), RegionEntry
-Segment at 23:23 (count = 0), Skipped
-Segment at 25:1 (count = 1), RegionEntry
-Segment at 25:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt
deleted file mode 100644
index fbc3adbfb6d..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-Counter in file 0 15:1 -> 16:27, #1
-Counter in file 0 17:11 -> 17:24, (#1 + (#2 + (#3 + #4)))
-Counter in file 0 18:12 -> 18:26, ((#1 + (#2 + (#3 + #4))) - #5)
-Counter in file 0 18:27 -> 21:10, #2
-Counter in file 0 21:19 -> 21:32, (((#1 + (#2 + (#3 + #4))) - #5) - #2)
-Counter in file 0 21:33 -> 24:10, #3
-Counter in file 0 24:10 -> 24:11, #4
-Counter in file 0 25:9 -> 25:23, (#2 + (#3 + #4))
-Counter in file 0 27:5 -> 28:2, #5
-Counter in file 0 4:1 -> 5:18, #1
-Counter in file 0 5:19 -> 7:6, #2
-Counter in file 0 7:6 -> 7:7, (#1 - #2)
-Counter in file 0 8:9 -> 13:2, (#2 + (#1 - #2))
-Emitting segments for file: ../coverage/overflow.rs
-Combined regions:
-  4:1 -> 5:18 (count=4)
-  5:19 -> 7:6 (count=1)
-  7:6 -> 7:7 (count=3)
-  8:9 -> 13:2 (count=4)
-  15:1 -> 16:27 (count=1)
-  17:11 -> 17:24 (count=10)
-  18:12 -> 18:26 (count=10)
-  18:27 -> 21:10 (count=0)
-  21:19 -> 21:32 (count=10)
-  21:33 -> 24:10 (count=3)
-  24:10 -> 24:11 (count=6)
-  25:9 -> 25:23 (count=9)
-  27:5 -> 28:2 (count=0)
-Segment at 4:1 (count = 4), RegionEntry
-Segment at 5:18 (count = 0), Skipped
-Segment at 5:19 (count = 1), RegionEntry
-Segment at 7:6 (count = 3), RegionEntry
-Segment at 7:7 (count = 0), Skipped
-Segment at 8:9 (count = 4), RegionEntry
-Segment at 13:2 (count = 0), Skipped
-Segment at 15:1 (count = 1), RegionEntry
-Segment at 16:27 (count = 0), Skipped
-Segment at 17:11 (count = 10), RegionEntry
-Segment at 17:24 (count = 0), Skipped
-Segment at 18:12 (count = 10), RegionEntry
-Segment at 18:26 (count = 0), Skipped
-Segment at 18:27 (count = 0), RegionEntry
-Segment at 21:10 (count = 0), Skipped
-Segment at 21:19 (count = 10), RegionEntry
-Segment at 21:32 (count = 0), Skipped
-Segment at 21:33 (count = 3), RegionEntry
-Segment at 24:10 (count = 6), RegionEntry
-Segment at 24:11 (count = 0), Skipped
-Segment at 25:9 (count = 9), RegionEntry
-Segment at 25:23 (count = 0), Skipped
-Segment at 27:5 (count = 0), RegionEntry
-Segment at 28:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt
deleted file mode 100644
index ad87f03026d..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-Counter in file 0 13:1 -> 14:27, #1
-Counter in file 0 15:11 -> 15:24, (#1 + (#2 + (#3 + #4)))
-Counter in file 0 16:12 -> 16:26, ((#1 + (#2 + (#3 + #4))) - #5)
-Counter in file 0 16:27 -> 18:10, #2
-Counter in file 0 18:19 -> 18:32, (((#1 + (#2 + (#3 + #4))) - #5) - #2)
-Counter in file 0 18:33 -> 20:10, #3
-Counter in file 0 20:10 -> 20:11, #4
-Counter in file 0 21:9 -> 21:23, (#2 + (#3 + #4))
-Counter in file 0 23:5 -> 24:2, #5
-Counter in file 0 4:1 -> 4:36, #1
-Counter in file 0 5:8 -> 5:20, (#1 + 0)
-Counter in file 0 6:9 -> 7:26, #2
-Counter in file 0 8:12 -> 11:2, (#1 - #2)
-Emitting segments for file: ../coverage/panic_unwind.rs
-Combined regions:
-  4:1 -> 4:36 (count=4)
-  5:8 -> 5:20 (count=4)
-  6:9 -> 7:26 (count=1)
-  8:12 -> 11:2 (count=3)
-  13:1 -> 14:27 (count=1)
-  15:11 -> 15:24 (count=10)
-  16:12 -> 16:26 (count=10)
-  16:27 -> 18:10 (count=0)
-  18:19 -> 18:32 (count=10)
-  18:33 -> 20:10 (count=3)
-  20:10 -> 20:11 (count=6)
-  21:9 -> 21:23 (count=9)
-  23:5 -> 24:2 (count=0)
-Segment at 4:1 (count = 4), RegionEntry
-Segment at 4:36 (count = 0), Skipped
-Segment at 5:8 (count = 4), RegionEntry
-Segment at 5:20 (count = 0), Skipped
-Segment at 6:9 (count = 1), RegionEntry
-Segment at 7:26 (count = 0), Skipped
-Segment at 8:12 (count = 3), RegionEntry
-Segment at 11:2 (count = 0), Skipped
-Segment at 13:1 (count = 1), RegionEntry
-Segment at 14:27 (count = 0), Skipped
-Segment at 15:11 (count = 10), RegionEntry
-Segment at 15:24 (count = 0), Skipped
-Segment at 16:12 (count = 10), RegionEntry
-Segment at 16:26 (count = 0), Skipped
-Segment at 16:27 (count = 0), RegionEntry
-Segment at 18:10 (count = 0), Skipped
-Segment at 18:19 (count = 10), RegionEntry
-Segment at 18:32 (count = 0), Skipped
-Segment at 18:33 (count = 3), RegionEntry
-Segment at 20:10 (count = 6), RegionEntry
-Segment at 20:11 (count = 0), Skipped
-Segment at 21:9 (count = 9), RegionEntry
-Segment at 21:23 (count = 0), Skipped
-Segment at 23:5 (count = 0), RegionEntry
-Segment at 24:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.partial_eq.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.partial_eq.txt
deleted file mode 100644
index fa5c12bb6f8..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.partial_eq.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-Counter in file 0 4:10 -> 4:15, 0
-Counter in file 0 4:24 -> 4:25, 0
-Counter in file 0 4:24 -> 4:25, 0
-Counter in file 0 4:32 -> 4:33, 0
-Counter in file 0 4:32 -> 4:33, 0
-Counter in file 0 4:35 -> 4:36, 0
-Counter in file 0 4:39 -> 4:40, 0
-Counter in file 0 4:39 -> 4:40, 0
-Counter in file 0 4:39 -> 4:40, 0
-Counter in file 0 4:39 -> 4:40, 0
-Counter in file 0 4:48 -> 4:49, 0
-Counter in file 0 4:51 -> 4:52, 0
-Counter in file 0 4:53 -> 4:54, 0
-Counter in file 0 7:5 -> 7:6, #1
-Counter in file 0 7:5 -> 7:6, 0
-Counter in file 0 7:5 -> 7:6, 0
-Counter in file 0 7:5 -> 7:6, 0
-Counter in file 0 8:5 -> 8:17, 0
-Counter in file 0 8:5 -> 8:17, 0
-Counter in file 0 8:5 -> 8:17, 0
-Counter in file 0 21:1 -> 26:2, #1
-Counter in file 0 4:17 -> 4:22, #1
-Counter in file 0 12:5 -> 18:6, #1
-Counter in file 0 4:39 -> 4:40, #1
-Counter in file 0 8:5 -> 8:17, #1
-Emitting segments for file: ../coverage/partial_eq.rs
-Combined regions:
-  4:10 -> 4:15 (count=0)
-  4:17 -> 4:22 (count=2)
-  4:24 -> 4:25 (count=0)
-  4:32 -> 4:33 (count=0)
-  4:35 -> 4:36 (count=0)
-  4:39 -> 4:40 (count=1)
-  4:48 -> 4:49 (count=0)
-  4:51 -> 4:52 (count=0)
-  4:53 -> 4:54 (count=0)
-  7:5 -> 7:6 (count=1)
-  8:5 -> 8:17 (count=0)
-  12:5 -> 18:6 (count=2)
-  21:1 -> 26:2 (count=1)
-Segment at 4:10 (count = 0), RegionEntry
-Segment at 4:15 (count = 0), Skipped
-Segment at 4:17 (count = 2), RegionEntry
-Segment at 4:22 (count = 0), Skipped
-Segment at 4:24 (count = 0), RegionEntry
-Segment at 4:25 (count = 0), Skipped
-Segment at 4:32 (count = 0), RegionEntry
-Segment at 4:33 (count = 0), Skipped
-Segment at 4:35 (count = 0), RegionEntry
-Segment at 4:36 (count = 0), Skipped
-Segment at 4:39 (count = 1), RegionEntry
-Segment at 4:40 (count = 0), Skipped
-Segment at 4:48 (count = 0), RegionEntry
-Segment at 4:49 (count = 0), Skipped
-Segment at 4:51 (count = 0), RegionEntry
-Segment at 4:52 (count = 0), Skipped
-Segment at 4:53 (count = 0), RegionEntry
-Segment at 4:54 (count = 0), Skipped
-Segment at 7:5 (count = 1), RegionEntry
-Segment at 7:6 (count = 0), Skipped
-Segment at 8:5 (count = 0), RegionEntry
-Segment at 8:17 (count = 0), Skipped
-Segment at 12:5 (count = 2), RegionEntry
-Segment at 18:6 (count = 0), Skipped
-Segment at 21:1 (count = 1), RegionEntry
-Segment at 26:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_loop.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_loop.txt
deleted file mode 100644
index c0b09486dfb..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_loop.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-Counter in file 0 3:1 -> 12:16, #1
-Counter in file 0 13:5 -> 18:6, #2
-Counter in file 0 18:6 -> 18:7, (#1 - #2)
-Counter in file 0 23:13 -> 25:14, ((#2 + (#1 - #2)) + #3)
-Counter in file 0 27:13 -> 27:18, (((#2 + (#1 - #2)) + #3) - #3)
-Counter in file 0 29:10 -> 32:10, #3
-Counter in file 0 35:1 -> 35:2, ((((#2 + (#1 - #2)) + #3) - #3) + 0)
-Emitting segments for file: ../coverage/simple_loop.rs
-Combined regions:
-  3:1 -> 12:16 (count=1)
-  13:5 -> 18:6 (count=1)
-  18:6 -> 18:7 (count=0)
-  23:13 -> 25:14 (count=11)
-  27:13 -> 27:18 (count=1)
-  29:10 -> 32:10 (count=10)
-  35:1 -> 35:2 (count=1)
-Segment at 3:1 (count = 1), RegionEntry
-Segment at 12:16 (count = 0), Skipped
-Segment at 13:5 (count = 1), RegionEntry
-Segment at 18:6 (count = 0), RegionEntry
-Segment at 18:7 (count = 0), Skipped
-Segment at 23:13 (count = 11), RegionEntry
-Segment at 25:14 (count = 0), Skipped
-Segment at 27:13 (count = 1), RegionEntry
-Segment at 27:18 (count = 0), Skipped
-Segment at 29:10 (count = 10), RegionEntry
-Segment at 32:10 (count = 0), Skipped
-Segment at 35:1 (count = 1), RegionEntry
-Segment at 35:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_match.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_match.txt
deleted file mode 100644
index c01630bd87b..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.simple_match.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-Counter in file 0 3:1 -> 10:15, #1
-Counter in file 0 10:16 -> 12:6, #2
-Counter in file 0 12:6 -> 12:7, (#1 - #2)
-Counter in file 0 15:9 -> 15:10, (((#2 + (#1 - #2)) + (#3 + #4)) - #5)
-Counter in file 0 17:9 -> 17:13, ((#2 + (#1 - #2)) + (#3 + #4))
-Counter in file 0 22:13 -> 22:22, ((((#2 + (#1 - #2)) + (#3 + #4)) - #5) + 0)
-Counter in file 0 24:13 -> 24:14, #3
-Counter in file 0 26:17 -> 28:18, ((((#2 + (#1 - #2)) + (#3 + #4)) - #5) + 0)
-Counter in file 0 30:13 -> 37:14, (#3 + 0)
-Counter in file 0 40:13 -> 40:15, #4
-Counter in file 0 43:1 -> 43:2, #5
-Emitting segments for file: ../coverage/simple_match.rs
-Combined regions:
-  3:1 -> 10:15 (count=1)
-  10:16 -> 12:6 (count=1)
-  12:6 -> 12:7 (count=0)
-  15:9 -> 15:10 (count=2)
-  17:9 -> 17:13 (count=3)
-  22:13 -> 22:22 (count=2)
-  24:13 -> 24:14 (count=1)
-  26:17 -> 28:18 (count=2)
-  30:13 -> 37:14 (count=1)
-  40:13 -> 40:15 (count=1)
-  43:1 -> 43:2 (count=1)
-Segment at 3:1 (count = 1), RegionEntry
-Segment at 10:15 (count = 0), Skipped
-Segment at 10:16 (count = 1), RegionEntry
-Segment at 12:6 (count = 0), RegionEntry
-Segment at 12:7 (count = 0), Skipped
-Segment at 15:9 (count = 2), RegionEntry
-Segment at 15:10 (count = 0), Skipped
-Segment at 17:9 (count = 3), RegionEntry
-Segment at 17:13 (count = 0), Skipped
-Segment at 22:13 (count = 2), RegionEntry
-Segment at 22:22 (count = 0), Skipped
-Segment at 24:13 (count = 1), RegionEntry
-Segment at 24:14 (count = 0), Skipped
-Segment at 26:17 (count = 2), RegionEntry
-Segment at 28:18 (count = 0), Skipped
-Segment at 30:13 (count = 1), RegionEntry
-Segment at 37:14 (count = 0), Skipped
-Segment at 40:13 (count = 1), RegionEntry
-Segment at 40:15 (count = 0), Skipped
-Segment at 43:1 (count = 1), RegionEntry
-Segment at 43:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.tight_inf_loop.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.tight_inf_loop.txt
deleted file mode 100644
index a6cd4298808..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.tight_inf_loop.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Counter in file 0 1:1 -> 2:13, #1
-Counter in file 0 4:6 -> 5:2, (#1 - #2)
-Emitting segments for file: ../coverage/tight_inf_loop.rs
-Combined regions:
-  1:1 -> 2:13 (count=1)
-  4:6 -> 5:2 (count=1)
-Segment at 1:1 (count = 1), RegionEntry
-Segment at 2:13 (count = 0), Skipped
-Segment at 4:6 (count = 1), RegionEntry
-Segment at 5:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.try_error_result.txt
deleted file mode 100644
index 2b7962df2f9..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.try_error_result.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-Counter in file 0 12:1 -> 14:23, #1
-Counter in file 0 17:9 -> 17:10, ((#1 + (#2 + #3)) - #4)
-Counter in file 0 19:9 -> 19:14, (#1 + (#2 + #3))
-Counter in file 0 21:9 -> 25:26, (((#1 + (#2 + #3)) - #4) + 0)
-Counter in file 0 27:13 -> 27:41, #8
-Counter in file 0 27:41 -> 27:42, #5
-Counter in file 0 28:13 -> 28:42, (#8 - #5)
-Counter in file 0 28:42 -> 28:43, #6
-Counter in file 0 32:13 -> 32:42, (((#1 + (#2 + #3)) - #4) - #8)
-Counter in file 0 32:42 -> 32:43, #7
-Counter in file 0 35:5 -> 35:11, #4
-Counter in file 0 36:1 -> 36:2, ((#5 + (#6 + #7)) + #4)
-Counter in file 0 4:1 -> 5:20, #1
-Counter in file 0 6:9 -> 6:16, #2
-Counter in file 0 8:9 -> 8:15, (#1 - #2)
-Counter in file 0 10:1 -> 10:2, (#2 + (#1 - #2))
-Emitting segments for file: ../coverage/try_error_result.rs
-Combined regions:
-  4:1 -> 5:20 (count=6)
-  6:9 -> 6:16 (count=1)
-  8:9 -> 8:15 (count=5)
-  10:1 -> 10:2 (count=6)
-  12:1 -> 14:23 (count=1)
-  17:9 -> 17:10 (count=6)
-  19:9 -> 19:14 (count=6)
-  21:9 -> 25:26 (count=6)
-  27:13 -> 27:41 (count=1)
-  27:41 -> 27:42 (count=1)
-  28:13 -> 28:42 (count=0)
-  28:42 -> 28:43 (count=0)
-  32:13 -> 32:42 (count=5)
-  32:42 -> 32:43 (count=0)
-  35:5 -> 35:11 (count=0)
-  36:1 -> 36:2 (count=1)
-Segment at 4:1 (count = 6), RegionEntry
-Segment at 5:20 (count = 0), Skipped
-Segment at 6:9 (count = 1), RegionEntry
-Segment at 6:16 (count = 0), Skipped
-Segment at 8:9 (count = 5), RegionEntry
-Segment at 8:15 (count = 0), Skipped
-Segment at 10:1 (count = 6), RegionEntry
-Segment at 10:2 (count = 0), Skipped
-Segment at 12:1 (count = 1), RegionEntry
-Segment at 14:23 (count = 0), Skipped
-Segment at 17:9 (count = 6), RegionEntry
-Segment at 17:10 (count = 0), Skipped
-Segment at 19:9 (count = 6), RegionEntry
-Segment at 19:14 (count = 0), Skipped
-Segment at 21:9 (count = 6), RegionEntry
-Segment at 25:26 (count = 0), Skipped
-Segment at 27:13 (count = 1), RegionEntry
-Segment at 27:41 (count = 1), RegionEntry
-Segment at 27:42 (count = 0), Skipped
-Segment at 28:13 (count = 0), RegionEntry
-Segment at 28:42 (count = 0), RegionEntry
-Segment at 28:43 (count = 0), Skipped
-Segment at 32:13 (count = 5), RegionEntry
-Segment at 32:42 (count = 0), RegionEntry
-Segment at 32:43 (count = 0), Skipped
-Segment at 35:5 (count = 0), RegionEntry
-Segment at 35:11 (count = 0), Skipped
-Segment at 36:1 (count = 1), RegionEntry
-Segment at 36:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.uses_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.uses_crate.txt
deleted file mode 100644
index b0319cd9e18..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.uses_crate.txt
+++ /dev/null
@@ -1,110 +0,0 @@
-Counter in file 0 17:1 -> 19:2, #1
-Counter in file 0 25:1 -> 27:2, #1
-Counter in file 0 17:1 -> 19:2, #1
-Counter in file 0 5:1 -> 12:2, #1
-Counter in file 0 17:1 -> 19:2, 0
-Counter in file 0 33:1 -> 35:2, 0
-Counter in file 0 45:1 -> 48:16, 0
-Counter in file 0 48:17 -> 50:6, 0
-Counter in file 0 50:6 -> 50:7, 0
-Counter in file 0 51:1 -> 51:2, 0
-Counter in file 0 53:1 -> 61:2, #1
-Counter in file 0 25:1 -> 27:2, #1
-Counter in file 0 29:1 -> 31:2, #1
-Counter in file 0 21:1 -> 23:2, #1
-Counter in file 0 5:1 -> 5:24, #1
-Counter in file 0 9:9 -> 11:15, (#1 + 0)
-Counter in file 0 11:16 -> 13:6, #2
-Counter in file 0 13:6 -> 13:7, (#1 - #2)
-Counter in file 0 14:5 -> 15:2, (#2 + (#1 - #2))
-Counter in file 0 21:1 -> 23:2, #1
-Counter in file 0 37:1 -> 40:16, #1
-Counter in file 0 40:17 -> 42:6, #2
-Counter in file 0 42:6 -> 42:7, (#1 - #2)
-Counter in file 0 43:1 -> 43:2, (#2 + (#1 - #2))
-Emitting segments for file: ../coverage/lib/used_crate.rs
-Combined regions:
-  5:1 -> 5:24 (count=1)
-  9:9 -> 11:15 (count=1)
-  11:16 -> 13:6 (count=1)
-  13:6 -> 13:7 (count=0)
-  14:5 -> 15:2 (count=1)
-  17:1 -> 19:2 (count=2)
-  21:1 -> 23:2 (count=2)
-  25:1 -> 27:2 (count=2)
-  29:1 -> 31:2 (count=2)
-  33:1 -> 35:2 (count=0)
-  37:1 -> 40:16 (count=0)
-  40:17 -> 42:6 (count=0)
-  42:6 -> 42:7 (count=0)
-  43:1 -> 43:2 (count=0)
-  45:1 -> 48:16 (count=0)
-  48:17 -> 50:6 (count=0)
-  50:6 -> 50:7 (count=0)
-  51:1 -> 51:2 (count=0)
-  53:1 -> 61:2 (count=1)
-Segment at 5:1 (count = 1), RegionEntry
-Segment at 5:24 (count = 0), Skipped
-Segment at 9:9 (count = 1), RegionEntry
-Segment at 11:15 (count = 0), Skipped
-Segment at 11:16 (count = 1), RegionEntry
-Segment at 13:6 (count = 0), RegionEntry
-Segment at 13:7 (count = 0), Skipped
-Segment at 14:5 (count = 1), RegionEntry
-Segment at 15:2 (count = 0), Skipped
-Segment at 17:1 (count = 2), RegionEntry
-Segment at 19:2 (count = 0), Skipped
-Segment at 21:1 (count = 2), RegionEntry
-Segment at 23:2 (count = 0), Skipped
-Segment at 25:1 (count = 2), RegionEntry
-Segment at 27:2 (count = 0), Skipped
-Segment at 29:1 (count = 2), RegionEntry
-Segment at 31:2 (count = 0), Skipped
-Segment at 33:1 (count = 0), RegionEntry
-Segment at 35:2 (count = 0), Skipped
-Segment at 37:1 (count = 0), RegionEntry
-Segment at 40:16 (count = 0), Skipped
-Segment at 40:17 (count = 0), RegionEntry
-Segment at 42:6 (count = 0), RegionEntry
-Segment at 42:7 (count = 0), Skipped
-Segment at 43:1 (count = 0), RegionEntry
-Segment at 43:2 (count = 0), Skipped
-Segment at 45:1 (count = 0), RegionEntry
-Segment at 48:16 (count = 0), Skipped
-Segment at 48:17 (count = 0), RegionEntry
-Segment at 50:6 (count = 0), RegionEntry
-Segment at 50:7 (count = 0), Skipped
-Segment at 51:1 (count = 0), RegionEntry
-Segment at 51:2 (count = 0), Skipped
-Segment at 53:1 (count = 1), RegionEntry
-Segment at 61:2 (count = 0), Skipped
-Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate41used_only_from_bin_crate_generic_functionReECs4fqI2P2rA04_10uses_crate
-Combined regions:
-  17:1 -> 19:2 (count=1)
-Segment at 17:1 (count = 1), RegionEntry
-Segment at 19:2 (count = 0), Skipped
-Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate41used_only_from_bin_crate_generic_functionRINtNtCs3QflaznQylx_5alloc3vec3VeclEECs4fqI2P2rA04_10uses_crate
-Combined regions:
-  17:1 -> 19:2 (count=1)
-Segment at 17:1 (count = 1), RegionEntry
-Segment at 19:2 (count = 0), Skipped
-Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate46used_only_from_this_lib_crate_generic_functionINtNtCs3QflaznQylx_5alloc3vec3VeclEEB2_
-Combined regions:
-  21:1 -> 23:2 (count=1)
-Segment at 21:1 (count = 1), RegionEntry
-Segment at 23:2 (count = 0), Skipped
-Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate46used_only_from_this_lib_crate_generic_functionReEB2_
-Combined regions:
-  21:1 -> 23:2 (count=1)
-Segment at 21:1 (count = 1), RegionEntry
-Segment at 23:2 (count = 0), Skipped
-Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate50used_from_bin_crate_and_lib_crate_generic_functionINtNtCs3QflaznQylx_5alloc3vec3VeclEECs4fqI2P2rA04_10uses_crate
-Combined regions:
-  25:1 -> 27:2 (count=1)
-Segment at 25:1 (count = 1), RegionEntry
-Segment at 27:2 (count = 0), Skipped
-Emitting segments for function: _RINvCsbDqzXfLQacH_10used_crate50used_from_bin_crate_and_lib_crate_generic_functionReEB2_
-Combined regions:
-  25:1 -> 27:2 (count=1)
-Segment at 25:1 (count = 1), RegionEntry
-Segment at 27:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while.txt
deleted file mode 100644
index 90629ac84cd..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-Counter in file 0 1:1 -> 2:16, #1
-Counter in file 0 3:11 -> 3:20, (#1 + #2)
-Counter in file 0 3:21 -> 4:6, #2
-Counter in file 0 5:1 -> 5:2, ((#1 + #2) - #2)
-Emitting segments for file: ../coverage/while.rs
-Combined regions:
-  1:1 -> 2:16 (count=1)
-  3:11 -> 3:20 (count=1)
-  3:21 -> 4:6 (count=0)
-  5:1 -> 5:2 (count=1)
-Segment at 1:1 (count = 1), RegionEntry
-Segment at 2:16 (count = 0), Skipped
-Segment at 3:11 (count = 1), RegionEntry
-Segment at 3:20 (count = 0), Skipped
-Segment at 3:21 (count = 0), RegionEntry
-Segment at 4:6 (count = 0), Skipped
-Segment at 5:1 (count = 1), RegionEntry
-Segment at 5:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while_early_ret.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while_early_ret.txt
deleted file mode 100644
index 12f444945a1..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.while_early_ret.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-Counter in file 0 4:1 -> 5:27, #1
-Counter in file 0 7:9 -> 9:10, (#1 + #2)
-Counter in file 0 12:13 -> 14:14, ((#1 + #2) - #3)
-Counter in file 0 18:21 -> 20:22, (((#1 + #2) - #3) - #2)
-Counter in file 0 22:21 -> 22:27, #4
-Counter in file 0 26:21 -> 26:27, #5
-Counter in file 0 29:10 -> 32:10, #2
-Counter in file 0 35:5 -> 35:11, #3
-Counter in file 0 36:1 -> 36:2, ((#4 + #5) + #3)
-Emitting segments for file: ../coverage/while_early_ret.rs
-Combined regions:
-  4:1 -> 5:27 (count=1)
-  7:9 -> 9:10 (count=7)
-  12:13 -> 14:14 (count=7)
-  18:21 -> 20:22 (count=1)
-  22:21 -> 22:27 (count=0)
-  26:21 -> 26:27 (count=1)
-  29:10 -> 32:10 (count=6)
-  35:5 -> 35:11 (count=0)
-  36:1 -> 36:2 (count=1)
-Segment at 4:1 (count = 1), RegionEntry
-Segment at 5:27 (count = 0), Skipped
-Segment at 7:9 (count = 7), RegionEntry
-Segment at 9:10 (count = 0), Skipped
-Segment at 12:13 (count = 7), RegionEntry
-Segment at 14:14 (count = 0), Skipped
-Segment at 18:21 (count = 1), RegionEntry
-Segment at 20:22 (count = 0), Skipped
-Segment at 22:21 (count = 0), RegionEntry
-Segment at 22:27 (count = 0), Skipped
-Segment at 26:21 (count = 1), RegionEntry
-Segment at 26:27 (count = 0), Skipped
-Segment at 29:10 (count = 6), RegionEntry
-Segment at 32:10 (count = 0), Skipped
-Segment at 35:5 (count = 0), RegionEntry
-Segment at 35:11 (count = 0), Skipped
-Segment at 36:1 (count = 1), RegionEntry
-Segment at 36:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.yield.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.yield.txt
deleted file mode 100644
index 6ed3e465611..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.yield.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-Counter in file 0 7:1 -> 7:11, #1
-Counter in file 0 8:9 -> 8:22, (#1 + 0)
-Counter in file 0 13:11 -> 14:35, (#1 + 0)
-Counter in file 0 14:39 -> 14:41, #4
-Counter in file 0 15:14 -> 15:52, (#2 + #3)
-Counter in file 0 17:11 -> 17:46, (#4 + 0)
-Counter in file 0 18:34 -> 18:39, (#4 - #5)
-Counter in file 0 18:44 -> 18:46, ((#4 - #5) - #6)
-Counter in file 0 19:14 -> 19:52, (#5 + #6)
-Counter in file 0 22:9 -> 22:22, (((#4 - #5) - #6) + 0)
-Counter in file 0 29:11 -> 30:35, (((#4 - #5) - #6) + 0)
-Counter in file 0 30:39 -> 30:41, #9
-Counter in file 0 31:14 -> 31:52, (#7 + #8)
-Counter in file 0 33:11 -> 34:35, (#9 + 0)
-Counter in file 0 34:39 -> 34:41, #12
-Counter in file 0 35:14 -> 35:52, (#10 + #11)
-Counter in file 0 37:1 -> 37:2, (#12 + 0)
-Counter in file 0 8:28 -> 9:16, #1
-Counter in file 0 10:16 -> 11:6, #2
-Counter in file 0 22:28 -> 23:16, #1
-Counter in file 0 24:9 -> 24:16, #2
-Counter in file 0 25:9 -> 25:16, #3
-Counter in file 0 26:16 -> 27:6, #4
-Emitting segments for file: ../coverage/yield.rs
-Combined regions:
-  7:1 -> 7:11 (count=1)
-  8:9 -> 8:22 (count=1)
-  8:28 -> 9:16 (count=1)
-  10:16 -> 11:6 (count=1)
-  13:11 -> 14:35 (count=1)
-  14:39 -> 14:41 (count=1)
-  15:14 -> 15:52 (count=0)
-  17:11 -> 17:46 (count=1)
-  18:34 -> 18:39 (count=1)
-  18:44 -> 18:46 (count=1)
-  19:14 -> 19:52 (count=0)
-  22:9 -> 22:22 (count=1)
-  22:28 -> 23:16 (count=1)
-  24:9 -> 24:16 (count=1)
-  25:9 -> 25:16 (count=0)
-  26:16 -> 27:6 (count=0)
-  29:11 -> 30:35 (count=1)
-  30:39 -> 30:41 (count=1)
-  31:14 -> 31:52 (count=0)
-  33:11 -> 34:35 (count=1)
-  34:39 -> 34:41 (count=1)
-  35:14 -> 35:52 (count=0)
-  37:1 -> 37:2 (count=1)
-Segment at 7:1 (count = 1), RegionEntry
-Segment at 7:11 (count = 0), Skipped
-Segment at 8:9 (count = 1), RegionEntry
-Segment at 8:22 (count = 0), Skipped
-Segment at 8:28 (count = 1), RegionEntry
-Segment at 9:16 (count = 0), Skipped
-Segment at 10:16 (count = 1), RegionEntry
-Segment at 11:6 (count = 0), Skipped
-Segment at 13:11 (count = 1), RegionEntry
-Segment at 14:35 (count = 0), Skipped
-Segment at 14:39 (count = 1), RegionEntry
-Segment at 14:41 (count = 0), Skipped
-Segment at 15:14 (count = 0), RegionEntry
-Segment at 15:52 (count = 0), Skipped
-Segment at 17:11 (count = 1), RegionEntry
-Segment at 17:46 (count = 0), Skipped
-Segment at 18:34 (count = 1), RegionEntry
-Segment at 18:39 (count = 0), Skipped
-Segment at 18:44 (count = 1), RegionEntry
-Segment at 18:46 (count = 0), Skipped
-Segment at 19:14 (count = 0), RegionEntry
-Segment at 19:52 (count = 0), Skipped
-Segment at 22:9 (count = 1), RegionEntry
-Segment at 22:22 (count = 0), Skipped
-Segment at 22:28 (count = 1), RegionEntry
-Segment at 23:16 (count = 0), Skipped
-Segment at 24:9 (count = 1), RegionEntry
-Segment at 24:16 (count = 0), Skipped
-Segment at 25:9 (count = 0), RegionEntry
-Segment at 25:16 (count = 0), Skipped
-Segment at 26:16 (count = 0), RegionEntry
-Segment at 27:6 (count = 0), Skipped
-Segment at 29:11 (count = 1), RegionEntry
-Segment at 30:35 (count = 0), Skipped
-Segment at 30:39 (count = 1), RegionEntry
-Segment at 30:41 (count = 0), Skipped
-Segment at 31:14 (count = 0), RegionEntry
-Segment at 31:52 (count = 0), Skipped
-Segment at 33:11 (count = 1), RegionEntry
-Segment at 34:35 (count = 0), Skipped
-Segment at 34:39 (count = 1), RegionEntry
-Segment at 34:41 (count = 0), Skipped
-Segment at 35:14 (count = 0), RegionEntry
-Segment at 35:52 (count = 0), Skipped
-Segment at 37:1 (count = 1), RegionEntry
-Segment at 37:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py b/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py
new file mode 100755
index 00000000000..e5777ad2512
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage-reports/normalize_paths.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+
+from __future__ import print_function
+
+import sys
+
+# Normalize file paths in output
+for line in sys.stdin:
+    if line.startswith("..") and line.rstrip().endswith(".rs:"):
+        print(line.replace("\\", "/"), end='')
+    else:
+        print(line, end='')
diff --git a/src/test/run-make-fulldeps/coverage-reports/prettify_json.py b/src/test/run-make-fulldeps/coverage-reports/prettify_json.py
deleted file mode 100644
index ed9279841f7..00000000000
--- a/src/test/run-make-fulldeps/coverage-reports/prettify_json.py
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-import json
-
-# Try to decode line in order to ensure it is a valid JSON document
-for line in sys.stdin:
-    parsed = json.loads(line)
-    print (json.dumps(parsed, indent=2, separators=(',', ': '), sort_keys=True))
diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html
new file mode 100644
index 00000000000..8d074558aae
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html
@@ -0,0 +1,127 @@
+<!DOCTYPE html>
+<!--
+
+Preview this file as rendered HTML from the github source at:
+https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html
+
+For revisions in Pull Requests (PR):
+  * Replace "rust-lang" with the github PR author
+  * Replace "master" with the PR branch name
+
+-->
+<html>
+<head>
+<title>doctest.main - Coverage Spans</title>
+<style>
+    .line {
+        counter-increment: line;
+    }
+    .line:before {
+        content: counter(line) ": ";
+        font-family: Menlo, Monaco, monospace;
+        font-style: italic;
+        width: 3.8em;
+        display: inline-block;
+        text-align: right;
+        filter: opacity(50%);
+        -webkit-user-select: none;
+    }
+    .code {
+        color: #dddddd;
+        background-color: #222222;
+        font-family: Menlo, Monaco, monospace;
+        line-height: 1.4em;
+        border-bottom: 2px solid #222222;
+        white-space: pre;
+        display: inline-block;
+    }
+    .odd {
+        background-color: #55bbff;
+        color: #223311;
+    }
+    .even {
+        background-color: #ee7756;
+        color: #551133;
+    }
+    .code {
+        --index: calc(var(--layer) - 1);
+        padding-top: calc(var(--index) * 0.15em);
+        filter:
+            hue-rotate(calc(var(--index) * 25deg))
+            saturate(calc(100% - (var(--index) * 2%)))
+            brightness(calc(100% - (var(--index) * 1.5%)));
+    }
+    .annotation {
+        color: #4444ff;
+        font-family: monospace;
+        font-style: italic;
+        display: none;
+        -webkit-user-select: none;
+    }
+    body:active .annotation {
+        /* requires holding mouse down anywhere on the page */
+        display: inline-block;
+    }
+    span:hover .annotation {
+        /* requires hover over a span ONLY on its first line */
+        display: inline-block;
+    }
+</style>
+</head>
+<body>
+<div class="code" style="counter-reset: line 59"><span class="line"><span><span class="code even" style="--layer: 1"><span class="annotation">@0⦊</span>fn main() <span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0">{</span></span>
+<span class="line"><span class="code" style="--layer: 0">    if </span><span><span class="code even" style="--layer: 1" title="61:8-61:12: @0[1]: _1 = const true
+61:8-61:12: @0[2]: FakeRead(ForMatchedPlace, _1)"><span class="annotation">@0⦊</span>true<span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0"> {</span></span>
+<span class="line"><span class="code" style="--layer: 0">        </span><span><span class="code odd" style="--layer: 1" title="62:9-62:26: @5[0]: _2 = const ()"><span class="annotation">@5⦊</span></span></span><span class="code even" style="--layer: 2" title="62:9-62:26: @6[5]: _75 = const main::promoted[3]
+62:9-62:26: @6[6]: _18 = &amp;(*_75)
+62:9-62:26: @6[7]: _17 = &amp;(*_18)
+62:9-62:26: @6[8]: _16 = move _17 as &amp;[&amp;str] (Pointer(Unsize))
+62:9-62:26: @6[17]: _26 = &amp;(*_8)
+62:9-62:26: @6[18]: _25 = &amp;_26
+62:9-62:26: @6[21]: _28 = &amp;(*_9)
+62:9-62:26: @6[22]: _27 = &amp;_28
+62:9-62:26: @6[23]: _24 = (move _25, move _27)
+62:9-62:26: @6[26]: FakeRead(ForMatchedPlace, _24)
+62:9-62:26: @6[28]: _29 = (_24.0: &amp;&amp;i32)
+62:9-62:26: @6[30]: _30 = (_24.1: &amp;&amp;i32)
+62:9-62:26: @6[33]: _32 = &amp;(*_29)
+62:9-62:26: @6[35]: _33 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
+62:9-62:26: @6.Call: _31 = ArgumentV1::new::&lt;&amp;i32&gt;(move _32, move _33) -&gt; [return: bb7, unwind: bb17]
+62:9-62:26: @7[4]: _35 = &amp;(*_30)
+62:9-62:26: @7[6]: _36 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
+62:9-62:26: @7.Call: _34 = ArgumentV1::new::&lt;&amp;i32&gt;(move _35, move _36) -&gt; [return: bb8, unwind: bb17]
+62:9-62:26: @8[2]: _23 = [move _31, move _34]
+62:9-62:26: @8[7]: _22 = &amp;_23
+62:9-62:26: @8[8]: _21 = &amp;(*_22)
+62:9-62:26: @8[9]: _20 = move _21 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
+62:9-62:26: @8.Call: _15 = Arguments::new_v1(move _16, move _20) -&gt; [return: bb9, unwind: bb17]
+62:9-62:26: @9.Call: core::panicking::panic_fmt(move _15) -&gt; bb17"><span class="annotation">@4,6,7,8,9⦊</span>assert_eq!(1, 1);<span class="annotation">⦉@4,6,7,8,9</span></span><span><span class="code odd" style="--layer: 1" title="62:9-62:26: @5[0]: _2 = const ()"><span class="annotation">⦉@5</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">    } else {</span></span>
+<span class="line"><span class="code" style="--layer: 0">        </span><span><span class="code even" style="--layer: 1" title="64:9-64:26: @11[0]: _37 = const ()"><span class="annotation">@11⦊</span></span></span><span class="code even" style="--layer: 2" title="64:9-64:26: @12[5]: _72 = const main::promoted[0]
+64:9-64:26: @12[6]: _53 = &amp;(*_72)
+64:9-64:26: @12[7]: _52 = &amp;(*_53)
+64:9-64:26: @12[8]: _51 = move _52 as &amp;[&amp;str] (Pointer(Unsize))
+64:9-64:26: @12[17]: _61 = &amp;(*_43)
+64:9-64:26: @12[18]: _60 = &amp;_61
+64:9-64:26: @12[21]: _63 = &amp;(*_44)
+64:9-64:26: @12[22]: _62 = &amp;_63
+64:9-64:26: @12[23]: _59 = (move _60, move _62)
+64:9-64:26: @12[26]: FakeRead(ForMatchedPlace, _59)
+64:9-64:26: @12[28]: _64 = (_59.0: &amp;&amp;i32)
+64:9-64:26: @12[30]: _65 = (_59.1: &amp;&amp;i32)
+64:9-64:26: @12[33]: _67 = &amp;(*_64)
+64:9-64:26: @12[35]: _68 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
+64:9-64:26: @12.Call: _66 = ArgumentV1::new::&lt;&amp;i32&gt;(move _67, move _68) -&gt; [return: bb13, unwind: bb17]
+64:9-64:26: @13[4]: _70 = &amp;(*_65)
+64:9-64:26: @13[6]: _71 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
+64:9-64:26: @13.Call: _69 = ArgumentV1::new::&lt;&amp;i32&gt;(move _70, move _71) -&gt; [return: bb14, unwind: bb17]
+64:9-64:26: @14[2]: _58 = [move _66, move _69]
+64:9-64:26: @14[7]: _57 = &amp;_58
+64:9-64:26: @14[8]: _56 = &amp;(*_57)
+64:9-64:26: @14[9]: _55 = move _56 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
+64:9-64:26: @14.Call: _50 = Arguments::new_v1(move _51, move _55) -&gt; [return: bb15, unwind: bb17]
+64:9-64:26: @15.Call: core::panicking::panic_fmt(move _50) -&gt; bb17"><span class="annotation">@10,12,13,14,15⦊</span>assert_eq!(1, 2);<span class="annotation">⦉@10,12,13,14,15</span></span><span><span class="code even" style="--layer: 1" title="64:9-64:26: @11[0]: _37 = const ()"><span class="annotation">⦉@11</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">    }</span></span>
+<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="66:2-66:2: @16.Return: return"><span class="annotation">@16⦊</span>‸<span class="annotation">⦉@16</span></span></span></span></div>
+</body>
+</html>
diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html
new file mode 100644
index 00000000000..ae119d9ca9f
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html
@@ -0,0 +1,173 @@
+<!DOCTYPE html>
+<!--
+
+Preview this file as rendered HTML from the github source at:
+https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html
+
+For revisions in Pull Requests (PR):
+  * Replace "rust-lang" with the github PR author
+  * Replace "master" with the PR branch name
+
+-->
+<html>
+<head>
+<title>doctest_crate.fn_run_in_doctests - Coverage Spans</title>
+<style>
+    .line {
+        counter-increment: line;
+    }
+    .line:before {
+        content: counter(line) ": ";
+        font-family: Menlo, Monaco, monospace;
+        font-style: italic;
+        width: 3.8em;
+        display: inline-block;
+        text-align: right;
+        filter: opacity(50%);
+        -webkit-user-select: none;
+    }
+    .code {
+        color: #dddddd;
+        background-color: #222222;
+        font-family: Menlo, Monaco, monospace;
+        line-height: 1.4em;
+        border-bottom: 2px solid #222222;
+        white-space: pre;
+        display: inline-block;
+    }
+    .odd {
+        background-color: #55bbff;
+        color: #223311;
+    }
+    .even {
+        background-color: #ee7756;
+        color: #551133;
+    }
+    .code {
+        --index: calc(var(--layer) - 1);
+        padding-top: calc(var(--index) * 0.15em);
+        filter:
+            hue-rotate(calc(var(--index) * 25deg))
+            saturate(calc(100% - (var(--index) * 2%)))
+            brightness(calc(100% - (var(--index) * 1.5%)));
+    }
+    .annotation {
+        color: #4444ff;
+        font-family: monospace;
+        font-style: italic;
+        display: none;
+        -webkit-user-select: none;
+    }
+    body:active .annotation {
+        /* requires holding mouse down anywhere on the page */
+        display: inline-block;
+    }
+    span:hover .annotation {
+        /* requires hover over a span ONLY on its first line */
+        display: inline-block;
+    }
+</style>
+</head>
+<body>
+<div class="code" style="counter-reset: line 1"><span class="line"><span><span class="code even" style="--layer: 1"><span class="annotation">@0⦊</span>pub fn fn_run_in_doctests(conditional: usize) <span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0">{</span></span>
+<span class="line"><span class="code" style="--layer: 0">    match </span><span><span class="code even" style="--layer: 1" title="3:11-3:22: @0[0]: FakeRead(ForMatchedPlace, _1)"><span class="annotation">@0⦊</span>conditional<span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0"> {</span></span>
+<span class="line"><span class="code" style="--layer: 0">        1 =&gt; </span><span><span class="code odd" style="--layer: 1" title="4:14-4:30: @7[0]: _0 = const ()"><span class="annotation">@7⦊</span></span></span><span class="code even" style="--layer: 2" title="4:14-4:30: @8[5]: _138 = const fn_run_in_doctests::promoted[0]
+4:14-4:30: @8[6]: _17 = &amp;(*_138)
+4:14-4:30: @8[7]: _16 = &amp;(*_17)
+4:14-4:30: @8[8]: _15 = move _16 as &amp;[&amp;str] (Pointer(Unsize))
+4:14-4:30: @8[17]: _25 = &amp;(*_7)
+4:14-4:30: @8[18]: _24 = &amp;_25
+4:14-4:30: @8[21]: _27 = &amp;(*_8)
+4:14-4:30: @8[22]: _26 = &amp;_27
+4:14-4:30: @8[23]: _23 = (move _24, move _26)
+4:14-4:30: @8[26]: FakeRead(ForMatchedPlace, _23)
+4:14-4:30: @8[28]: _28 = (_23.0: &amp;&amp;i32)
+4:14-4:30: @8[30]: _29 = (_23.1: &amp;&amp;i32)
+4:14-4:30: @8[33]: _31 = &amp;(*_28)
+4:14-4:30: @8[35]: _32 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
+4:14-4:30: @8.Call: _30 = ArgumentV1::new::&lt;&amp;i32&gt;(move _31, move _32) -&gt; [return: bb9, unwind: bb33]
+4:14-4:30: @9[4]: _34 = &amp;(*_29)
+4:14-4:30: @9[6]: _35 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
+4:14-4:30: @9.Call: _33 = ArgumentV1::new::&lt;&amp;i32&gt;(move _34, move _35) -&gt; [return: bb10, unwind: bb33]
+4:14-4:30: @10[2]: _22 = [move _30, move _33]
+4:14-4:30: @10[7]: _21 = &amp;_22
+4:14-4:30: @10[8]: _20 = &amp;(*_21)
+4:14-4:30: @10[9]: _19 = move _20 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
+4:14-4:30: @10.Call: _14 = Arguments::new_v1(move _15, move _19) -&gt; [return: bb11, unwind: bb33]
+4:14-4:30: @11.Call: core::panicking::panic_fmt(move _14) -&gt; bb33"><span class="annotation">@6,8,9,10,11⦊</span>assert_eq!(1, 1)<span class="annotation">⦉@6,8,9,10,11</span></span><span><span class="code odd" style="--layer: 1" title="4:14-4:30: @7[0]: _0 = const ()"><span class="annotation">⦉@7</span></span></span><span class="code" style="--layer: 0">, // this is run,</span></span>
+<span class="line"><span class="code" style="--layer: 0">        2 =&gt; </span><span><span class="code even" style="--layer: 1" title="5:14-5:30: @14[0]: _0 = const ()"><span class="annotation">@14⦊</span></span></span><span class="code even" style="--layer: 2" title="5:14-5:30: @15[5]: _141 = const fn_run_in_doctests::promoted[3]
+5:14-5:30: @15[6]: _51 = &amp;(*_141)
+5:14-5:30: @15[7]: _50 = &amp;(*_51)
+5:14-5:30: @15[8]: _49 = move _50 as &amp;[&amp;str] (Pointer(Unsize))
+5:14-5:30: @15[17]: _59 = &amp;(*_41)
+5:14-5:30: @15[18]: _58 = &amp;_59
+5:14-5:30: @15[21]: _61 = &amp;(*_42)
+5:14-5:30: @15[22]: _60 = &amp;_61
+5:14-5:30: @15[23]: _57 = (move _58, move _60)
+5:14-5:30: @15[26]: FakeRead(ForMatchedPlace, _57)
+5:14-5:30: @15[28]: _62 = (_57.0: &amp;&amp;i32)
+5:14-5:30: @15[30]: _63 = (_57.1: &amp;&amp;i32)
+5:14-5:30: @15[33]: _65 = &amp;(*_62)
+5:14-5:30: @15[35]: _66 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
+5:14-5:30: @15.Call: _64 = ArgumentV1::new::&lt;&amp;i32&gt;(move _65, move _66) -&gt; [return: bb16, unwind: bb33]
+5:14-5:30: @16[4]: _68 = &amp;(*_63)
+5:14-5:30: @16[6]: _69 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
+5:14-5:30: @16.Call: _67 = ArgumentV1::new::&lt;&amp;i32&gt;(move _68, move _69) -&gt; [return: bb17, unwind: bb33]
+5:14-5:30: @17[2]: _56 = [move _64, move _67]
+5:14-5:30: @17[7]: _55 = &amp;_56
+5:14-5:30: @17[8]: _54 = &amp;(*_55)
+5:14-5:30: @17[9]: _53 = move _54 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
+5:14-5:30: @17.Call: _48 = Arguments::new_v1(move _49, move _53) -&gt; [return: bb18, unwind: bb33]
+5:14-5:30: @18.Call: core::panicking::panic_fmt(move _48) -&gt; bb33"><span class="annotation">@13,15,16,17,18⦊</span>assert_eq!(1, 1)<span class="annotation">⦉@13,15,16,17,18</span></span><span><span class="code even" style="--layer: 1" title="5:14-5:30: @14[0]: _0 = const ()"><span class="annotation">⦉@14</span></span></span><span class="code" style="--layer: 0">, // this,</span></span>
+<span class="line"><span class="code" style="--layer: 0">        3 =&gt; </span><span><span class="code odd" style="--layer: 1" title="6:14-6:30: @21[0]: _0 = const ()"><span class="annotation">@21⦊</span></span></span><span class="code even" style="--layer: 2" title="6:14-6:30: @22[5]: _144 = const fn_run_in_doctests::promoted[6]
+6:14-6:30: @22[6]: _85 = &amp;(*_144)
+6:14-6:30: @22[7]: _84 = &amp;(*_85)
+6:14-6:30: @22[8]: _83 = move _84 as &amp;[&amp;str] (Pointer(Unsize))
+6:14-6:30: @22[17]: _93 = &amp;(*_75)
+6:14-6:30: @22[18]: _92 = &amp;_93
+6:14-6:30: @22[21]: _95 = &amp;(*_76)
+6:14-6:30: @22[22]: _94 = &amp;_95
+6:14-6:30: @22[23]: _91 = (move _92, move _94)
+6:14-6:30: @22[26]: FakeRead(ForMatchedPlace, _91)
+6:14-6:30: @22[28]: _96 = (_91.0: &amp;&amp;i32)
+6:14-6:30: @22[30]: _97 = (_91.1: &amp;&amp;i32)
+6:14-6:30: @22[33]: _99 = &amp;(*_96)
+6:14-6:30: @22[35]: _100 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
+6:14-6:30: @22.Call: _98 = ArgumentV1::new::&lt;&amp;i32&gt;(move _99, move _100) -&gt; [return: bb23, unwind: bb33]
+6:14-6:30: @23[4]: _102 = &amp;(*_97)
+6:14-6:30: @23[6]: _103 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
+6:14-6:30: @23.Call: _101 = ArgumentV1::new::&lt;&amp;i32&gt;(move _102, move _103) -&gt; [return: bb24, unwind: bb33]
+6:14-6:30: @24[2]: _90 = [move _98, move _101]
+6:14-6:30: @24[7]: _89 = &amp;_90
+6:14-6:30: @24[8]: _88 = &amp;(*_89)
+6:14-6:30: @24[9]: _87 = move _88 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
+6:14-6:30: @24.Call: _82 = Arguments::new_v1(move _83, move _87) -&gt; [return: bb25, unwind: bb33]
+6:14-6:30: @25.Call: core::panicking::panic_fmt(move _82) -&gt; bb33"><span class="annotation">@20,22,23,24,25⦊</span>assert_eq!(1, 1)<span class="annotation">⦉@20,22,23,24,25</span></span><span><span class="code odd" style="--layer: 1" title="6:14-6:30: @21[0]: _0 = const ()"><span class="annotation">⦉@21</span></span></span><span class="code" style="--layer: 0">, // and this too</span></span>
+<span class="line"><span class="code" style="--layer: 0">        _ =&gt; </span><span><span class="code even" style="--layer: 1" title="7:14-7:30: @27[0]: _0 = const ()"><span class="annotation">@27⦊</span></span></span><span class="code even" style="--layer: 2" title="7:14-7:30: @28[5]: _147 = const fn_run_in_doctests::promoted[9]
+7:14-7:30: @28[6]: _119 = &amp;(*_147)
+7:14-7:30: @28[7]: _118 = &amp;(*_119)
+7:14-7:30: @28[8]: _117 = move _118 as &amp;[&amp;str] (Pointer(Unsize))
+7:14-7:30: @28[17]: _127 = &amp;(*_109)
+7:14-7:30: @28[18]: _126 = &amp;_127
+7:14-7:30: @28[21]: _129 = &amp;(*_110)
+7:14-7:30: @28[22]: _128 = &amp;_129
+7:14-7:30: @28[23]: _125 = (move _126, move _128)
+7:14-7:30: @28[26]: FakeRead(ForMatchedPlace, _125)
+7:14-7:30: @28[28]: _130 = (_125.0: &amp;&amp;i32)
+7:14-7:30: @28[30]: _131 = (_125.1: &amp;&amp;i32)
+7:14-7:30: @28[33]: _133 = &amp;(*_130)
+7:14-7:30: @28[35]: _134 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
+7:14-7:30: @28.Call: _132 = ArgumentV1::new::&lt;&amp;i32&gt;(move _133, move _134) -&gt; [return: bb29, unwind: bb33]
+7:14-7:30: @29[4]: _136 = &amp;(*_131)
+7:14-7:30: @29[6]: _137 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
+7:14-7:30: @29.Call: _135 = ArgumentV1::new::&lt;&amp;i32&gt;(move _136, move _137) -&gt; [return: bb30, unwind: bb33]
+7:14-7:30: @30[2]: _124 = [move _132, move _135]
+7:14-7:30: @30[7]: _123 = &amp;_124
+7:14-7:30: @30[8]: _122 = &amp;(*_123)
+7:14-7:30: @30[9]: _121 = move _122 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
+7:14-7:30: @30.Call: _116 = Arguments::new_v1(move _117, move _121) -&gt; [return: bb31, unwind: bb33]
+7:14-7:30: @31.Call: core::panicking::panic_fmt(move _116) -&gt; bb33"><span class="annotation">@26,28,29,30,31⦊</span>assert_eq!(1, 2)<span class="annotation">⦉@26,28,29,30,31</span></span><span><span class="code even" style="--layer: 1" title="7:14-7:30: @27[0]: _0 = const ()"><span class="annotation">⦉@27</span></span></span><span class="code" style="--layer: 0">, // however this is not</span></span>
+<span class="line"><span class="code" style="--layer: 0">    }</span></span>
+<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="9:2-9:2: @32.Return: return"><span class="annotation">@32⦊</span>‸<span class="annotation">⦉@32</span></span></span></span></div>
+</body>
+</html>
diff --git a/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html
new file mode 100644
index 00000000000..133a85c8394
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html
@@ -0,0 +1,271 @@
+<!DOCTYPE html>
+<!--
+
+Preview this file as rendered HTML from the github source at:
+https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.match_or_pattern/match_or_pattern.main.-------.InstrumentCoverage.0.html
+
+For revisions in Pull Requests (PR):
+  * Replace "rust-lang" with the github PR author
+  * Replace "master" with the PR branch name
+
+-->
+<html>
+<head>
+<title>match_or_pattern.main - Coverage Spans</title>
+<style>
+    .line {
+        counter-increment: line;
+    }
+    .line:before {
+        content: counter(line) ": ";
+        font-family: Menlo, Monaco, monospace;
+        font-style: italic;
+        width: 3.8em;
+        display: inline-block;
+        text-align: right;
+        filter: opacity(50%);
+        -webkit-user-select: none;
+    }
+    .code {
+        color: #dddddd;
+        background-color: #222222;
+        font-family: Menlo, Monaco, monospace;
+        line-height: 1.4em;
+        border-bottom: 2px solid #222222;
+        white-space: pre;
+        display: inline-block;
+    }
+    .odd {
+        background-color: #55bbff;
+        color: #223311;
+    }
+    .even {
+        background-color: #ee7756;
+        color: #551133;
+    }
+    .code {
+        --index: calc(var(--layer) - 1);
+        padding-top: calc(var(--index) * 0.15em);
+        filter:
+            hue-rotate(calc(var(--index) * 25deg))
+            saturate(calc(100% - (var(--index) * 2%)))
+            brightness(calc(100% - (var(--index) * 1.5%)));
+    }
+    .annotation {
+        color: #4444ff;
+        font-family: monospace;
+        font-style: italic;
+        display: none;
+        -webkit-user-select: none;
+    }
+    body:active .annotation {
+        /* requires holding mouse down anywhere on the page */
+        display: inline-block;
+    }
+    span:hover .annotation {
+        /* requires hover over a span ONLY on its first line */
+        display: inline-block;
+    }
+</style>
+</head>
+<body>
+<div class="code" style="counter-reset: line 2"><span class="line"><span><span class="code even" style="--layer: 1" title="7:19-7:35: @0.Call: _4 = args() -&gt; [return: bb1, unwind: bb41]
+7:19-7:35: @1[0]: _3 = &amp;_4
+7:19-7:41: @1.Call: _2 = &lt;Args as ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb40]
+7:19-7:46: @2[1]: _1 = Eq(move _2, const 1_usize)
+7:9-7:16: @2[3]: FakeRead(ForLet, _1)
+9:21-9:22: @3[2]: _5 = const 0_u8
+9:9-9:14: @3[3]: FakeRead(ForLet, _5)
+9:16-9:18: @3[4]: AscribeUserType(_5, o, UserTypeProjection { base: UserType(1), projs: [] })
+10:21-10:22: @3[6]: _6 = const 0_u8
+10:9-10:14: @3[7]: FakeRead(ForLet, _6)
+10:16-10:18: @3[8]: AscribeUserType(_6, o, UserTypeProjection { base: UserType(3), projs: [] })
+11:8-11:15: @3[11]: _8 = _1
+11:8-11:15: @3[12]: FakeRead(ForMatchedPlace, _8)"><span class="annotation">@0,1,2,3⦊</span>fn main() {</span></span>
+<span class="line"><span class="code even" style="--layer: 1" title="7:19-7:35: @0.Call: _4 = args() -&gt; [return: bb1, unwind: bb41]
+7:19-7:35: @1[0]: _3 = &amp;_4
+7:19-7:41: @1.Call: _2 = &lt;Args as ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb40]
+7:19-7:46: @2[1]: _1 = Eq(move _2, const 1_usize)
+7:9-7:16: @2[3]: FakeRead(ForLet, _1)
+9:21-9:22: @3[2]: _5 = const 0_u8
+9:9-9:14: @3[3]: FakeRead(ForLet, _5)
+9:16-9:18: @3[4]: AscribeUserType(_5, o, UserTypeProjection { base: UserType(1), projs: [] })
+10:21-10:22: @3[6]: _6 = const 0_u8
+10:9-10:14: @3[7]: FakeRead(ForLet, _6)
+10:16-10:18: @3[8]: AscribeUserType(_6, o, UserTypeProjection { base: UserType(3), projs: [] })
+11:8-11:15: @3[11]: _8 = _1
+11:8-11:15: @3[12]: FakeRead(ForMatchedPlace, _8)">    // Initialize test constants in a way that cannot be determined at compile time, to ensure</span></span>
+<span class="line"><span class="code even" style="--layer: 1" title="7:19-7:35: @0.Call: _4 = args() -&gt; [return: bb1, unwind: bb41]
+7:19-7:35: @1[0]: _3 = &amp;_4
+7:19-7:41: @1.Call: _2 = &lt;Args as ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb40]
+7:19-7:46: @2[1]: _1 = Eq(move _2, const 1_usize)
+7:9-7:16: @2[3]: FakeRead(ForLet, _1)
+9:21-9:22: @3[2]: _5 = const 0_u8
+9:9-9:14: @3[3]: FakeRead(ForLet, _5)
+9:16-9:18: @3[4]: AscribeUserType(_5, o, UserTypeProjection { base: UserType(1), projs: [] })
+10:21-10:22: @3[6]: _6 = const 0_u8
+10:9-10:14: @3[7]: FakeRead(ForLet, _6)
+10:16-10:18: @3[8]: AscribeUserType(_6, o, UserTypeProjection { base: UserType(3), projs: [] })
+11:8-11:15: @3[11]: _8 = _1
+11:8-11:15: @3[12]: FakeRead(ForMatchedPlace, _8)">    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from</span></span>
+<span class="line"><span class="code even" style="--layer: 1" title="7:19-7:35: @0.Call: _4 = args() -&gt; [return: bb1, unwind: bb41]
+7:19-7:35: @1[0]: _3 = &amp;_4
+7:19-7:41: @1.Call: _2 = &lt;Args as ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb40]
+7:19-7:46: @2[1]: _1 = Eq(move _2, const 1_usize)
+7:9-7:16: @2[3]: FakeRead(ForLet, _1)
+9:21-9:22: @3[2]: _5 = const 0_u8
+9:9-9:14: @3[3]: FakeRead(ForLet, _5)
+9:16-9:18: @3[4]: AscribeUserType(_5, o, UserTypeProjection { base: UserType(1), projs: [] })
+10:21-10:22: @3[6]: _6 = const 0_u8
+10:9-10:14: @3[7]: FakeRead(ForLet, _6)
+10:16-10:18: @3[8]: AscribeUserType(_6, o, UserTypeProjection { base: UserType(3), projs: [] })
+11:8-11:15: @3[11]: _8 = _1
+11:8-11:15: @3[12]: FakeRead(ForMatchedPlace, _8)">    // dependent conditions.</span></span>
+<span class="line"><span class="code even" style="--layer: 1" title="7:19-7:35: @0.Call: _4 = args() -&gt; [return: bb1, unwind: bb41]
+7:19-7:35: @1[0]: _3 = &amp;_4
+7:19-7:41: @1.Call: _2 = &lt;Args as ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb40]
+7:19-7:46: @2[1]: _1 = Eq(move _2, const 1_usize)
+7:9-7:16: @2[3]: FakeRead(ForLet, _1)
+9:21-9:22: @3[2]: _5 = const 0_u8
+9:9-9:14: @3[3]: FakeRead(ForLet, _5)
+9:16-9:18: @3[4]: AscribeUserType(_5, o, UserTypeProjection { base: UserType(1), projs: [] })
+10:21-10:22: @3[6]: _6 = const 0_u8
+10:9-10:14: @3[7]: FakeRead(ForLet, _6)
+10:16-10:18: @3[8]: AscribeUserType(_6, o, UserTypeProjection { base: UserType(3), projs: [] })
+11:8-11:15: @3[11]: _8 = _1
+11:8-11:15: @3[12]: FakeRead(ForMatchedPlace, _8)">    let is_true = std::env::args().len() == 1;</span></span>
+<span class="line"><span class="code even" style="--layer: 1" title="7:19-7:35: @0.Call: _4 = args() -&gt; [return: bb1, unwind: bb41]
+7:19-7:35: @1[0]: _3 = &amp;_4
+7:19-7:41: @1.Call: _2 = &lt;Args as ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb40]
+7:19-7:46: @2[1]: _1 = Eq(move _2, const 1_usize)
+7:9-7:16: @2[3]: FakeRead(ForLet, _1)
+9:21-9:22: @3[2]: _5 = const 0_u8
+9:9-9:14: @3[3]: FakeRead(ForLet, _5)
+9:16-9:18: @3[4]: AscribeUserType(_5, o, UserTypeProjection { base: UserType(1), projs: [] })
+10:21-10:22: @3[6]: _6 = const 0_u8
+10:9-10:14: @3[7]: FakeRead(ForLet, _6)
+10:16-10:18: @3[8]: AscribeUserType(_6, o, UserTypeProjection { base: UserType(3), projs: [] })
+11:8-11:15: @3[11]: _8 = _1
+11:8-11:15: @3[12]: FakeRead(ForMatchedPlace, _8)"></span></span>
+<span class="line"><span class="code even" style="--layer: 1" title="7:19-7:35: @0.Call: _4 = args() -&gt; [return: bb1, unwind: bb41]
+7:19-7:35: @1[0]: _3 = &amp;_4
+7:19-7:41: @1.Call: _2 = &lt;Args as ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb40]
+7:19-7:46: @2[1]: _1 = Eq(move _2, const 1_usize)
+7:9-7:16: @2[3]: FakeRead(ForLet, _1)
+9:21-9:22: @3[2]: _5 = const 0_u8
+9:9-9:14: @3[3]: FakeRead(ForLet, _5)
+9:16-9:18: @3[4]: AscribeUserType(_5, o, UserTypeProjection { base: UserType(1), projs: [] })
+10:21-10:22: @3[6]: _6 = const 0_u8
+10:9-10:14: @3[7]: FakeRead(ForLet, _6)
+10:16-10:18: @3[8]: AscribeUserType(_6, o, UserTypeProjection { base: UserType(3), projs: [] })
+11:8-11:15: @3[11]: _8 = _1
+11:8-11:15: @3[12]: FakeRead(ForMatchedPlace, _8)">    let mut a: u8 = 0;</span></span>
+<span class="line"><span class="code even" style="--layer: 1" title="7:19-7:35: @0.Call: _4 = args() -&gt; [return: bb1, unwind: bb41]
+7:19-7:35: @1[0]: _3 = &amp;_4
+7:19-7:41: @1.Call: _2 = &lt;Args as ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb40]
+7:19-7:46: @2[1]: _1 = Eq(move _2, const 1_usize)
+7:9-7:16: @2[3]: FakeRead(ForLet, _1)
+9:21-9:22: @3[2]: _5 = const 0_u8
+9:9-9:14: @3[3]: FakeRead(ForLet, _5)
+9:16-9:18: @3[4]: AscribeUserType(_5, o, UserTypeProjection { base: UserType(1), projs: [] })
+10:21-10:22: @3[6]: _6 = const 0_u8
+10:9-10:14: @3[7]: FakeRead(ForLet, _6)
+10:16-10:18: @3[8]: AscribeUserType(_6, o, UserTypeProjection { base: UserType(3), projs: [] })
+11:8-11:15: @3[11]: _8 = _1
+11:8-11:15: @3[12]: FakeRead(ForMatchedPlace, _8)">    let mut b: u8 = 0;</span></span>
+<span class="line"><span class="code even" style="--layer: 1" title="7:19-7:35: @0.Call: _4 = args() -&gt; [return: bb1, unwind: bb41]
+7:19-7:35: @1[0]: _3 = &amp;_4
+7:19-7:41: @1.Call: _2 = &lt;Args as ExactSizeIterator&gt;::len(move _3) -&gt; [return: bb2, unwind: bb40]
+7:19-7:46: @2[1]: _1 = Eq(move _2, const 1_usize)
+7:9-7:16: @2[3]: FakeRead(ForLet, _1)
+9:21-9:22: @3[2]: _5 = const 0_u8
+9:9-9:14: @3[3]: FakeRead(ForLet, _5)
+9:16-9:18: @3[4]: AscribeUserType(_5, o, UserTypeProjection { base: UserType(1), projs: [] })
+10:21-10:22: @3[6]: _6 = const 0_u8
+10:9-10:14: @3[7]: FakeRead(ForLet, _6)
+10:16-10:18: @3[8]: AscribeUserType(_6, o, UserTypeProjection { base: UserType(3), projs: [] })
+11:8-11:15: @3[11]: _8 = _1
+11:8-11:15: @3[12]: FakeRead(ForMatchedPlace, _8)">    if is_true<span class="annotation">⦉@0,1,2,3</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="12:9-12:14: @6[0]: _5 = const 2_u8
+13:9-13:14: @6[1]: _6 = const 0_u8
+11:16-14:6: @6[2]: _7 = const ()"><span class="annotation">@4,6⦊</span>{</span></span>
+<span class="line"><span class="code odd" style="--layer: 1" title="12:9-12:14: @6[0]: _5 = const 2_u8
+13:9-13:14: @6[1]: _6 = const 0_u8
+11:16-14:6: @6[2]: _7 = const ()">        a = 2;</span></span>
+<span class="line"><span class="code odd" style="--layer: 1" title="12:9-12:14: @6[0]: _5 = const 2_u8
+13:9-13:14: @6[1]: _6 = const 0_u8
+11:16-14:6: @6[2]: _7 = const ()">        b = 0;</span></span>
+<span class="line"><span class="code odd" style="--layer: 1" title="12:9-12:14: @6[0]: _5 = const 2_u8
+13:9-13:14: @6[1]: _6 = const 0_u8
+11:16-14:6: @6[2]: _7 = const ()">    }<span class="annotation">⦉@4,6</span></span></span><span><span class="code even" style="--layer: 1" title="14:6-14:6: @5[0]: _7 = const ()"><span class="annotation">@5⦊</span>‸<span class="annotation">⦉@5</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">    match </span><span><span class="code odd" style="--layer: 1" title="15:12-15:13: @7[5]: _11 = _5
+15:15-15:16: @7[7]: _12 = _6
+15:11-15:17: @7[8]: _10 = (move _11, move _12)
+15:11-15:17: @7[11]: FakeRead(ForMatchedPlace, _10)"><span class="annotation">@7⦊</span>(a, b)<span class="annotation">⦉@7</span></span></span><span class="code" style="--layer: 0"> {</span></span>
+<span class="line"><span class="code" style="--layer: 0">        // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`.</span></span>
+<span class="line"><span class="code" style="--layer: 0">        // This test confirms a fix for Issue #79569.</span></span>
+<span class="line"><span class="code" style="--layer: 0">        (0 | 1, 2 | 3) =&gt; </span><span><span class="code even" style="--layer: 1" title="18:27-18:29: @11[0]: _9 = const ()"><span class="annotation">@10,11⦊</span>{}<span class="annotation">⦉@10,11</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">        _ =&gt; </span><span><span class="code odd" style="--layer: 1" title="19:14-19:16: @8[0]: _9 = const ()"><span class="annotation">@8⦊</span>{}<span class="annotation">⦉@8</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">    }</span></span>
+<span class="line"><span class="code" style="--layer: 0">    if </span><span><span class="code even" style="--layer: 1" title="21:8-21:15: @12[4]: _14 = _1
+21:8-21:15: @12[5]: FakeRead(ForMatchedPlace, _14)"><span class="annotation">@12⦊</span>is_true<span class="annotation">⦉@12</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="22:9-22:14: @15[0]: _5 = const 0_u8
+23:9-23:14: @15[1]: _6 = const 0_u8
+21:16-24:6: @15[2]: _13 = const ()"><span class="annotation">@13,15⦊</span>{</span></span>
+<span class="line"><span class="code odd" style="--layer: 1" title="22:9-22:14: @15[0]: _5 = const 0_u8
+23:9-23:14: @15[1]: _6 = const 0_u8
+21:16-24:6: @15[2]: _13 = const ()">        a = 0;</span></span>
+<span class="line"><span class="code odd" style="--layer: 1" title="22:9-22:14: @15[0]: _5 = const 0_u8
+23:9-23:14: @15[1]: _6 = const 0_u8
+21:16-24:6: @15[2]: _13 = const ()">        b = 0;</span></span>
+<span class="line"><span class="code odd" style="--layer: 1" title="22:9-22:14: @15[0]: _5 = const 0_u8
+23:9-23:14: @15[1]: _6 = const 0_u8
+21:16-24:6: @15[2]: _13 = const ()">    }<span class="annotation">⦉@13,15</span></span></span><span><span class="code even" style="--layer: 1" title="24:6-24:6: @14[0]: _13 = const ()"><span class="annotation">@14⦊</span>‸<span class="annotation">⦉@14</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">    match </span><span><span class="code odd" style="--layer: 1" title="25:12-25:13: @16[5]: _17 = _5
+25:15-25:16: @16[7]: _18 = _6
+25:11-25:17: @16[8]: _16 = (move _17, move _18)
+25:11-25:17: @16[11]: FakeRead(ForMatchedPlace, _16)"><span class="annotation">@16⦊</span>(a, b)<span class="annotation">⦉@16</span></span></span><span class="code" style="--layer: 0"> {</span></span>
+<span class="line"><span class="code" style="--layer: 0">        (0 | 1, 2 | 3) =&gt; </span><span><span class="code even" style="--layer: 1" title="26:27-26:29: @20[0]: _15 = const ()"><span class="annotation">@19,20⦊</span>{}<span class="annotation">⦉@19,20</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">        _ =&gt; </span><span><span class="code odd" style="--layer: 1" title="27:14-27:16: @17[0]: _15 = const ()"><span class="annotation">@17⦊</span>{}<span class="annotation">⦉@17</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">    }</span></span>
+<span class="line"><span class="code" style="--layer: 0">    if </span><span><span class="code even" style="--layer: 1" title="29:8-29:15: @21[4]: _20 = _1
+29:8-29:15: @21[5]: FakeRead(ForMatchedPlace, _20)"><span class="annotation">@21⦊</span>is_true<span class="annotation">⦉@21</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="30:9-30:14: @24[0]: _5 = const 2_u8
+31:9-31:14: @24[1]: _6 = const 2_u8
+29:16-32:6: @24[2]: _19 = const ()"><span class="annotation">@22,24⦊</span>{</span></span>
+<span class="line"><span class="code odd" style="--layer: 1" title="30:9-30:14: @24[0]: _5 = const 2_u8
+31:9-31:14: @24[1]: _6 = const 2_u8
+29:16-32:6: @24[2]: _19 = const ()">        a = 2;</span></span>
+<span class="line"><span class="code odd" style="--layer: 1" title="30:9-30:14: @24[0]: _5 = const 2_u8
+31:9-31:14: @24[1]: _6 = const 2_u8
+29:16-32:6: @24[2]: _19 = const ()">        b = 2;</span></span>
+<span class="line"><span class="code odd" style="--layer: 1" title="30:9-30:14: @24[0]: _5 = const 2_u8
+31:9-31:14: @24[1]: _6 = const 2_u8
+29:16-32:6: @24[2]: _19 = const ()">    }<span class="annotation">⦉@22,24</span></span></span><span><span class="code even" style="--layer: 1" title="32:6-32:6: @23[0]: _19 = const ()"><span class="annotation">@23⦊</span>‸<span class="annotation">⦉@23</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">    match </span><span><span class="code odd" style="--layer: 1" title="33:12-33:13: @25[5]: _23 = _5
+33:15-33:16: @25[7]: _24 = _6
+33:11-33:17: @25[8]: _22 = (move _23, move _24)
+33:11-33:17: @25[11]: FakeRead(ForMatchedPlace, _22)"><span class="annotation">@25⦊</span>(a, b)<span class="annotation">⦉@25</span></span></span><span class="code" style="--layer: 0"> {</span></span>
+<span class="line"><span class="code" style="--layer: 0">        (0 | 1, 2 | 3) =&gt; </span><span><span class="code even" style="--layer: 1" title="34:27-34:29: @29[0]: _21 = const ()"><span class="annotation">@28,29⦊</span>{}<span class="annotation">⦉@28,29</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">        _ =&gt; </span><span><span class="code odd" style="--layer: 1" title="35:14-35:16: @26[0]: _21 = const ()"><span class="annotation">@26⦊</span>{}<span class="annotation">⦉@26</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">    }</span></span>
+<span class="line"><span class="code" style="--layer: 0">    if </span><span><span class="code even" style="--layer: 1" title="37:8-37:15: @30[4]: _26 = _1
+37:8-37:15: @30[5]: FakeRead(ForMatchedPlace, _26)"><span class="annotation">@30⦊</span>is_true<span class="annotation">⦉@30</span></span></span><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="38:9-38:14: @33[0]: _5 = const 0_u8
+39:9-39:14: @33[1]: _6 = const 2_u8
+37:16-40:6: @33[2]: _25 = const ()"><span class="annotation">@31,33⦊</span>{</span></span>
+<span class="line"><span class="code odd" style="--layer: 1" title="38:9-38:14: @33[0]: _5 = const 0_u8
+39:9-39:14: @33[1]: _6 = const 2_u8
+37:16-40:6: @33[2]: _25 = const ()">        a = 0;</span></span>
+<span class="line"><span class="code odd" style="--layer: 1" title="38:9-38:14: @33[0]: _5 = const 0_u8
+39:9-39:14: @33[1]: _6 = const 2_u8
+37:16-40:6: @33[2]: _25 = const ()">        b = 2;</span></span>
+<span class="line"><span class="code odd" style="--layer: 1" title="38:9-38:14: @33[0]: _5 = const 0_u8
+39:9-39:14: @33[1]: _6 = const 2_u8
+37:16-40:6: @33[2]: _25 = const ()">    }<span class="annotation">⦉@31,33</span></span></span><span><span class="code even" style="--layer: 1" title="40:6-40:6: @32[0]: _25 = const ()"><span class="annotation">@32⦊</span>‸<span class="annotation">⦉@32</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">    match </span><span><span class="code odd" style="--layer: 1" title="41:12-41:13: @34[4]: _28 = _5
+41:15-41:16: @34[6]: _29 = _6
+41:11-41:17: @34[7]: _27 = (move _28, move _29)
+41:11-41:17: @34[10]: FakeRead(ForMatchedPlace, _27)"><span class="annotation">@34⦊</span>(a, b)<span class="annotation">⦉@34</span></span></span><span class="code" style="--layer: 0"> {</span></span>
+<span class="line"><span class="code" style="--layer: 0">        (0 | 1, 2 | 3) =&gt; </span><span><span class="code even" style="--layer: 1" title="42:27-42:29: @38[0]: _0 = const ()"><span class="annotation">@37,38⦊</span>{}<span class="annotation">⦉@37,38</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">        _ =&gt; </span><span><span class="code odd" style="--layer: 1" title="43:14-43:16: @35[0]: _0 = const ()"><span class="annotation">@35⦊</span>{}<span class="annotation">⦉@35</span></span></span><span class="code" style="--layer: 0"></span></span>
+<span class="line"><span class="code" style="--layer: 0">    }</span></span>
+<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code even" style="--layer: 1" title="45:2-45:2: @39.Return: return"><span class="annotation">@39⦊</span>‸<span class="annotation">⦉@39</span></span></span></span></div>
+</body>
+</html>
diff --git a/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir b/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir
index abf8df8fdc9..d1824d189e3 100644
--- a/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir
+++ b/src/test/run-make-fulldeps/coverage/compiletest-ignore-dir
@@ -1,3 +1,3 @@
-# Directory "instrument-coverage" supports the tests at prefix ../instrument-coverage-*
+# Directory "coverage" supports the tests at prefix ../coverage-*
 
-# Use ./x.py [options] test src/test/run-make-fulldeps/instrument-coverage to run all related tests.
+# Use ./x.py [options] test src/test/run-make-fulldeps/coverage to run all related tests.
diff --git a/src/test/run-make-fulldeps/coverage/coverage_tools.mk b/src/test/run-make-fulldeps/coverage/coverage_tools.mk
index 7dc485cd94d..4d340d4b1da 100644
--- a/src/test/run-make-fulldeps/coverage/coverage_tools.mk
+++ b/src/test/run-make-fulldeps/coverage/coverage_tools.mk
@@ -1,7 +1,7 @@
-# Common Makefile include for Rust `run-make-fulldeps/instrument-coverage-* tests. Include this
+# Common Makefile include for Rust `run-make-fulldeps/coverage-* tests. Include this
 # file with the line:
 #
-# -include ../instrument-coverage/coverage_tools.mk
+# -include ../coverage/coverage_tools.mk
 
 -include ../tools.mk
 
diff --git a/src/test/run-make-fulldeps/coverage/doctest.rs b/src/test/run-make-fulldeps/coverage/doctest.rs
new file mode 100644
index 00000000000..e41d669bf0c
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage/doctest.rs
@@ -0,0 +1,66 @@
+//! This test ensures that code from doctests is properly re-mapped.
+//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
+//!
+//! Just some random code:
+//! ```
+//! if true {
+//!     // this is executed!
+//!     assert_eq!(1, 1);
+//! } else {
+//!     // this is not!
+//!     assert_eq!(1, 2);
+//! }
+//! ```
+//!
+//! doctest testing external code:
+//! ```
+//! extern crate doctest_crate;
+//! doctest_crate::fn_run_in_doctests(1);
+//! ```
+//!
+//! doctest returning a result:
+//! ```
+//! #[derive(Debug)]
+//! struct SomeError;
+//! let mut res = Err(SomeError);
+//! if res.is_ok() {
+//!   res?;
+//! } else {
+//!   res = Ok(0);
+//! }
+//! // need to be explicit because rustdoc cant infer the return type
+//! Ok::<(), SomeError>(())
+//! ```
+//!
+//! doctest with custom main:
+//! ```
+//! #[derive(Debug)]
+//! struct SomeError;
+//!
+//! extern crate doctest_crate;
+//!
+//! fn doctest_main() -> Result<(), SomeError> {
+//!     doctest_crate::fn_run_in_doctests(2);
+//!     Ok(())
+//! }
+//!
+//! // this `main` is not shown as covered, as it clashes with all the other
+//! // `main` functions that were automatically generated for doctests
+//! fn main() -> Result<(), SomeError> {
+//!     doctest_main()
+//! }
+//! ```
+
+/// doctest attached to fn testing external code:
+/// ```
+/// extern crate doctest_crate;
+/// doctest_crate::fn_run_in_doctests(3);
+/// ```
+///
+fn main() {
+    if true {
+        assert_eq!(1, 1);
+    } else {
+        assert_eq!(1, 2);
+    }
+}
diff --git a/src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs b/src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs
new file mode 100644
index 00000000000..c3210146d69
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs
@@ -0,0 +1,9 @@
+/// A function run only from within doctests
+pub fn fn_run_in_doctests(conditional: usize) {
+    match conditional {
+        1 => assert_eq!(1, 1), // this is run,
+        2 => assert_eq!(1, 1), // this,
+        3 => assert_eq!(1, 1), // and this too
+        _ => assert_eq!(1, 2), // however this is not
+    }
+}
diff --git a/src/test/run-make-fulldeps/coverage/match_or_pattern.rs b/src/test/run-make-fulldeps/coverage/match_or_pattern.rs
new file mode 100644
index 00000000000..4c6a8a9b703
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage/match_or_pattern.rs
@@ -0,0 +1,45 @@
+#![feature(or_patterns)]
+
+fn main() {
+    // Initialize test constants in a way that cannot be determined at compile time, to ensure
+    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
+    // dependent conditions.
+    let is_true = std::env::args().len() == 1;
+
+    let mut a: u8 = 0;
+    let mut b: u8 = 0;
+    if is_true {
+        a = 2;
+        b = 0;
+    }
+    match (a, b) {
+        // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`.
+        // This test confirms a fix for Issue #79569.
+        (0 | 1, 2 | 3) => {}
+        _ => {}
+    }
+    if is_true {
+        a = 0;
+        b = 0;
+    }
+    match (a, b) {
+        (0 | 1, 2 | 3) => {}
+        _ => {}
+    }
+    if is_true {
+        a = 2;
+        b = 2;
+    }
+    match (a, b) {
+        (0 | 1, 2 | 3) => {}
+        _ => {}
+    }
+    if is_true {
+        a = 0;
+        b = 2;
+    }
+    match (a, b) {
+        (0 | 1, 2 | 3) => {}
+        _ => {}
+    }
+}
diff --git a/src/test/run-make-fulldeps/many-crates-but-no-match/Makefile b/src/test/run-make-fulldeps/many-crates-but-no-match/Makefile
index 03a797d95f9..e7268311b13 100644
--- a/src/test/run-make-fulldeps/many-crates-but-no-match/Makefile
+++ b/src/test/run-make-fulldeps/many-crates-but-no-match/Makefile
@@ -1,9 +1,8 @@
 -include ../tools.mk
 
-# Modelled after compile-fail/changing-crates test, but this one puts
+# Modelled after ui/changing-crates.rs test, but this one puts
 # more than one (mismatching) candidate crate into the search path,
-# which did not appear directly expressible in compile-fail/aux-build
-# infrastructure.
+# which did not appear directly expressible in UI testing infrastructure.
 #
 # Note that we move the built libraries into target direcrtories rather than
 # use the `--out-dir` option because the `../tools.mk` file already bakes a
@@ -33,4 +32,4 @@ all:
 		'crate `crateA`:' \
 		'crate `crateB`:' \
 		< $(LOG)
-	# the 'crate `crateA`' will match two entries.
\ No newline at end of file
+	# the 'crate `crateA`' will match two entries.
diff --git a/src/test/run-make-fulldeps/separate-link/Makefile b/src/test/run-make-fulldeps/separate-link/Makefile
new file mode 100644
index 00000000000..060484e89f9
--- /dev/null
+++ b/src/test/run-make-fulldeps/separate-link/Makefile
@@ -0,0 +1,6 @@
+-include ../tools.mk
+
+all:
+	echo 'fn main(){}' | $(RUSTC) -Z no-link -
+	$(RUSTC) -Z link-only $(TMPDIR)/rust_out.rlink
+	$(call RUN,rust_out)
diff --git a/src/test/run-make-fulldeps/split-dwarf/Makefile b/src/test/run-make-fulldeps/split-dwarf/Makefile
new file mode 100644
index 00000000000..e1a78e2edfc
--- /dev/null
+++ b/src/test/run-make-fulldeps/split-dwarf/Makefile
@@ -0,0 +1,8 @@
+-include ../tools.mk
+
+# only-linux
+
+all:
+	$(RUSTC) -Z split-dwarf=split foo.rs
+	rm $(TMPDIR)/foo.dwp
+	rm $(TMPDIR)/$(call BIN,foo)
diff --git a/src/test/run-make-fulldeps/split-dwarf/foo.rs b/src/test/run-make-fulldeps/split-dwarf/foo.rs
new file mode 100644
index 00000000000..f328e4d9d04
--- /dev/null
+++ b/src/test/run-make-fulldeps/split-dwarf/foo.rs
@@ -0,0 +1 @@
+fn main() {}
diff --git a/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs
index 12898aa5c74..71b38a9f8ca 100644
--- a/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs
+++ b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs
@@ -5,7 +5,7 @@
 // causing a type mismatch.
 
 // The test is nearly the same as the one in
-// compile-fail/type-mismatch-same-crate-name.rs
+// ui/type/type-mismatch-same-crate-name.rs
 // but deals with the case where one of the crates
 // is only introduced as an indirect dependency.
 // and the type is accessed via a re-export.
diff --git a/src/test/rustdoc-ui/auxiliary/issue-61592.rs b/src/test/rustdoc-ui/auxiliary/issue-61592.rs
new file mode 100644
index 00000000000..57a365b3f38
--- /dev/null
+++ b/src/test/rustdoc-ui/auxiliary/issue-61592.rs
@@ -0,0 +1,3 @@
+#![crate_name = "foo"]
+
+pub trait Foo {}
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/const-generics.rs b/src/test/rustdoc-ui/error-in-impl-trait/const-generics.rs
index 97760cbf8fb..ed62f0208aa 100644
--- a/src/test/rustdoc-ui/error-in-impl-trait/const-generics.rs
+++ b/src/test/rustdoc-ui/error-in-impl-trait/const-generics.rs
@@ -1,6 +1,5 @@
 // check-pass
 // edition:2018
-#![feature(min_const_generics)]
 trait ValidTrait {}
 
 /// This has docs
diff --git a/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs b/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs
new file mode 100644
index 00000000000..114502b0ddf
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-doc/non-path-primitives.rs
@@ -0,0 +1,34 @@
+#![deny(broken_intra_doc_links)]
+// These are links that could reasonably expected to work, but don't.
+
+// `[]` isn't supported because it had too many false positives.
+//! [X]([T]::not_here)
+//! [Y](&[]::not_here)
+//! [X]([]::not_here)
+//! [Y]([T;N]::not_here)
+
+// These don't work because markdown syntax doesn't allow it.
+//! [[T]::rotate_left] //~ ERROR unresolved link to `T`
+//! [&[]::not_here]
+//![Z]([T; N]::map) //~ ERROR unresolved link to `Z`
+//! [`[T; N]::map`]
+//! [[]::map]
+//! [Z][] //~ ERROR unresolved link to `Z`
+//!
+//! [Z]: [T; N]::map //~ ERROR unresolved link to `Z`
+
+// `()` isn't supported because it had too many false positives.
+//! [()::not_here]
+//! [X]((,)::not_here)
+//! [(,)::not_here]
+
+// FIXME: Associated items on some primitives aren't working, because the impls
+// are part of the compiler instead of being part of the source code.
+//! [unit::eq] //~ ERROR unresolved
+//! [tuple::eq] //~ ERROR unresolved
+//! [fn::eq] //~ ERROR unresolved
+//! [never::eq] //~ ERROR unresolved
+
+// FIXME(#78800): This breaks because it's a blanket impl
+// (I think? Might break for other reasons too.)
+//! [reference::deref] //~ ERROR unresolved
diff --git a/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr
new file mode 100644
index 00000000000..ea831e648f6
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr
@@ -0,0 +1,69 @@
+error: unresolved link to `T`
+  --> $DIR/non-path-primitives.rs:11:7
+   |
+LL | //! [[T]::rotate_left]
+   |       ^ no item named `T` in scope
+   |
+note: the lint level is defined here
+  --> $DIR/non-path-primitives.rs:1:9
+   |
+LL | #![deny(broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+error: unresolved link to `Z`
+  --> $DIR/non-path-primitives.rs:13:5
+   |
+LL | //![Z]([T; N]::map)
+   |     ^ no item named `Z` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+error: unresolved link to `Z`
+  --> $DIR/non-path-primitives.rs:16:6
+   |
+LL | //! [Z][]
+   |      ^ no item named `Z` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+error: unresolved link to `Z`
+  --> $DIR/non-path-primitives.rs:18:6
+   |
+LL | //! [Z]: [T; N]::map
+   |      ^ no item named `Z` in scope
+   |
+   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
+
+error: unresolved link to `unit::eq`
+  --> $DIR/non-path-primitives.rs:27:6
+   |
+LL | //! [unit::eq]
+   |      ^^^^^^^^ the builtin type `unit` has no associated item named `eq`
+
+error: unresolved link to `tuple::eq`
+  --> $DIR/non-path-primitives.rs:28:6
+   |
+LL | //! [tuple::eq]
+   |      ^^^^^^^^^ the builtin type `tuple` has no associated item named `eq`
+
+error: unresolved link to `fn::eq`
+  --> $DIR/non-path-primitives.rs:29:6
+   |
+LL | //! [fn::eq]
+   |      ^^^^^^ the builtin type `fn` has no associated item named `eq`
+
+error: unresolved link to `never::eq`
+  --> $DIR/non-path-primitives.rs:30:6
+   |
+LL | //! [never::eq]
+   |      ^^^^^^^^^ the builtin type `never` has no associated item named `eq`
+
+error: unresolved link to `reference::deref`
+  --> $DIR/non-path-primitives.rs:34:6
+   |
+LL | //! [reference::deref]
+   |      ^^^^^^^^^^^^^^^^ the builtin type `reference` has no associated item named `deref`
+
+error: aborting due to 9 previous errors
+
diff --git a/src/test/rustdoc-ui/issue-61592-2.rs b/src/test/rustdoc-ui/issue-61592-2.rs
new file mode 100644
index 00000000000..5b4fc5ee700
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-61592-2.rs
@@ -0,0 +1,10 @@
+// aux-build:issue-61592.rs
+
+extern crate foo;
+
+#[doc = "bar"]
+#[doc(inline)] //~ ERROR
+#[doc = "baz"]
+pub use foo::Foo as _;
+
+fn main() {}
diff --git a/src/test/rustdoc-ui/issue-61592-2.stderr b/src/test/rustdoc-ui/issue-61592-2.stderr
new file mode 100644
index 00000000000..1b7f8bb552c
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-61592-2.stderr
@@ -0,0 +1,12 @@
+error[E0780]: anonymous imports cannot be inlined
+  --> $DIR/issue-61592-2.rs:6:7
+   |
+LL | #[doc(inline)]
+   |       ^^^^^^
+LL | #[doc = "baz"]
+LL | pub use foo::Foo as _;
+   | ---------------------- anonymous import
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0780`.
diff --git a/src/test/rustdoc-ui/issue-61592.rs b/src/test/rustdoc-ui/issue-61592.rs
new file mode 100644
index 00000000000..66772557f2c
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-61592.rs
@@ -0,0 +1,8 @@
+// aux-build:issue-61592.rs
+
+extern crate foo;
+
+#[doc(inline)] //~ ERROR
+pub use foo::Foo as _;
+
+fn main() {}
diff --git a/src/test/rustdoc-ui/issue-61592.stderr b/src/test/rustdoc-ui/issue-61592.stderr
new file mode 100644
index 00000000000..9c9c9106f8a
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-61592.stderr
@@ -0,0 +1,11 @@
+error[E0780]: anonymous imports cannot be inlined
+  --> $DIR/issue-61592.rs:5:7
+   |
+LL | #[doc(inline)]
+   |       ^^^^^^
+LL | pub use foo::Foo as _;
+   | ---------------------- anonymous import
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0780`.
diff --git a/src/test/rustdoc-ui/reference-link-has-one-warning.rs b/src/test/rustdoc-ui/reference-link-has-one-warning.rs
deleted file mode 100644
index 21cb7eb9040..00000000000
--- a/src/test/rustdoc-ui/reference-link-has-one-warning.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-// ignore-test
-// check-pass
-
-/// docs [label][with#anchor#error]
-//~^ WARNING has an issue with the link anchor
-pub struct S;
diff --git a/src/test/rustdoc-ui/reference-link-has-one-warning.stderr b/src/test/rustdoc-ui/reference-link-has-one-warning.stderr
deleted file mode 100644
index a1eeb60f178..00000000000
--- a/src/test/rustdoc-ui/reference-link-has-one-warning.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-warning: `[with#anchor#error]` has an issue with the link anchor.
-  --> $DIR/reference-link-has-one-warning.rs:3:18
-   |
-LL | /// docs [label][with#anchor#error]
-   |                  ^^^^^^^^^^^^^^^^^ only one `#` is allowed in a link
-   |
-   = note: `#[warn(broken_intra_doc_links)]` on by default
-
-warning: 1 warning emitted
-
diff --git a/src/test/rustdoc-ui/reference-links.rs b/src/test/rustdoc-ui/reference-links.rs
new file mode 100644
index 00000000000..7c1a79722c9
--- /dev/null
+++ b/src/test/rustdoc-ui/reference-links.rs
@@ -0,0 +1,7 @@
+// Test that errors point to the reference, not to the title text.
+#![deny(broken_intra_doc_links)]
+//! Links to [a] [link][a]
+//!
+//! [a]: std::process::Comman
+//~^ ERROR unresolved
+//~| ERROR unresolved
diff --git a/src/test/rustdoc-ui/reference-links.stderr b/src/test/rustdoc-ui/reference-links.stderr
new file mode 100644
index 00000000000..6ba73fbdb00
--- /dev/null
+++ b/src/test/rustdoc-ui/reference-links.stderr
@@ -0,0 +1,20 @@
+error: unresolved link to `std::process::Comman`
+  --> $DIR/reference-links.rs:5:10
+   |
+LL | //! [a]: std::process::Comman
+   |          ^^^^^^^^^^^^^^^^^^^^ no item named `Comman` in module `process`
+   |
+note: the lint level is defined here
+  --> $DIR/reference-links.rs:2:9
+   |
+LL | #![deny(broken_intra_doc_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unresolved link to `std::process::Comman`
+  --> $DIR/reference-links.rs:5:10
+   |
+LL | //! [a]: std::process::Comman
+   |          ^^^^^^^^^^^^^^^^^^^^ no item named `Comman` in module `process`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs
index e7a7d1831f7..aa4ad261c80 100644
--- a/src/test/rustdoc/async-fn.rs
+++ b/src/test/rustdoc/async-fn.rs
@@ -1,6 +1,5 @@
+// ignore-tidy-linelength
 // edition:2018
-#![feature(min_const_generics)]
-
 // @has async_fn/fn.foo.html '//pre[@class="rust fn"]' 'pub async fn foo() -> Option<Foo>'
 pub async fn foo() -> Option<Foo> {
     None
@@ -48,7 +47,50 @@ impl Foo {
     pub async fn mut_self(mut self, mut first: usize) {}
 }
 
+pub trait Pattern<'a> {}
+
 pub trait Trait<const N: usize> {}
 // @has async_fn/fn.const_generics.html
 // @has - '//pre[@class="rust fn"]' 'pub async fn const_generics<const N: usize>(_: impl Trait<N>)'
 pub async fn const_generics<const N: usize>(_: impl Trait<N>) {}
+
+// test that elided lifetimes are properly elided and not displayed as `'_`
+// regression test for #63037
+// @has async_fn/fn.elided.html
+// @has - '//pre[@class="rust fn"]' 'pub async fn elided(foo: &str) -> &str'
+pub async fn elided(foo: &str) -> &str {}
+// This should really be shown as written, but for implementation reasons it's difficult.
+// See `impl Clean for TyKind::Rptr`.
+// @has async_fn/fn.user_elided.html
+// @has - '//pre[@class="rust fn"]' 'pub async fn user_elided(foo: &str) -> &str'
+pub async fn user_elided(foo: &'_ str) -> &str {}
+// @has async_fn/fn.static_trait.html
+// @has - '//pre[@class="rust fn"]' 'pub async fn static_trait(foo: &str) -> Box<dyn Bar>'
+pub async fn static_trait(foo: &str) -> Box<dyn Bar> {}
+// @has async_fn/fn.lifetime_for_trait.html
+// @has - '//pre[@class="rust fn"]' "pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_>"
+pub async fn lifetime_for_trait(foo: &str) -> Box<dyn Bar + '_> {}
+// @has async_fn/fn.elided_in_input_trait.html
+// @has - '//pre[@class="rust fn"]' "pub async fn elided_in_input_trait(t: impl Pattern<'_>)"
+pub async fn elided_in_input_trait(t: impl Pattern<'_>) {}
+
+struct AsyncFdReadyGuard<'a, T> { x: &'a T }
+
+impl Foo {
+    // @has async_fn/struct.Foo.html
+    // @has - '//h4[@class="method"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar) -> impl Iterator<Item = &usize>'
+    pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator<Item = &usize> {}
+    // taken from `tokio` as an example of a method that was particularly bad before
+    // @has - '//h4[@class="method"]' "pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()>"
+    pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()> {}
+    // @has - '//h4[@class="method"]' "pub async fn mut_self(&mut self)"
+    pub async fn mut_self(&mut self) {}
+}
+
+// test named lifetimes, just in case
+// @has async_fn/fn.named.html
+// @has - '//pre[@class="rust fn"]' "pub async fn named<'a, 'b>(foo: &'a str) -> &'b str"
+pub async fn named<'a, 'b>(foo: &'a str) -> &'b str {}
+// @has async_fn/fn.named_trait.html
+// @has - '//pre[@class="rust fn"]' "pub async fn named_trait<'a, 'b>(foo: impl Pattern<'a>) -> impl Pattern<'b>"
+pub async fn named_trait<'a, 'b>(foo: impl Pattern<'a>) -> impl Pattern<'b> {}
diff --git a/src/test/rustdoc/auxiliary/issue-61592.rs b/src/test/rustdoc/auxiliary/issue-61592.rs
new file mode 100644
index 00000000000..6e16a4caf59
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/issue-61592.rs
@@ -0,0 +1,4 @@
+#![crate_name = "foo"]
+
+pub trait FooTrait {}
+pub struct FooStruct;
diff --git a/src/test/rustdoc/codeblock-title.rs b/src/test/rustdoc/codeblock-title.rs
index b59b21111b0..140c5b3a672 100644
--- a/src/test/rustdoc/codeblock-title.rs
+++ b/src/test/rustdoc/codeblock-title.rs
@@ -1,10 +1,9 @@
 #![crate_name = "foo"]
 
-// ignore-tidy-linelength
-
-// @has foo/fn.bar.html '//*[@class="tooltip compile_fail"]/span' "This example deliberately fails to compile"
-// @has foo/fn.bar.html '//*[@class="tooltip ignore"]/span' "This example is not tested"
-// @has foo/fn.bar.html '//*[@class="tooltip should_panic"]/span' "This example panics"
+// @has foo/fn.bar.html '//*[@class="tooltip compile_fail"]' "ⓘ"
+// @has foo/fn.bar.html '//*[@class="tooltip ignore"]' "ⓘ"
+// @has foo/fn.bar.html '//*[@class="tooltip should_panic"]' "ⓘ"
+// @has foo/fn.bar.html '//*[@data-edition="2018"]' "ⓘ"
 
 /// foo
 ///
@@ -20,7 +19,7 @@
 /// hoo();
 /// ```
 ///
-/// ```
+/// ```edition2018
 /// let x = 0;
 /// ```
 pub fn bar() -> usize { 2 }
diff --git a/src/test/rustdoc/const-generics/auxiliary/extern_crate.rs b/src/test/rustdoc/const-generics/auxiliary/extern_crate.rs
index b8bd040f7a4..55b632a48f2 100644
--- a/src/test/rustdoc/const-generics/auxiliary/extern_crate.rs
+++ b/src/test/rustdoc/const-generics/auxiliary/extern_crate.rs
@@ -1,6 +1,4 @@
 // edition:2018
-#![feature(min_const_generics)]
-
 pub fn extern_fn<const N: usize>() -> impl Iterator<Item = [u8; N]> {
     [[0; N]; N].iter().copied()
 }
diff --git a/src/test/rustdoc/const-generics/const-generics-docs.rs b/src/test/rustdoc/const-generics/const-generics-docs.rs
index 9c68e067c6f..21bf216c304 100644
--- a/src/test/rustdoc/const-generics/const-generics-docs.rs
+++ b/src/test/rustdoc/const-generics/const-generics-docs.rs
@@ -1,6 +1,5 @@
 // edition:2018
 // aux-build: extern_crate.rs
-#![feature(min_const_generics)]
 #![crate_name = "foo"]
 
 extern crate extern_crate;
diff --git a/src/test/rustdoc/const-generics/type-alias.rs b/src/test/rustdoc/const-generics/type-alias.rs
index 3064d0701e3..85160dc07a7 100644
--- a/src/test/rustdoc/const-generics/type-alias.rs
+++ b/src/test/rustdoc/const-generics/type-alias.rs
@@ -1,5 +1,4 @@
 // ignore-tidy-linelength
-#![feature(min_const_generics)]
 #![crate_name = "foo"]
 
 // @has foo/type.CellIndex.html '//pre[@class="rust typedef"]' 'type CellIndex<const D: usize> = [i64; D];'
diff --git a/src/test/rustdoc/doc-cfg.rs b/src/test/rustdoc/doc-cfg.rs
index f86541cd118..51a58378299 100644
--- a/src/test/rustdoc/doc-cfg.rs
+++ b/src/test/rustdoc/doc-cfg.rs
@@ -25,12 +25,13 @@ pub mod unix_only {
     // @has doc_cfg/unix_only/trait.ArmOnly.html \
     //  '//*[@id="main"]/*[@class="item-info"]/*[@class="stab portability"]' \
     //  'This is supported on Unix and ARM only.'
-    // @count - '//*[@class="stab portability"]' 2
+    // @count - '//*[@class="stab portability"]' 1
     #[doc(cfg(target_arch = "arm"))]
     pub trait ArmOnly {
         fn unix_and_arm_only_function();
     }
 
+    #[doc(cfg(target_arch = "arm"))]
     impl ArmOnly for super::Portable {
         fn unix_and_arm_only_function() {}
     }
diff --git a/src/test/rustdoc/intra-doc/non-path-primitives.rs b/src/test/rustdoc/intra-doc/non-path-primitives.rs
new file mode 100644
index 00000000000..ad4f6ddd9de
--- /dev/null
+++ b/src/test/rustdoc/intra-doc/non-path-primitives.rs
@@ -0,0 +1,39 @@
+// ignore-tidy-linelength
+#![crate_name = "foo"]
+#![deny(broken_intra_doc_links)]
+
+// @has foo/index.html '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.rotate_left"]' 'slice::rotate_left'
+//! [slice::rotate_left]
+
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.array.html#method.map"]' 'array::map'
+//! [array::map]
+
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' 'pointer::is_null'
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' '*const::is_null'
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' '*mut::is_null'
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.is_null"]' '*::is_null'
+//! [pointer::is_null]
+//! [*const::is_null]
+//! [*mut::is_null]
+//! [*::is_null]
+
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.unit.html"]' 'unit'
+//! [unit]
+
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.tuple.html"]' 'tuple'
+//! [tuple]
+
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.reference.html"]' 'reference'
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.reference.html"]' '&'
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.reference.html"]' '&mut'
+//! [reference]
+//! [&]
+//! [&mut]
+
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.fn.html"]' 'fn'
+//! [fn]
+
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.never.html"]' 'never'
+// @has - '//a[@href="https://doc.rust-lang.org/nightly/std/primitive.never.html"]' '!'
+//! [never]
+//! [!]
diff --git a/src/test/rustdoc/intra-link-self-cache.rs b/src/test/rustdoc/intra-link-self-cache.rs
new file mode 100644
index 00000000000..add1530a5a6
--- /dev/null
+++ b/src/test/rustdoc/intra-link-self-cache.rs
@@ -0,0 +1,14 @@
+#![crate_name = "foo"]
+// @has foo/enum.E1.html '//a/@href' '../foo/enum.E1.html#variant.A'
+
+/// [Self::A::b]
+pub enum E1 {
+    A { b: usize }
+}
+
+// @has foo/enum.E2.html '//a/@href' '../foo/enum.E2.html#variant.A'
+
+/// [Self::A::b]
+pub enum E2 {
+    A { b: usize }
+}
diff --git a/src/test/rustdoc/issue-61592.rs b/src/test/rustdoc/issue-61592.rs
new file mode 100644
index 00000000000..aef038c07d8
--- /dev/null
+++ b/src/test/rustdoc/issue-61592.rs
@@ -0,0 +1,15 @@
+// aux-build:issue-61592.rs
+
+extern crate foo;
+
+// @has issue_61592/index.html
+// @has - '//a[@href="#reexports"]' 'Re-exports'
+// @has - '//code' 'pub use foo::FooTrait as _;'
+// @!has - '//a[@href="trait._.html"]'
+pub use foo::FooTrait as _;
+
+// @has issue_61592/index.html
+// @has - '//a[@href="#reexports"]' 'Re-exports'
+// @has - '//code' 'pub use foo::FooStruct as _;'
+// @!has - '//a[@href="struct._.html"]'
+pub use foo::FooStruct as _;
diff --git a/src/test/rustdoc/issue-79201.rs b/src/test/rustdoc/issue-79201.rs
new file mode 100644
index 00000000000..f95d79cd493
--- /dev/null
+++ b/src/test/rustdoc/issue-79201.rs
@@ -0,0 +1,41 @@
+#![feature(doc_cfg)]
+
+// @has 'issue_79201/trait.Foo.html'
+// @count   - '//*[@class="stab portability"]' 6
+// @matches - '//*[@class="stab portability"]' 'crate feature foo-root'
+// @matches - '//*[@class="stab portability"]' 'crate feature foo-public-mod'
+// @matches - '//*[@class="stab portability"]' 'crate feature foo-private-mod'
+// @matches - '//*[@class="stab portability"]' 'crate feature foo-fn'
+// @matches - '//*[@class="stab portability"]' 'crate feature foo-method'
+
+pub trait Foo {}
+
+#[doc(cfg(feature = "foo-root"))]
+impl crate::Foo for usize {}
+
+#[doc(cfg(feature = "foo-public-mod"))]
+pub mod public {
+    impl crate::Foo for u8 {}
+}
+
+#[doc(cfg(feature = "foo-private-mod"))]
+mod private {
+    impl crate::Foo for u16 {}
+}
+
+#[doc(cfg(feature = "foo-const"))]
+const _: () = {
+    impl crate::Foo for u32 {}
+};
+
+#[doc(cfg(feature = "foo-fn"))]
+fn __() {
+    impl crate::Foo for u64 {}
+}
+
+#[doc(cfg(feature = "foo-method"))]
+impl dyn Foo {
+    fn __() {
+        impl crate::Foo for u128 {}
+    }
+}
diff --git a/src/test/rustdoc/pub-restricted.rs b/src/test/rustdoc/pub-restricted.rs
deleted file mode 100644
index 6720d848ac3..00000000000
--- a/src/test/rustdoc/pub-restricted.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-// compile-flags: --document-private-items
-
-#![feature(crate_visibility_modifier)]
-
-#![crate_name = "foo"]
-
-// @has 'foo/struct.FooPublic.html' '//pre' 'pub struct FooPublic'
-pub struct FooPublic;
-// @has 'foo/struct.FooJustCrate.html' '//pre' 'pub(crate) struct FooJustCrate'
-crate struct FooJustCrate;
-// @has 'foo/struct.FooPubCrate.html' '//pre' 'pub(crate) struct FooPubCrate'
-pub(crate) struct FooPubCrate;
-// @has 'foo/struct.FooSelf.html' '//pre' 'pub(crate) struct FooSelf'
-pub(self) struct FooSelf;
-// @has 'foo/struct.FooInSelf.html' '//pre' 'pub(crate) struct FooInSelf'
-pub(in self) struct FooInSelf;
-mod a {
-    // @has 'foo/a/struct.FooSuper.html' '//pre' 'pub(crate) struct FooSuper'
-    pub(super) struct FooSuper;
-    // @has 'foo/a/struct.FooInSuper.html' '//pre' 'pub(crate) struct FooInSuper'
-    pub(in super) struct FooInSuper;
-    // @has 'foo/a/struct.FooInA.html' '//pre' 'pub(in a) struct FooInA'
-    pub(in a) struct FooInA;
-    mod b {
-        // @has 'foo/a/b/struct.FooInSelfSuperB.html' '//pre' 'pub(in a::b) struct FooInSelfSuperB'
-        pub(in a::b) struct FooInSelfSuperB;
-        // @has 'foo/a/b/struct.FooInSuperSuper.html' '//pre' 'pub(crate) struct FooInSuperSuper'
-        pub(in super::super) struct FooInSuperSuper;
-        // @has 'foo/a/b/struct.FooInAB.html' '//pre' 'pub(in a::b) struct FooInAB'
-        pub(in a::b) struct FooInAB;
-    }
-}
diff --git a/src/test/rustdoc/rustc_deprecated-future.rs b/src/test/rustdoc/rustc_deprecated-future.rs
index 3133775706b..95a767a8329 100644
--- a/src/test/rustdoc/rustc_deprecated-future.rs
+++ b/src/test/rustdoc/rustc_deprecated-future.rs
@@ -4,8 +4,16 @@
 
 // @has rustc_deprecated_future/index.html '//*[@class="stab deprecated"]' \
 //      'Deprecation planned'
-// @has rustc_deprecated_future/struct.S.html '//*[@class="stab deprecated"]' \
+// @has rustc_deprecated_future/struct.S1.html '//*[@class="stab deprecated"]' \
 //      'Deprecating in 99.99.99: effectively never'
 #[rustc_deprecated(since = "99.99.99", reason = "effectively never")]
 #[stable(feature = "rustc_deprecated-future-test", since = "1.0.0")]
-pub struct S;
+pub struct S1;
+
+// @has rustc_deprecated_future/index.html '//*[@class="stab deprecated"]' \
+//      'Deprecation planned'
+// @has rustc_deprecated_future/struct.S2.html '//*[@class="stab deprecated"]' \
+//      'Deprecating in a future Rust version: literally never'
+#[rustc_deprecated(since = "TBD", reason = "literally never")]
+#[stable(feature = "rustc_deprecated-future-test", since = "1.0.0")]
+pub struct S2;
diff --git a/src/test/rustdoc/visibility.rs b/src/test/rustdoc/visibility.rs
new file mode 100644
index 00000000000..59427693c5a
--- /dev/null
+++ b/src/test/rustdoc/visibility.rs
@@ -0,0 +1,44 @@
+// compile-flags: --document-private-items
+
+#![feature(crate_visibility_modifier)]
+
+#![crate_name = "foo"]
+
+// @has 'foo/struct.FooPublic.html' '//pre' 'pub struct FooPublic'
+pub struct FooPublic;
+// @has 'foo/struct.FooJustCrate.html' '//pre' 'pub(crate) struct FooJustCrate'
+crate struct FooJustCrate;
+// @has 'foo/struct.FooPubCrate.html' '//pre' 'pub(crate) struct FooPubCrate'
+pub(crate) struct FooPubCrate;
+// @has 'foo/struct.FooSelf.html' '//pre' 'pub(crate) struct FooSelf'
+pub(self) struct FooSelf;
+// @has 'foo/struct.FooInSelf.html' '//pre' 'pub(crate) struct FooInSelf'
+pub(in self) struct FooInSelf;
+// @has 'foo/struct.FooPriv.html' '//pre' 'pub(crate) struct FooPriv'
+struct FooPriv;
+
+mod a {
+    // @has 'foo/a/struct.FooASuper.html' '//pre' 'pub(crate) struct FooASuper'
+    pub(super) struct FooASuper;
+    // @has 'foo/a/struct.FooAInSuper.html' '//pre' 'pub(crate) struct FooAInSuper'
+    pub(in super) struct FooAInSuper;
+    // @has 'foo/a/struct.FooAInA.html' '//pre' 'struct FooAInA'
+    // @!has 'foo/a/struct.FooAInA.html' '//pre' 'pub'
+    pub(in a) struct FooAInA;
+    // @has 'foo/a/struct.FooAPriv.html' '//pre' 'struct FooAPriv'
+    // @!has 'foo/a/struct.FooAPriv.html' '//pre' 'pub'
+    struct FooAPriv;
+
+    mod b {
+        // @has 'foo/a/b/struct.FooBSuper.html' '//pre' 'pub(super) struct FooBSuper'
+        pub(super) struct FooBSuper;
+        // @has 'foo/a/b/struct.FooBInSuperSuper.html' '//pre' 'pub(crate) struct FooBInSuperSuper'
+        pub(in super::super) struct FooBInSuperSuper;
+        // @has 'foo/a/b/struct.FooBInAB.html' '//pre' 'struct FooBInAB'
+        // @!has 'foo/a/b/struct.FooBInAB.html' '//pre' 'pub'
+        pub(in a::b) struct FooBInAB;
+        // @has 'foo/a/b/struct.FooBPriv.html' '//pre' 'struct FooBPriv'
+        // @!has 'foo/a/b/struct.FooBPriv.html' '//pre' 'pub'
+        struct FooBPriv;
+    }
+}
diff --git a/src/test/ui-fulldeps/dropck-tarena-cycle-checked.rs b/src/test/ui-fulldeps/dropck-tarena-cycle-checked.rs
index fabcd727482..cc97971a0dd 100644
--- a/src/test/ui-fulldeps/dropck-tarena-cycle-checked.rs
+++ b/src/test/ui-fulldeps/dropck-tarena-cycle-checked.rs
@@ -1,8 +1,8 @@
 // Reject mixing cyclic structure and Drop when using TypedArena.
 //
-// (Compare against compile-fail/dropck_vec_cycle_checked.rs)
+// (Compare against dropck-vec-cycle-checked.rs)
 //
-// (Also compare against compile-fail/dropck_tarena_unsound_drop.rs,
+// (Also compare against ui-fulldeps/dropck-tarena-unsound-drop.rs,
 //  which is a reduction of this code to more directly show the reason
 //  for the error message we see here.)
 
diff --git a/src/test/ui-fulldeps/dropck_tarena_sound_drop.rs b/src/test/ui-fulldeps/dropck_tarena_sound_drop.rs
index c5b9efee8e7..187f9a24a90 100644
--- a/src/test/ui-fulldeps/dropck_tarena_sound_drop.rs
+++ b/src/test/ui-fulldeps/dropck_tarena_sound_drop.rs
@@ -5,7 +5,7 @@
 // methods might access borrowed data, as long as the borrowed data
 // has lifetime that strictly outlives the arena itself.
 //
-// Compare against compile-fail/dropck_tarena_unsound_drop.rs, which
+// Compare against ui-fulldeps/dropck-tarena-unsound-drop.rs, which
 // shows a similar setup, but restricts `f` so that the struct `C<'a>`
 // is force-fed a lifetime equal to that of the borrowed arena.
 
diff --git a/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs b/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs
index d4858932815..c8559d24728 100644
--- a/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs
+++ b/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs
@@ -17,7 +17,12 @@ impl Drop for D {
     fn drop(&mut self) {
         println!("Dropping {}", self.0);
         let old = LOG.load(Ordering::SeqCst);
-        LOG.compare_and_swap(old, old << 4 | self.0 as usize, Ordering::SeqCst);
+        let _ = LOG.compare_exchange(
+            old,
+            old << 4 | self.0 as usize,
+            Ordering::SeqCst,
+            Ordering::SeqCst
+        );
     }
 }
 
diff --git a/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs b/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs
index e8a5b00a55b..e75051caabc 100644
--- a/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs
+++ b/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs
@@ -17,7 +17,12 @@ impl Drop for D {
     fn drop(&mut self) {
         println!("Dropping {}", self.0);
         let old = LOG.load(Ordering::SeqCst);
-        LOG.compare_and_swap(old, old << 4 | self.0 as usize, Ordering::SeqCst);
+        let _ = LOG.compare_exchange(
+            old,
+            old << 4 | self.0 as usize,
+            Ordering::SeqCst,
+            Ordering::SeqCst
+        );
     }
 }
 
diff --git a/src/test/ui/array-slice-vec/copy-out-of-array-1.rs b/src/test/ui/array-slice-vec/copy-out-of-array-1.rs
index e64985ae3f6..c6d311148d0 100644
--- a/src/test/ui/array-slice-vec/copy-out-of-array-1.rs
+++ b/src/test/ui/array-slice-vec/copy-out-of-array-1.rs
@@ -2,7 +2,7 @@
 
 // Ensure that we can copy out of a fixed-size array.
 //
-// (Compare with compile-fail/move-out-of-array-1.rs)
+// (Compare with ui/moves/move-out-of-array-1.rs)
 
 #[derive(Copy, Clone)]
 struct C { _x: u8 }
diff --git a/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr b/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr
index 7c1a92c79d9..0ad05b3adeb 100644
--- a/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr
+++ b/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr
@@ -6,7 +6,6 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error[E0308]: mismatched types
   --> $DIR/match_arr_unknown_len.rs:6:9
diff --git a/src/test/ui/array-slice-vec/nested-vec-3.rs b/src/test/ui/array-slice-vec/nested-vec-3.rs
index 52b892dbcdf..96497a53d30 100644
--- a/src/test/ui/array-slice-vec/nested-vec-3.rs
+++ b/src/test/ui/array-slice-vec/nested-vec-3.rs
@@ -18,7 +18,12 @@ impl Drop for D {
     fn drop(&mut self) {
         println!("Dropping {}", self.0);
         let old = LOG.load(Ordering::SeqCst);
-        LOG.compare_and_swap(old, old << 4 | self.0 as usize, Ordering::SeqCst);
+        let _ = LOG.compare_exchange(
+            old,
+            old << 4 | self.0 as usize,
+            Ordering::SeqCst,
+            Ordering::SeqCst,
+        );
     }
 }
 
diff --git a/src/test/ui/associated-consts/associated-const-type-parameter-arrays.rs b/src/test/ui/associated-consts/associated-const-type-parameter-arrays.rs
index d51821059fc..5152d784047 100644
--- a/src/test/ui/associated-consts/associated-const-type-parameter-arrays.rs
+++ b/src/test/ui/associated-consts/associated-const-type-parameter-arrays.rs
@@ -14,8 +14,7 @@ impl Foo for Def {
 
 pub fn test<A: Foo, B: Foo>() {
     let _array: [u32; <A as Foo>::Y];
-    //~^ ERROR the trait bound `A: Foo` is not satisfied [E0277]
+    //~^ ERROR generic parameters may not be used
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/src/test/ui/associated-consts/associated-const-type-parameter-arrays.stderr b/src/test/ui/associated-consts/associated-const-type-parameter-arrays.stderr
index ac40e390cfb..d3a1cd30e2b 100644
--- a/src/test/ui/associated-consts/associated-const-type-parameter-arrays.stderr
+++ b/src/test/ui/associated-consts/associated-const-type-parameter-arrays.stderr
@@ -1,17 +1,11 @@
-error[E0277]: the trait bound `A: Foo` is not satisfied
-  --> $DIR/associated-const-type-parameter-arrays.rs:16:23
+error: generic parameters may not be used in const operations
+  --> $DIR/associated-const-type-parameter-arrays.rs:16:24
    |
-LL |     const Y: usize;
-   |     --------------- required by `Foo::Y`
-...
 LL |     let _array: [u32; <A as Foo>::Y];
-   |                       ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
+   |                        ^ cannot perform const operation using `A`
    |
-help: consider further restricting this bound
-   |
-LL | pub fn test<A: Foo + Foo, B: Foo>() {
-   |                    ^^^^^
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-item/associated-item-duplicate-bounds.rs b/src/test/ui/associated-item/associated-item-duplicate-bounds.rs
index bec922b0721..242a02353a1 100644
--- a/src/test/ui/associated-item/associated-item-duplicate-bounds.rs
+++ b/src/test/ui/associated-item/associated-item-duplicate-bounds.rs
@@ -5,7 +5,7 @@ trait Adapter {
 struct Foo<A: Adapter> {
     adapter: A,
     links: [u32; A::LINKS], // Shouldn't suggest bounds already there.
-    //~^ ERROR: no associated item named `LINKS` found
+    //~^ ERROR generic parameters may not be used in const operations
 }
 
 fn main() {}
diff --git a/src/test/ui/associated-item/associated-item-duplicate-bounds.stderr b/src/test/ui/associated-item/associated-item-duplicate-bounds.stderr
index ff1ad4c006e..0d84dca5b80 100644
--- a/src/test/ui/associated-item/associated-item-duplicate-bounds.stderr
+++ b/src/test/ui/associated-item/associated-item-duplicate-bounds.stderr
@@ -1,11 +1,11 @@
-error[E0599]: no associated item named `LINKS` found for type parameter `A` in the current scope
-  --> $DIR/associated-item-duplicate-bounds.rs:7:21
+error: generic parameters may not be used in const operations
+  --> $DIR/associated-item-duplicate-bounds.rs:7:18
    |
 LL |     links: [u32; A::LINKS], // Shouldn't suggest bounds already there.
-   |                     ^^^^^ associated item not found in `A`
+   |                  ^^^^^^^^ cannot perform const operation using `A`
    |
-   = help: items from traits can only be used if the type parameter is bounded by the trait
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed
index 760d2b433c8..bca69a97677 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed
@@ -11,7 +11,7 @@ pub trait Foo<T> {
 
 fn foo2<I : for<'x> Foo<&'x isize>>(
     x: <I as Foo<&isize>>::A)
-    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+    //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
 {
     // This case is illegal because we have to instantiate `'x`, and
     // we don't know what region to instantiate it with.
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs
index 6eb584ea645..1e23dd8890b 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs
@@ -11,7 +11,7 @@ pub trait Foo<T> {
 
 fn foo2<I : for<'x> Foo<&'x isize>>(
     x: I::A)
-    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+    //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
 {
     // This case is illegal because we have to instantiate `'x`, and
     // we don't know what region to instantiate it with.
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr
index f2137f68665..989624bdd93 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr
@@ -1,4 +1,4 @@
-error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
   --> $DIR/associated-types-project-from-hrtb-in-fn.rs:13:8
    |
 LL |     x: I::A)
@@ -6,3 +6,4 @@ LL |     x: I::A)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0212`.
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs
index 58f186d7775..ed30d86cb5b 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs
@@ -9,14 +9,14 @@ pub trait Foo<T> {
 
 struct SomeStruct<I: for<'x> Foo<&'x isize>> {
     field: I::A
-    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+    //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
 }
 
 enum SomeEnum<'b, I: for<'a> Foo<&'a isize>> {
     TupleVariant(I::A),
-    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+    //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
     StructVariant { field: I::A },
-    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+    //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
     OkVariant(&'b usize),
 }
 
@@ -33,7 +33,7 @@ struct YetAnotherStruct<'a, I: for<'x> Foo<&'x isize>> {
 struct Why<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x,
     'y, 'z, 'aa, I: for<'l, 'm> Foo<&'l &'m isize>> {
     field: I::A,
-    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+    //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
 }
 
 pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr
index e3fd2860ebc..cadc3e9eab1 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr
@@ -1,4 +1,4 @@
-error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
   --> $DIR/associated-types-project-from-hrtb-in-struct.rs:11:12
    |
 LL |     field: I::A
@@ -10,7 +10,7 @@ LL | struct SomeStruct<'a, I: for<'x> Foo<&'x isize>> {
 LL |     field: <I as Foo<&'a isize>>::A
    |
 
-error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
   --> $DIR/associated-types-project-from-hrtb-in-struct.rs:16:18
    |
 LL |     TupleVariant(I::A),
@@ -22,7 +22,7 @@ LL | enum SomeEnum<'c, 'b, I: for<'a> Foo<&'a isize>> {
 LL |     TupleVariant(<I as Foo<&'c isize>>::A),
    |
 
-error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
   --> $DIR/associated-types-project-from-hrtb-in-struct.rs:18:28
    |
 LL |     StructVariant { field: I::A },
@@ -36,7 +36,7 @@ LL |
 LL |     StructVariant { field: <I as Foo<&'c isize>>::A },
    |
 
-error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
   --> $DIR/associated-types-project-from-hrtb-in-struct.rs:35:12
    |
 LL |     field: I::A,
@@ -51,3 +51,4 @@ LL |     field: <I as Foo<&'bb &'bb isize>>::A,
 
 error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0212`.
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed
index acf32bccbec..66d8613f184 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed
@@ -11,7 +11,7 @@ pub trait Foo<T> {
 
 trait SomeTrait<I : for<'x> Foo<&'x isize>> {
     fn some_method(&self, arg: <I as Foo<&isize>>::A);
-    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+    //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
 }
 
 trait AnotherTrait<I : for<'x> Foo<&'x isize>> {
@@ -30,7 +30,7 @@ struct Peach<X>(std::marker::PhantomData<X>);
 
 impl<X: for<'a> Banana<'a>> Peach<X> {
     fn mango(&self) -> <X as Banana<'_>>::Assoc {
-    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+    //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
         Default::default()
     }
 }
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs
index a249f89685e..0a1b29de19e 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs
@@ -11,7 +11,7 @@ pub trait Foo<T> {
 
 trait SomeTrait<I : for<'x> Foo<&'x isize>> {
     fn some_method(&self, arg: I::A);
-    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+    //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
 }
 
 trait AnotherTrait<I : for<'x> Foo<&'x isize>> {
@@ -30,7 +30,7 @@ struct Peach<X>(std::marker::PhantomData<X>);
 
 impl<X: for<'a> Banana<'a>> Peach<X> {
     fn mango(&self) -> X::Assoc {
-    //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
+    //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
         Default::default()
     }
 }
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr
index a37fec24493..d457f9f8468 100644
--- a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr
@@ -1,10 +1,10 @@
-error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
   --> $DIR/associated-types-project-from-hrtb-in-trait-method.rs:13:32
    |
 LL |     fn some_method(&self, arg: I::A);
    |                                ^^^^ help: use a fully qualified path with inferred lifetimes: `<I as Foo<&isize>>::A`
 
-error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
   --> $DIR/associated-types-project-from-hrtb-in-trait-method.rs:32:24
    |
 LL |     fn mango(&self) -> X::Assoc {
@@ -12,3 +12,4 @@ LL |     fn mango(&self) -> X::Assoc {
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0212`.
diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs
index 5f06a829600..3b8c8c019e5 100644
--- a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs
+++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs
@@ -3,7 +3,7 @@
 // the trait definition if there is no default method and for every impl,
 // `Self` does implement `Get`.
 //
-// See also compile-fail tests associated-types-no-suitable-supertrait
+// See also tests associated-types-no-suitable-supertrait
 // and associated-types-no-suitable-supertrait-2, which show how small
 // variants of the code below can fail.
 
diff --git a/src/test/ui/associated-types/defaults-cyclic-fail-1.rs b/src/test/ui/associated-types/defaults-cyclic-fail-1.rs
index afb2b3df716..61ef013236e 100644
--- a/src/test/ui/associated-types/defaults-cyclic-fail-1.rs
+++ b/src/test/ui/associated-types/defaults-cyclic-fail-1.rs
@@ -24,13 +24,13 @@ impl Tr for u32 {
 // ...but not in an impl that redefines one of the types.
 impl Tr for bool {
     type A = Box<Self::B>;
-    //~^ ERROR type mismatch resolving `<bool as Tr>::B == _`
+    //~^ ERROR overflow evaluating the requirement `<bool as Tr>::B == _`
 }
 // (the error is shown twice for some reason)
 
 impl Tr for usize {
     type B = &'static Self::A;
-    //~^ ERROR type mismatch resolving `<usize as Tr>::A == _`
+    //~^ ERROR overflow evaluating the requirement `<usize as Tr>::A == _`
 }
 
 fn main() {
diff --git a/src/test/ui/associated-types/defaults-cyclic-fail-1.stderr b/src/test/ui/associated-types/defaults-cyclic-fail-1.stderr
index ae7150d47ca..5e98520b411 100644
--- a/src/test/ui/associated-types/defaults-cyclic-fail-1.stderr
+++ b/src/test/ui/associated-types/defaults-cyclic-fail-1.stderr
@@ -1,15 +1,15 @@
-error[E0271]: type mismatch resolving `<bool as Tr>::B == _`
+error[E0275]: overflow evaluating the requirement `<bool as Tr>::B == _`
   --> $DIR/defaults-cyclic-fail-1.rs:26:5
    |
 LL |     type A = Box<Self::B>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0271]: type mismatch resolving `<usize as Tr>::A == _`
+error[E0275]: overflow evaluating the requirement `<usize as Tr>::A == _`
   --> $DIR/defaults-cyclic-fail-1.rs:32:5
    |
 LL |     type B = &'static Self::A;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/associated-types/defaults-cyclic-fail-2.rs b/src/test/ui/associated-types/defaults-cyclic-fail-2.rs
index ba4bb0d5a29..e91c9f2d29a 100644
--- a/src/test/ui/associated-types/defaults-cyclic-fail-2.rs
+++ b/src/test/ui/associated-types/defaults-cyclic-fail-2.rs
@@ -25,13 +25,13 @@ impl Tr for u32 {
 
 impl Tr for bool {
     type A = Box<Self::B>;
-    //~^ ERROR type mismatch resolving `<bool as Tr>::B == _`
+    //~^ ERROR overflow evaluating the requirement `<bool as Tr>::B == _`
 }
 // (the error is shown twice for some reason)
 
 impl Tr for usize {
     type B = &'static Self::A;
-    //~^ ERROR type mismatch resolving `<usize as Tr>::A == _`
+    //~^ ERROR overflow evaluating the requirement `<usize as Tr>::A == _`
 }
 
 fn main() {
diff --git a/src/test/ui/associated-types/defaults-cyclic-fail-2.stderr b/src/test/ui/associated-types/defaults-cyclic-fail-2.stderr
index 0dfbac2dec5..c538805f858 100644
--- a/src/test/ui/associated-types/defaults-cyclic-fail-2.stderr
+++ b/src/test/ui/associated-types/defaults-cyclic-fail-2.stderr
@@ -1,15 +1,15 @@
-error[E0271]: type mismatch resolving `<bool as Tr>::B == _`
+error[E0275]: overflow evaluating the requirement `<bool as Tr>::B == _`
   --> $DIR/defaults-cyclic-fail-2.rs:27:5
    |
 LL |     type A = Box<Self::B>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0271]: type mismatch resolving `<usize as Tr>::A == _`
+error[E0275]: overflow evaluating the requirement `<usize as Tr>::A == _`
   --> $DIR/defaults-cyclic-fail-2.rs:33:5
    |
 LL |     type B = &'static Self::A;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/associated-types/defaults-wf.stderr b/src/test/ui/associated-types/defaults-wf.stderr
index 4c43e6a182d..d4fa5be742f 100644
--- a/src/test/ui/associated-types/defaults-wf.stderr
+++ b/src/test/ui/associated-types/defaults-wf.stderr
@@ -4,7 +4,7 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation
 LL |     type Ty = Vec<[u8]>;
    |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    | 
-  ::: $SRC_DIR/alloc/src/vec.rs:LL:COL
+  ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
    |
 LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
    |                - required by this bound in `Vec`
diff --git a/src/test/ui/associated-types/impl-wf-cycle-1.rs b/src/test/ui/associated-types/impl-wf-cycle-1.rs
new file mode 100644
index 00000000000..ba074210a2b
--- /dev/null
+++ b/src/test/ui/associated-types/impl-wf-cycle-1.rs
@@ -0,0 +1,29 @@
+// Regression test for #79714
+
+trait Baz {}
+impl Baz for () {}
+impl<T> Baz for (T,) {}
+
+trait Fiz {}
+impl Fiz for bool {}
+
+trait Grault {
+    type A;
+    type B;
+}
+
+impl<T: Grault> Grault for (T,)
+where
+    Self::A: Baz,
+    Self::B: Fiz,
+{
+    type A = ();
+    //~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
+    type B = bool;
+    //~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
+}
+//~^^^^^^^^^^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
+
+fn main() {
+    let x: <(_,) as Grault>::A = ();
+}
diff --git a/src/test/ui/associated-types/impl-wf-cycle-1.stderr b/src/test/ui/associated-types/impl-wf-cycle-1.stderr
new file mode 100644
index 00000000000..82328048c99
--- /dev/null
+++ b/src/test/ui/associated-types/impl-wf-cycle-1.stderr
@@ -0,0 +1,39 @@
+error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
+  --> $DIR/impl-wf-cycle-1.rs:15:1
+   |
+LL | / impl<T: Grault> Grault for (T,)
+LL | | where
+LL | |     Self::A: Baz,
+LL | |     Self::B: Fiz,
+...  |
+LL | |
+LL | | }
+   | |_^
+   |
+   = note: required because of the requirements on the impl of `Grault` for `(T,)`
+   = note: 1 redundant requirements hidden
+   = note: required because of the requirements on the impl of `Grault` for `(T,)`
+
+error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
+  --> $DIR/impl-wf-cycle-1.rs:20:5
+   |
+LL |     type A = ();
+   |     ^^^^^^^^^^^^
+   |
+   = note: required because of the requirements on the impl of `Grault` for `(T,)`
+   = note: 1 redundant requirements hidden
+   = note: required because of the requirements on the impl of `Grault` for `(T,)`
+
+error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
+  --> $DIR/impl-wf-cycle-1.rs:22:5
+   |
+LL |     type B = bool;
+   |     ^^^^^^^^^^^^^^
+   |
+   = note: required because of the requirements on the impl of `Grault` for `(T,)`
+   = note: 1 redundant requirements hidden
+   = note: required because of the requirements on the impl of `Grault` for `(T,)`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/associated-types/impl-wf-cycle-2.rs b/src/test/ui/associated-types/impl-wf-cycle-2.rs
new file mode 100644
index 00000000000..6fccc54f229
--- /dev/null
+++ b/src/test/ui/associated-types/impl-wf-cycle-2.rs
@@ -0,0 +1,16 @@
+// Regression test for #79714
+
+trait Grault {
+    type A;
+}
+
+impl<T: Grault> Grault for (T,)
+where
+    Self::A: Copy,
+{
+    type A = ();
+    //~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
+}
+//~^^^^^^^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
+
+fn main() {}
diff --git a/src/test/ui/associated-types/impl-wf-cycle-2.stderr b/src/test/ui/associated-types/impl-wf-cycle-2.stderr
new file mode 100644
index 00000000000..5cd18a33adf
--- /dev/null
+++ b/src/test/ui/associated-types/impl-wf-cycle-2.stderr
@@ -0,0 +1,25 @@
+error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
+  --> $DIR/impl-wf-cycle-2.rs:7:1
+   |
+LL | / impl<T: Grault> Grault for (T,)
+LL | | where
+LL | |     Self::A: Copy,
+LL | | {
+LL | |     type A = ();
+LL | |
+LL | | }
+   | |_^
+   |
+   = note: required because of the requirements on the impl of `Grault` for `(T,)`
+
+error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
+  --> $DIR/impl-wf-cycle-2.rs:11:5
+   |
+LL |     type A = ();
+   |     ^^^^^^^^^^^^
+   |
+   = note: required because of the requirements on the impl of `Grault` for `(T,)`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/compile-fail/issue-23595-1.rs b/src/test/ui/associated-types/issue-23595-1.rs
index 483c205f42d..483c205f42d 100644
--- a/src/test/compile-fail/issue-23595-1.rs
+++ b/src/test/ui/associated-types/issue-23595-1.rs
diff --git a/src/test/ui/associated-types/issue-23595-1.stderr b/src/test/ui/associated-types/issue-23595-1.stderr
new file mode 100644
index 00000000000..bb455684ee3
--- /dev/null
+++ b/src/test/ui/associated-types/issue-23595-1.stderr
@@ -0,0 +1,16 @@
+error[E0191]: the value of the associated types `ChildKey` (from trait `Hierarchy`), `Children` (from trait `Hierarchy`), `Value` (from trait `Hierarchy`) must be specified
+  --> $DIR/issue-23595-1.rs:8:58
+   |
+LL |     type Value;
+   |     ----------- `Value` defined here
+LL |     type ChildKey;
+   |     -------------- `ChildKey` defined here
+LL |     type Children = dyn Index<Self::ChildKey, Output=dyn Hierarchy>;
+   |     -----------------------------------------------------^^^^^^^^^--
+   |     |                                                    |
+   |     |                                                    help: specify the associated types: `Hierarchy<Value = Type, ChildKey = Type, Children = Type>`
+   |     `Children` defined here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0191`.
diff --git a/src/test/compile-fail/issue-27675-unchecked-bounds.rs b/src/test/ui/associated-types/issue-27675-unchecked-bounds.rs
index 1cfc2304531..1cfc2304531 100644
--- a/src/test/compile-fail/issue-27675-unchecked-bounds.rs
+++ b/src/test/ui/associated-types/issue-27675-unchecked-bounds.rs
diff --git a/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr
new file mode 100644
index 00000000000..02396bd00a5
--- /dev/null
+++ b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `T: Copy` is not satisfied
+  --> $DIR/issue-27675-unchecked-bounds.rs:15:31
+   |
+LL | fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From {
+   |            ----- required by this bound in `copy`
+...
+LL |     copy::<dyn Setup<From=T>>(t)
+   |                               ^ the trait `Copy` is not implemented for `T`
+   |
+help: consider restricting type parameter `T`
+   |
+LL | pub fn copy_any<T: Copy>(t: &T) -> T {
+   |                  ^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr
index 123c3192cff..b96cab9f0f5 100644
--- a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr
+++ b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr
@@ -2,7 +2,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed
   --> $DIR/issue-74072-lifetime-name-annotations.rs:9:5
    |
 LL | pub async fn async_fn(x: &mut i32) -> &i32 {
-   |                                       - let's call the lifetime of this reference `'1`
+   |                          - let's call the lifetime of this reference `'1`
 LL |     let y = &*x;
    |             --- borrow of `*x` occurs here
 LL |     *x += 1;
diff --git a/src/test/ui/async-await/issue-75785-confusing-named-region.rs b/src/test/ui/async-await/issue-75785-confusing-named-region.rs
new file mode 100644
index 00000000000..452614087be
--- /dev/null
+++ b/src/test/ui/async-await/issue-75785-confusing-named-region.rs
@@ -0,0 +1,13 @@
+// edition:2018
+//
+// Regression test for issue #75785
+// Tests that we don't point to a confusing named
+// region when emitting a diagnostic
+
+pub async fn async_fn(x: &mut i32) -> (&i32, &i32) {
+    let y = &*x;
+    *x += 1; //~ ERROR cannot assign to
+    (&32, y)
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issue-75785-confusing-named-region.stderr b/src/test/ui/async-await/issue-75785-confusing-named-region.stderr
new file mode 100644
index 00000000000..3b731d9c60a
--- /dev/null
+++ b/src/test/ui/async-await/issue-75785-confusing-named-region.stderr
@@ -0,0 +1,15 @@
+error[E0506]: cannot assign to `*x` because it is borrowed
+  --> $DIR/issue-75785-confusing-named-region.rs:9:5
+   |
+LL | pub async fn async_fn(x: &mut i32) -> (&i32, &i32) {
+   |                          - let's call the lifetime of this reference `'1`
+LL |     let y = &*x;
+   |             --- borrow of `*x` occurs here
+LL |     *x += 1;
+   |     ^^^^^^^ assignment to borrowed `*x` occurs here
+LL |     (&32, y)
+   |     -------- returning this value requires that `*x` is borrowed for `'1`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0506`.
diff --git a/src/test/ui/async-await/issues/issue-78654.full.stderr b/src/test/ui/async-await/issues/issue-78654.full.stderr
index ff0260523db..a9208ade740 100644
--- a/src/test/ui/async-await/issues/issue-78654.full.stderr
+++ b/src/test/ui/async-await/issues/issue-78654.full.stderr
@@ -1,11 +1,11 @@
 error[E0573]: expected type, found built-in attribute `feature`
-  --> $DIR/issue-78654.rs:10:15
+  --> $DIR/issue-78654.rs:9:15
    |
 LL | impl<const H: feature> Foo {
    |               ^^^^^^^ not a type
 
 error[E0207]: the const parameter `H` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/issue-78654.rs:10:12
+  --> $DIR/issue-78654.rs:9:12
    |
 LL | impl<const H: feature> Foo {
    |            ^ unconstrained const parameter
diff --git a/src/test/ui/async-await/issues/issue-78654.min.stderr b/src/test/ui/async-await/issues/issue-78654.min.stderr
index ff0260523db..a9208ade740 100644
--- a/src/test/ui/async-await/issues/issue-78654.min.stderr
+++ b/src/test/ui/async-await/issues/issue-78654.min.stderr
@@ -1,11 +1,11 @@
 error[E0573]: expected type, found built-in attribute `feature`
-  --> $DIR/issue-78654.rs:10:15
+  --> $DIR/issue-78654.rs:9:15
    |
 LL | impl<const H: feature> Foo {
    |               ^^^^^^^ not a type
 
 error[E0207]: the const parameter `H` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/issue-78654.rs:10:12
+  --> $DIR/issue-78654.rs:9:12
    |
 LL | impl<const H: feature> Foo {
    |            ^ unconstrained const parameter
diff --git a/src/test/ui/async-await/issues/issue-78654.rs b/src/test/ui/async-await/issues/issue-78654.rs
index b57ed35f8e3..37ebb4ecac8 100644
--- a/src/test/ui/async-await/issues/issue-78654.rs
+++ b/src/test/ui/async-await/issues/issue-78654.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo;
 
diff --git a/src/test/ui/bad/bad-sized.stderr b/src/test/ui/bad/bad-sized.stderr
index 60a5bb9f786..260d78b543a 100644
--- a/src/test/ui/bad/bad-sized.stderr
+++ b/src/test/ui/bad/bad-sized.stderr
@@ -15,7 +15,7 @@ error[E0277]: the size for values of type `dyn Trait` cannot be known at compila
 LL |     let x: Vec<dyn Trait + Sized> = Vec::new();
    |            ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    | 
-  ::: $SRC_DIR/alloc/src/vec.rs:LL:COL
+  ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
    |
 LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
    |                - required by this bound in `Vec`
diff --git a/src/test/ui/binding/const-param.full.stderr b/src/test/ui/binding/const-param.full.stderr
new file mode 100644
index 00000000000..0200c6def24
--- /dev/null
+++ b/src/test/ui/binding/const-param.full.stderr
@@ -0,0 +1,9 @@
+error[E0158]: const parameters cannot be referenced in patterns
+  --> $DIR/const-param.rs:8:9
+   |
+LL |         N => {}
+   |         ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0158`.
diff --git a/src/test/ui/binding/const-param.min.stderr b/src/test/ui/binding/const-param.min.stderr
new file mode 100644
index 00000000000..0200c6def24
--- /dev/null
+++ b/src/test/ui/binding/const-param.min.stderr
@@ -0,0 +1,9 @@
+error[E0158]: const parameters cannot be referenced in patterns
+  --> $DIR/const-param.rs:8:9
+   |
+LL |         N => {}
+   |         ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0158`.
diff --git a/src/test/ui/binding/const-param.rs b/src/test/ui/binding/const-param.rs
index 3c7f4d071f6..4aec801cb15 100644
--- a/src/test/ui/binding/const-param.rs
+++ b/src/test/ui/binding/const-param.rs
@@ -1,6 +1,7 @@
 // Identifier pattern referring to a const generic parameter is an error (issue #68853).
-
-#![feature(const_generics)] //~ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
 
 fn check<const N: usize>() {
     match 1 {
diff --git a/src/test/ui/binding/const-param.stderr b/src/test/ui/binding/const-param.stderr
deleted file mode 100644
index d3d06a2d834..00000000000
--- a/src/test/ui/binding/const-param.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/const-param.rs:3:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
-
-error[E0158]: const parameters cannot be referenced in patterns
-  --> $DIR/const-param.rs:7:9
-   |
-LL |         N => {}
-   |         ^
-
-error: aborting due to previous error; 1 warning emitted
-
-For more information about this error, try `rustc --explain E0158`.
diff --git a/src/test/ui/binop/issue-77910-1.rs b/src/test/ui/binop/issue-77910-1.rs
new file mode 100644
index 00000000000..d786e335859
--- /dev/null
+++ b/src/test/ui/binop/issue-77910-1.rs
@@ -0,0 +1,11 @@
+fn foo(s: &i32) -> &i32 {
+    let xs;
+    xs
+}
+fn main() {
+    let y;
+    // we shouldn't ice with the bound var here.
+    assert_eq!(foo, y);
+    //~^ ERROR binary operation `==` cannot be applied to type
+    //~| ERROR `for<'r> fn(&'r i32) -> &'r i32 {foo}` doesn't implement `Debug`
+}
diff --git a/src/test/ui/binop/issue-77910-1.stderr b/src/test/ui/binop/issue-77910-1.stderr
new file mode 100644
index 00000000000..e48d3e19996
--- /dev/null
+++ b/src/test/ui/binop/issue-77910-1.stderr
@@ -0,0 +1,26 @@
+error[E0369]: binary operation `==` cannot be applied to type `for<'r> fn(&'r i32) -> &'r i32 {foo}`
+  --> $DIR/issue-77910-1.rs:8:5
+   |
+LL |     assert_eq!(foo, y);
+   |     ^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     for<'r> fn(&'r i32) -> &'r i32 {foo}
+   |     _
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: `for<'r> fn(&'r i32) -> &'r i32 {foo}` doesn't implement `Debug`
+  --> $DIR/issue-77910-1.rs:8:5
+   |
+LL |     assert_eq!(foo, y);
+   |     ^^^^^^^^^^^^^^^^^^^ `for<'r> fn(&'r i32) -> &'r i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |
+   = help: the trait `Debug` is not implemented for `for<'r> fn(&'r i32) -> &'r i32 {foo}`
+   = note: required because of the requirements on the impl of `Debug` for `&for<'r> fn(&'r i32) -> &'r i32 {foo}`
+   = note: required by `std::fmt::Debug::fmt`
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0369.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/binop/issue-77910-2.rs b/src/test/ui/binop/issue-77910-2.rs
new file mode 100644
index 00000000000..2bb48d36576
--- /dev/null
+++ b/src/test/ui/binop/issue-77910-2.rs
@@ -0,0 +1,9 @@
+fn foo(s: &i32) -> &i32 {
+    let xs;
+    xs
+}
+fn main() {
+    let y;
+    if foo == y {}
+    //~^ ERROR binary operation `==` cannot be applied to type
+}
diff --git a/src/test/ui/binop/issue-77910-2.stderr b/src/test/ui/binop/issue-77910-2.stderr
new file mode 100644
index 00000000000..5477a5762a8
--- /dev/null
+++ b/src/test/ui/binop/issue-77910-2.stderr
@@ -0,0 +1,11 @@
+error[E0369]: binary operation `==` cannot be applied to type `for<'r> fn(&'r i32) -> &'r i32 {foo}`
+  --> $DIR/issue-77910-2.rs:7:12
+   |
+LL |     if foo == y {}
+   |        --- ^^ - _
+   |        |
+   |        for<'r> fn(&'r i32) -> &'r i32 {foo}
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr b/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr
index ca1496a6c8d..a4090777939 100644
--- a/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr
+++ b/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.stderr
@@ -23,7 +23,7 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
   --> $DIR/borrowck-mut-borrow-linear-errors.rs:12:30
    |
 LL |             _ => { addr.push(&mut x); }
-   |                              ^^^^^^ mutable borrow starts here in previous iteration of loop
+   |                              ^^^^^^ `x` was mutably borrowed here in the previous iteration of the loop
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/borrowck/mut-borrow-in-loop.stderr b/src/test/ui/borrowck/mut-borrow-in-loop.stderr
index 260b9673d74..b621694a548 100644
--- a/src/test/ui/borrowck/mut-borrow-in-loop.stderr
+++ b/src/test/ui/borrowck/mut-borrow-in-loop.stderr
@@ -15,7 +15,7 @@ LL | impl<'a, T : 'a> FuncWrapper<'a, T> {
 LL |             (self.func)(arg)
    |             ------------^^^-
    |             |           |
-   |             |           mutable borrow starts here in previous iteration of loop
+   |             |           `*arg` was mutably borrowed here in the previous iteration of the loop
    |             argument requires that `*arg` is borrowed for `'a`
 
 error[E0499]: cannot borrow `*arg` as mutable more than once at a time
@@ -27,7 +27,7 @@ LL | impl<'a, T : 'a> FuncWrapper<'a, T> {
 LL |             (self.func)(arg)
    |             ------------^^^-
    |             |           |
-   |             |           mutable borrow starts here in previous iteration of loop
+   |             |           `*arg` was mutably borrowed here in the previous iteration of the loop
    |             argument requires that `*arg` is borrowed for `'a`
 
 error[E0499]: cannot borrow `*arg` as mutable more than once at a time
@@ -39,7 +39,7 @@ LL | impl<'a, T : 'a> FuncWrapper<'a, T> {
 LL |             (self.func)(arg)
    |             ------------^^^-
    |             |           |
-   |             |           mutable borrow starts here in previous iteration of loop
+   |             |           `*arg` was mutably borrowed here in the previous iteration of the loop
    |             argument requires that `*arg` is borrowed for `'a`
 
 error: aborting due to 3 previous errors; 1 warning emitted
diff --git a/src/test/ui/borrowck/two-phase-across-loop.stderr b/src/test/ui/borrowck/two-phase-across-loop.stderr
index 38993a50bf6..d4e515d12bb 100644
--- a/src/test/ui/borrowck/two-phase-across-loop.stderr
+++ b/src/test/ui/borrowck/two-phase-across-loop.stderr
@@ -2,7 +2,7 @@ error[E0499]: cannot borrow `foo` as mutable more than once at a time
   --> $DIR/two-phase-across-loop.rs:17:22
    |
 LL |         strings.push(foo.get_string());
-   |                      ^^^ mutable borrow starts here in previous iteration of loop
+   |                      ^^^ `foo` was mutably borrowed here in the previous iteration of the loop
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
new file mode 100644
index 00000000000..0b94317fd71
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
@@ -0,0 +1,86 @@
+// Test that arrays are completely captured by closures by relying on the borrow check diagnostics
+
+#![feature(capture_disjoint_fields)]
+//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+
+fn arrays_1() {
+    let mut arr = [1, 2, 3, 4, 5];
+
+    let mut c = || {
+        arr[0] += 10;
+    };
+
+    // c will capture `arr` completely, therefore another index into the
+    // array can't be modified here
+    arr[1] += 10;
+    //~^ ERROR: cannot use `arr` because it was mutably borrowed
+    //~| ERROR: cannot use `arr[_]` because it was mutably borrowed
+    c();
+}
+
+fn arrays_2() {
+    let mut arr = [1, 2, 3, 4, 5];
+
+    let c = || {
+        println!("{:#?}", &arr[3..4]);
+    };
+
+    // c will capture `arr` completely, therefore another index into the
+    // array can't be modified here
+    arr[1] += 10;
+    //~^ ERROR: cannot assign to `arr[_]` because it is borrowed
+    c();
+}
+
+fn arrays_3() {
+    let mut arr = [1, 2, 3, 4, 5];
+
+    let c = || {
+        println!("{}", arr[3]);
+    };
+
+    // c will capture `arr` completely, therefore another index into the
+    // array can't be modified here
+    arr[1] += 10;
+    //~^ ERROR: cannot assign to `arr[_]` because it is borrowed
+    c();
+}
+
+fn arrays_4() {
+    let mut arr = [1, 2, 3, 4, 5];
+
+    let mut c = || {
+        arr[1] += 10;
+    };
+
+    // c will capture `arr` completely, therefore we cannot borrow another index
+    // into the array.
+    println!("{}", arr[3]);
+    //~^ ERROR: cannot use `arr` because it was mutably borrowed
+    //~| ERROR: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
+
+    c();
+}
+
+fn arrays_5() {
+    let mut arr = [1, 2, 3, 4, 5];
+
+    let mut c = || {
+        arr[1] += 10;
+    };
+
+    // c will capture `arr` completely, therefore we cannot borrow other indecies
+    // into the array.
+    println!("{:#?}", &arr[3..2]);
+    //~^ ERROR: cannot borrow `arr` as immutable because it is also borrowed as mutable
+
+    c();
+}
+
+fn main() {
+    arrays_1();
+    arrays_2();
+    arrays_3();
+    arrays_4();
+    arrays_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
new file mode 100644
index 00000000000..77e3e71bc61
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
@@ -0,0 +1,111 @@
+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
+   |
+LL |     let mut c = || {
+   |                 -- borrow of `arr` occurs here
+LL |         arr[0] += 10;
+   |         --- borrow occurs due to use of `arr` in closure
+...
+LL |     arr[1] += 10;
+   |     ^^^^^^ use of borrowed `arr`
+...
+LL |     c();
+   |     - borrow later used here
+
+error[E0503]: cannot use `arr[_]` because it was mutably borrowed
+  --> $DIR/arrays.rs:15:5
+   |
+LL |     let mut c = || {
+   |                 -- borrow of `arr` occurs here
+LL |         arr[0] += 10;
+   |         --- borrow occurs due to use of `arr` in closure
+...
+LL |     arr[1] += 10;
+   |     ^^^^^^^^^^^^ use of borrowed `arr`
+...
+LL |     c();
+   |     - borrow later used here
+
+error[E0506]: cannot assign to `arr[_]` because it is borrowed
+  --> $DIR/arrays.rs:30:5
+   |
+LL |     let c = || {
+   |             -- borrow of `arr[_]` occurs here
+LL |         println!("{:#?}", &arr[3..4]);
+   |                            --- borrow occurs due to use in closure
+...
+LL |     arr[1] += 10;
+   |     ^^^^^^^^^^^^ assignment to borrowed `arr[_]` occurs here
+LL |
+LL |     c();
+   |     - borrow later used here
+
+error[E0506]: cannot assign to `arr[_]` because it is borrowed
+  --> $DIR/arrays.rs:44:5
+   |
+LL |     let c = || {
+   |             -- borrow of `arr[_]` occurs here
+LL |         println!("{}", arr[3]);
+   |                        --- borrow occurs due to use in closure
+...
+LL |     arr[1] += 10;
+   |     ^^^^^^^^^^^^ assignment to borrowed `arr[_]` occurs here
+LL |
+LL |     c();
+   |     - borrow later used here
+
+error[E0503]: cannot use `arr` because it was mutably borrowed
+  --> $DIR/arrays.rs:58:20
+   |
+LL |     let mut c = || {
+   |                 -- borrow of `arr` occurs here
+LL |         arr[1] += 10;
+   |         --- borrow occurs due to use of `arr` in closure
+...
+LL |     println!("{}", arr[3]);
+   |                    ^^^^^^ use of borrowed `arr`
+...
+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
+   |
+LL |     let mut c = || {
+   |                 -- mutable borrow occurs here
+LL |         arr[1] += 10;
+   |         --- first borrow occurs due to use of `arr` in closure
+...
+LL |     println!("{}", arr[3]);
+   |                    ^^^^^^ immutable borrow occurs here
+...
+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
+   |
+LL |     let mut c = || {
+   |                 -- mutable borrow occurs here
+LL |         arr[1] += 10;
+   |         --- first borrow occurs due to use of `arr` in closure
+...
+LL |     println!("{:#?}", &arr[3..2]);
+   |                        ^^^ immutable borrow occurs here
+...
+LL |     c();
+   |     - mutable borrow later used here
+
+error: aborting due to 7 previous errors; 1 warning emitted
+
+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/box.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.rs
new file mode 100644
index 00000000000..15be1d8c722
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.rs
@@ -0,0 +1,65 @@
+// Test borrow checker when we precise capture when using boxes
+
+#![feature(capture_disjoint_fields)]
+//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
+
+struct MetaData { x: String, name: String }
+struct Data { m: MetaData }
+struct BoxedData(Box<Data>);
+struct EvenMoreBoxedData(Box<BoxedData>);
+
+// Check diagnostics when the same path is mutated both inside and outside the closure
+fn box_1() {
+    let m = MetaData { x: format!("x"), name: format!("name") };
+    let d = Data { m };
+    let b = BoxedData(Box::new(d));
+    let mut e = EvenMoreBoxedData(Box::new(b));
+
+    let mut c = || {
+        e.0.0.m.x = format!("not-x");
+    };
+
+    e.0.0.m.x = format!("not-x");
+    //~^ ERROR: cannot assign to `e.0.0.m.x` because it is borrowed
+    c();
+}
+
+// Check diagnostics when a path is mutated inside a closure while attempting to read it outside
+// the closure.
+fn box_2() {
+    let m = MetaData { x: format!("x"), name: format!("name") };
+    let d = Data { m };
+    let b = BoxedData(Box::new(d));
+    let mut e = EvenMoreBoxedData(Box::new(b));
+
+    let mut c = || {
+        e.0.0.m.x = format!("not-x");
+    };
+
+    println!("{}", e.0.0.m.x);
+    //~^ ERROR: cannot borrow `e.0.0.m.x` as immutable because it is also borrowed as mutable
+    c();
+}
+
+// Check diagnostics when a path is read inside a closure while attempting to mutate it outside
+// the closure.
+fn box_3() {
+    let m = MetaData { x: format!("x"), name: format!("name") };
+    let d = Data { m };
+    let b = BoxedData(Box::new(d));
+    let mut e = EvenMoreBoxedData(Box::new(b));
+
+    let c = || {
+        println!("{}", e.0.0.m.x);
+    };
+
+    e.0.0.m.x = format!("not-x");
+    //~^ ERROR: cannot assign to `e.0.0.m.x` because it is borrowed
+    c();
+}
+
+fn main() {
+    box_1();
+    box_2();
+    box_3();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr
new file mode 100644
index 00000000000..17a9332fb3e
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr
@@ -0,0 +1,55 @@
+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
+   |
+LL |     let mut c = || {
+   |                 -- borrow of `e.0.0.m.x` occurs here
+LL |         e.0.0.m.x = format!("not-x");
+   |         - borrow occurs due to use in closure
+...
+LL |     e.0.0.m.x = format!("not-x");
+   |     ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here
+LL |
+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
+   |
+LL |     let mut c = || {
+   |                 -- mutable borrow occurs here
+LL |         e.0.0.m.x = format!("not-x");
+   |         - first borrow occurs due to use of `e.0.0.m.x` in closure
+...
+LL |     println!("{}", e.0.0.m.x);
+   |                    ^^^^^^^^^ immutable borrow occurs here
+LL |
+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
+   |
+LL |     let c = || {
+   |             -- borrow of `e.0.0.m.x` occurs here
+LL |         println!("{}", e.0.0.m.x);
+   |                        - borrow occurs due to use in closure
+...
+LL |     e.0.0.m.x = format!("not-x");
+   |     ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here
+LL |
+LL |     c();
+   |     - borrow later used here
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+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/multilevel-path.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.rs
new file mode 100644
index 00000000000..39b04c833e3
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.rs
@@ -0,0 +1,28 @@
+// 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 {
+    x: i32,
+    y: i32,
+}
+struct Wrapper {
+    p: Point,
+}
+
+fn main() {
+    let mut w = Wrapper { p: Point { x: 10, y: 10 } };
+
+    let mut c = || {
+        w.p.x += 20;
+    };
+
+    let py = &mut w.p.x;
+    //~^ ERROR: cannot borrow `w.p.x` as mutable more than once at a time
+    c();
+
+    *py = 20
+}
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
new file mode 100644
index 00000000000..e5a396c4e98
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr
@@ -0,0 +1,26 @@
+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
+   |
+LL |     let mut c = || {
+   |                 -- first mutable borrow occurs here
+LL |         w.p.x += 20;
+   |         - first borrow occurs due to use of `w.p.x` in closure
+...
+LL |     let py = &mut w.p.x;
+   |              ^^^^^^^^^^ second mutable borrow occurs here
+LL |
+LL |     c();
+   |     - first borrow later used here
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0499`.
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
new file mode 100644
index 00000000000..e78d8715e48
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.rs
@@ -0,0 +1,26 @@
+// 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,
+    y: i32,
+}
+
+fn main() {
+    let mut p = Point { x: 10, y: 20 };
+
+    // `p` is captured via mutable borrow.
+    let mut c = || {
+        p.x += 10;
+        println!("{:?}", p);
+    };
+
+
+    println!("{:?}", p);
+    //~^ ERROR: cannot borrow `p` as immutable because it is also borrowed as mutable
+    c();
+}
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
new file mode 100644
index 00000000000..45a61cd98b1
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr
@@ -0,0 +1,26 @@
+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
+   |
+LL |     let mut c = || {
+   |                 -- mutable borrow occurs here
+LL |         p.x += 10;
+   |         - first borrow occurs due to use of `p` in closure
+...
+LL |     println!("{:?}", p);
+   |                      ^ immutable borrow occurs here
+LL |
+LL |     c();
+   |     - mutable borrow later used here
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0502`.
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
new file mode 100644
index 00000000000..3a66399d028
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/box.rs
@@ -0,0 +1,97 @@
+// 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>);
+struct EvenMoreBoxedData(Box<BoxedData>);
+
+// Mutate disjoint paths, one inside one outside the closure
+fn box_1() {
+    let m = MetaData { x: format!("x"), name: format!("name") };
+    let d = Data { m };
+    let b = BoxedData(Box::new(d));
+    let mut e = EvenMoreBoxedData(Box::new(b));
+
+    let mut c = || {
+        e.0.0.m.x = format!("not-x");
+    };
+
+    e.0.0.m.name = format!("not-name");
+    c();
+}
+
+// Mutate a path inside the closure and read a disjoint path outside the closure
+fn box_2() {
+    let m = MetaData { x: format!("x"), name: format!("name") };
+    let d = Data { m };
+    let b = BoxedData(Box::new(d));
+    let mut e = EvenMoreBoxedData(Box::new(b));
+
+    let mut c = || {
+        e.0.0.m.x = format!("not-x");
+    };
+
+    println!("{}", e.0.0.m.name);
+    c();
+}
+
+// Read a path inside the closure and mutate a disjoint path outside the closure
+fn box_3() {
+    let m = MetaData { x: format!("x"), name: format!("name") };
+    let d = Data { m };
+    let b = BoxedData(Box::new(d));
+    let mut e = EvenMoreBoxedData(Box::new(b));
+
+    let c = || {
+        println!("{}", e.0.0.m.name);
+    };
+
+    e.0.0.m.x = format!("not-x");
+    c();
+}
+
+// Read disjoint paths, one inside the closure and one outside the closure.
+fn box_4() {
+    let m = MetaData { x: format!("x"), name: format!("name") };
+    let d = Data { m };
+    let b = BoxedData(Box::new(d));
+    let e = EvenMoreBoxedData(Box::new(b));
+
+    let c = || {
+        println!("{}", e.0.0.m.name);
+    };
+
+    println!("{}", e.0.0.m.x);
+    c();
+}
+
+// Read the same path, once inside the closure and once outside the closure.
+fn box_5() {
+    let m = MetaData { x: format!("x"), name: format!("name") };
+    let d = Data { m };
+    let b = BoxedData(Box::new(d));
+    let e = EvenMoreBoxedData(Box::new(b));
+
+    let c = || {
+        println!("{}", e.0.0.m.name);
+    };
+
+    println!("{}", e.0.0.m.name);
+    c();
+}
+
+fn main() {
+    box_1();
+    box_2();
+    box_3();
+    box_4();
+    box_5();
+}
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
new file mode 100644
index 00000000000..9883c01b946
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/box.stderr
@@ -0,0 +1,11 @@
+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/capture-disjoint-field-struct.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.rs
new file mode 100644
index 00000000000..2c359519b76
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.rs
@@ -0,0 +1,28 @@
+// 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,
+}
+
+fn main() {
+    let mut p = Point { x: 10, y: 10 };
+
+    let c = || {
+        println!("{}", p.x);
+    };
+
+    // `c` should only capture `p.x`, therefore mutating `p.y` is allowed.
+    let py = &mut p.y;
+
+    c();
+    *py = 20;
+}
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
new file mode 100644
index 00000000000..9b0dea770fb
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-struct.stderr
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 00000000000..2c6679feabe
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.rs
@@ -0,0 +1,23 @@
+// 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() {
+    let mut t = (10, 10);
+
+    let mut c = || {
+        let t1 = &mut t.1;
+        *t1 = 20;
+    };
+
+    // Test that `c` only captures t.1, therefore reading t.0 is allowed.
+    println!("{}", t.0);
+    c();
+}
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
new file mode 100644
index 00000000000..28d09153952
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple-mut.stderr
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 00000000000..52f5cef9f01
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.rs
@@ -0,0 +1,24 @@
+// 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() {
+    let mut t = (10, 10);
+
+    let c = || {
+        println!("{}", t.0);
+    };
+
+    // `c` only captures t.0, therefore mutating t.1 is allowed.
+    let t1 = &mut t.1;
+
+    c();
+    *t1 = 20;
+}
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
new file mode 100644
index 00000000000..4fb37f85f88
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/capture-disjoint-field-tuple.stderr
@@ -0,0 +1,11 @@
+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/disjoint-capture-in-same-closure.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs
new file mode 100644
index 00000000000..3f8e197b783
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.rs
@@ -0,0 +1,27 @@
+// 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.
+
+#![allow(unused)]
+
+struct Struct {
+    x: i32,
+    y: i32,
+    s: String,
+}
+
+fn main() {
+    let mut s = Struct { x: 10, y: 10, s: String::new() };
+
+    let mut c = {
+        s.x += 10;
+        s.y += 42;
+        s.s = String::from("new");
+    };
+}
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
new file mode 100644
index 00000000000..bba90f8917a
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/disjoint-capture-in-same-closure.stderr
@@ -0,0 +1,11 @@
+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/filter-on-struct-member.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.rs
new file mode 100644
index 00000000000..8c12593430e
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.rs
@@ -0,0 +1,41 @@
+// 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,
+}
+impl Filter {
+    fn allowed(&self, x: i32) -> bool {
+        x % self.div == 1
+    }
+}
+
+struct Data {
+    filter: Filter,
+    list: Vec<i32>,
+}
+impl Data {
+    fn update(&mut self) {
+        // The closure passed to filter only captures self.filter,
+        // therefore mutating self.list is allowed.
+        self.list.retain(
+            |v| self.filter.allowed(*v),
+        );
+    }
+}
+
+fn main() {
+    let mut d = Data { filter: Filter { div: 3 }, list: Vec::new() };
+
+    for i in 1..10 {
+        d.list.push(i);
+    }
+
+    d.update();
+}
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
new file mode 100644
index 00000000000..6930e18992a
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/filter-on-struct-member.stderr
@@ -0,0 +1,11 @@
+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/multilevel-path-1.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs
new file mode 100644
index 00000000000..142c156bd56
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.rs
@@ -0,0 +1,36 @@
+// run-pass
+
+// Test that closures can catpure paths that are more precise than just one level
+// from the root variable.
+//
+// If the closures can handle such precison we should be able to mutate one path in the closure
+// 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 {
+    x: i32,
+    y: i32,
+}
+struct Wrapper {
+    p: Point,
+}
+
+fn main() {
+    let mut w = Wrapper { p: Point { x: 10, y: 10 } };
+
+    let mut c = || {
+        w.p.x += 20;
+    };
+
+    // `c` only captures `w.p.x`, therefore it's safe to mutate `w.p.y`.
+    let py = &mut w.p.y;
+    c();
+
+    *py = 20
+}
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
new file mode 100644
index 00000000000..94b877522f4
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-1.stderr
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 00000000000..d8f7d55d5aa
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.rs
@@ -0,0 +1,34 @@
+// 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
+// while being able mutate another path outside the closure, where the two paths are disjoint
+// after applying two projections on the root variable.
+
+
+struct Point {
+    x: i32,
+    y: i32,
+}
+struct Wrapper {
+    p: Point,
+}
+
+fn main() {
+    let mut w = Wrapper { p: Point { x: 10, y: 10 } };
+
+    let c = || {
+        println!("{}", w.p.x);
+    };
+
+    // `c` only captures `w.p.x`, therefore it's safe to mutate `w.p.y`.
+    let py = &mut w.p.y;
+    c();
+
+    *py = 20
+}
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
new file mode 100644
index 00000000000..100a0e167c5
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-2.stderr
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 00000000000..fc3d48ec458
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.rs
@@ -0,0 +1,31 @@
+// 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
+// both inside and outside the closure at the same time.
+
+struct Point {
+    x: i32,
+    y: i32,
+}
+struct Wrapper {
+    p: Point,
+}
+
+fn main() {
+    let mut w = Wrapper { p: Point { x: 10, y: 10 } };
+
+    let c = || {
+        println!("{}", w.p.x);
+    };
+
+    let px = &w.p.x;
+    c();
+
+    println!("{}", px);
+}
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
new file mode 100644
index 00000000000..cf5be6a00e9
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/multilevel-path-3.stderr
@@ -0,0 +1,11 @@
+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/nested-closure.rs b/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.rs
new file mode 100644
index 00000000000..238580929ef
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.rs
@@ -0,0 +1,40 @@
+// 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,
+}
+
+fn main() {
+    let mut p = Point { x: 5, y: 20 };
+
+    // c1 should capture `p.x` via immutable borrow and
+    // `p.y` via mutable borrow.
+    let mut c1 = || {
+        println!("{}", p.x);
+
+        let incr = 10;
+
+        let mut c2 = || p.y += incr;
+        c2();
+
+        println!("{}", p.y);
+    };
+
+    c1();
+
+    // This should not throw an error because `p.x` is borrowed via Immutable borrow,
+    // and multiple immutable borrow of the same place are allowed.
+    let px = &p.x;
+
+    println!("{}", px);
+
+    c1();
+}
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
new file mode 100644
index 00000000000..293aa82ce9f
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/run_pass/nested-closure.stderr
@@ -0,0 +1,11 @@
+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/compile-fail/coerce-unsafe-closure-to-unsafe-fn-ptr.rs b/src/test/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.rs
index 36777693fab..36777693fab 100644
--- a/src/test/compile-fail/coerce-unsafe-closure-to-unsafe-fn-ptr.rs
+++ b/src/test/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.rs
diff --git a/src/test/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.stderr b/src/test/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.stderr
new file mode 100644
index 00000000000..a1fb1c02e46
--- /dev/null
+++ b/src/test/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.stderr
@@ -0,0 +1,11 @@
+error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+  --> $DIR/coerce-unsafe-closure-to-unsafe-fn-ptr.rs:2:31
+   |
+LL |     let _: unsafe fn() = || { ::std::pin::Pin::new_unchecked(&0_u8); };
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/compile-fail/coerce-unsafe-to-closure.rs b/src/test/ui/closures/coerce-unsafe-to-closure.rs
index 78bdd36f9cc..78bdd36f9cc 100644
--- a/src/test/compile-fail/coerce-unsafe-to-closure.rs
+++ b/src/test/ui/closures/coerce-unsafe-to-closure.rs
diff --git a/src/test/ui/closures/coerce-unsafe-to-closure.stderr b/src/test/ui/closures/coerce-unsafe-to-closure.stderr
new file mode 100644
index 00000000000..ab035d03b05
--- /dev/null
+++ b/src/test/ui/closures/coerce-unsafe-to-closure.stderr
@@ -0,0 +1,11 @@
+error[E0277]: expected a `FnOnce<(&str,)>` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
+  --> $DIR/coerce-unsafe-to-closure.rs:2:44
+   |
+LL |     let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
+   |                                            ^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&str,)>` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
+   |
+   = help: the trait `FnOnce<(&str,)>` is not implemented for `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/const-generics/apit-with-const-param.rs b/src/test/ui/const-generics/apit-with-const-param.rs
index facc0bcf513..3bc62141927 100644
--- a/src/test/ui/const-generics/apit-with-const-param.rs
+++ b/src/test/ui/const-generics/apit-with-const-param.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait Trait {}
 
diff --git a/src/test/ui/const-generics/arg-in-pat-1.rs b/src/test/ui/const-generics/arg-in-pat-1.rs
new file mode 100644
index 00000000000..82555084e41
--- /dev/null
+++ b/src/test/ui/const-generics/arg-in-pat-1.rs
@@ -0,0 +1,23 @@
+// check-pass
+enum ConstGenericEnum<const N: usize> {
+    Foo([i32; N]),
+    Bar,
+}
+
+fn foo<const N: usize>(val: &ConstGenericEnum<N>) {
+    if let ConstGenericEnum::<N>::Foo(field, ..) = val {}
+}
+
+fn bar<const N: usize>(val: &ConstGenericEnum<N>) {
+    match val {
+        ConstGenericEnum::<N>::Foo(field, ..) => (),
+        ConstGenericEnum::<N>::Bar => (),
+    }
+}
+
+fn main() {
+    match ConstGenericEnum::Bar {
+        ConstGenericEnum::<3>::Foo(field, ..) => (),
+        ConstGenericEnum::<3>::Bar => (),
+    }
+}
diff --git a/src/test/ui/const-generics/arg-in-pat-2.rs b/src/test/ui/const-generics/arg-in-pat-2.rs
new file mode 100644
index 00000000000..dc9e722eda8
--- /dev/null
+++ b/src/test/ui/const-generics/arg-in-pat-2.rs
@@ -0,0 +1,10 @@
+// check-pass
+enum Generic<const N: usize> {
+    Variant,
+}
+
+fn main() {
+    match todo!() {
+        Generic::<0usize>::Variant => todo!()
+    }
+}
diff --git a/src/test/ui/const-generics/arg-in-pat-3.rs b/src/test/ui/const-generics/arg-in-pat-3.rs
new file mode 100644
index 00000000000..24626a3b68a
--- /dev/null
+++ b/src/test/ui/const-generics/arg-in-pat-3.rs
@@ -0,0 +1,43 @@
+// check-pass
+struct Foo<const N: usize>;
+
+fn bindingp() {
+    match Foo {
+        mut x @ Foo::<3> => {
+            let ref mut _x @ Foo::<3> = x;
+        }
+    }
+}
+
+struct Bar<const N: usize> {
+    field: Foo<N>,
+}
+
+fn structp() {
+    match todo!() {
+        Bar::<3> {
+            field: Foo::<3>,
+        } => (),
+    }
+}
+
+struct Baz<const N: usize>(Foo<N>);
+
+fn tuplestructp() {
+    match Baz(Foo) {
+        Baz::<3>(Foo::<3>) => (),
+    }
+}
+
+impl<const N: usize> Baz<N> {
+    const ASSOC: usize = 3;
+}
+
+fn pathp() {
+    match 3 {
+        Baz::<3>::ASSOC => (),
+        _ => (),
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/argument_order.full.stderr b/src/test/ui/const-generics/argument_order.full.stderr
index b52e5050703..e533d4f7fb8 100644
--- a/src/test/ui/const-generics/argument_order.full.stderr
+++ b/src/test/ui/const-generics/argument_order.full.stderr
@@ -1,11 +1,11 @@
 error: lifetime parameters must be declared prior to const parameters
-  --> $DIR/argument_order.rs:12:32
+  --> $DIR/argument_order.rs:11:32
    |
 LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
    |               -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, const N: usize, T, const M: usize, U>`
 
 error[E0747]: lifetime provided when a type was expected
-  --> $DIR/argument_order.rs:20:23
+  --> $DIR/argument_order.rs:19:23
    |
 LL |     let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
    |                       ^^^^^^^
diff --git a/src/test/ui/const-generics/argument_order.min.stderr b/src/test/ui/const-generics/argument_order.min.stderr
index 728ae69b41f..f23bc6d6a2b 100644
--- a/src/test/ui/const-generics/argument_order.min.stderr
+++ b/src/test/ui/const-generics/argument_order.min.stderr
@@ -1,23 +1,23 @@
 error: type parameters must be declared prior to const parameters
-  --> $DIR/argument_order.rs:6:28
+  --> $DIR/argument_order.rs:5:28
    |
 LL | struct Bad<const N: usize, T> {
    |           -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
 
 error: lifetime parameters must be declared prior to const parameters
-  --> $DIR/argument_order.rs:12:32
+  --> $DIR/argument_order.rs:11:32
    |
 LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
    |               -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T, U, const N: usize, const M: usize>`
 
 error: type parameters must be declared prior to const parameters
-  --> $DIR/argument_order.rs:12:36
+  --> $DIR/argument_order.rs:11:36
    |
 LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {
    |               ---------------------^----------------------^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T, U, const N: usize, const M: usize>`
 
 error[E0747]: lifetime provided when a type was expected
-  --> $DIR/argument_order.rs:20:23
+  --> $DIR/argument_order.rs:19:23
    |
 LL |     let _: AlsoBad<7, 'static, u32, 'static, 17, u16>;
    |                       ^^^^^^^
diff --git a/src/test/ui/const-generics/argument_order.rs b/src/test/ui/const-generics/argument_order.rs
index 507baf5fd75..95eaeea5818 100644
--- a/src/test/ui/const-generics/argument_order.rs
+++ b/src/test/ui/const-generics/argument_order.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Bad<const N: usize, T> {
     //[min]~^ ERROR type parameters must be declared prior to const parameters
diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.full.stderr b/src/test/ui/const-generics/array-size-in-generic-struct-param.full.stderr
index cf4487b5829..0fb23e41b01 100644
--- a/src/test/ui/const-generics/array-size-in-generic-struct-param.full.stderr
+++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/array-size-in-generic-struct-param.rs:9:38
+  --> $DIR/array-size-in-generic-struct-param.rs:8:38
    |
 LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
    |                                      ^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
    = note: this may fail depending on what value the parameter takes
 
 error: constant expression depends on a generic parameter
-  --> $DIR/array-size-in-generic-struct-param.rs:20:10
+  --> $DIR/array-size-in-generic-struct-param.rs:19:10
    |
 LL |     arr: [u8; CFG.arr_size],
    |          ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr b/src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr
index 73c9ea59c95..7af23103ce7 100644
--- a/src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr
+++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/array-size-in-generic-struct-param.rs:9:48
+  --> $DIR/array-size-in-generic-struct-param.rs:8:48
    |
 LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
    |                                                ^ cannot perform const operation using `N`
@@ -8,7 +8,7 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/array-size-in-generic-struct-param.rs:20:15
+  --> $DIR/array-size-in-generic-struct-param.rs:19:15
    |
 LL |     arr: [u8; CFG.arr_size],
    |               ^^^ cannot perform const operation using `CFG`
@@ -17,7 +17,7 @@ LL |     arr: [u8; CFG.arr_size],
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: `Config` is forbidden as the type of a const generic parameter
-  --> $DIR/array-size-in-generic-struct-param.rs:18:21
+  --> $DIR/array-size-in-generic-struct-param.rs:17:21
    |
 LL | struct B<const CFG: Config> {
    |                     ^^^^^^
diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.rs b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs
index 768180d0813..cd0a9742cd1 100644
--- a/src/test/ui/const-generics/array-size-in-generic-struct-param.rs
+++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 #[allow(dead_code)]
 struct ArithArrayLen<const N: usize>([u32; 0 + N]);
diff --git a/src/test/ui/const-generics/array-wrapper-struct-ctor.rs b/src/test/ui/const-generics/array-wrapper-struct-ctor.rs
index 390b6cc2049..732a1871456 100644
--- a/src/test/ui/const-generics/array-wrapper-struct-ctor.rs
+++ b/src/test/ui/const-generics/array-wrapper-struct-ctor.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 #![allow(dead_code)]
 
diff --git a/src/test/ui/const-generics/associated-type-bound-fail.full.stderr b/src/test/ui/const-generics/associated-type-bound-fail.full.stderr
index 8ccbe5dee0e..6644e74f97a 100644
--- a/src/test/ui/const-generics/associated-type-bound-fail.full.stderr
+++ b/src/test/ui/const-generics/associated-type-bound-fail.full.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `u16: Bar<N>` is not satisfied
-  --> $DIR/associated-type-bound-fail.rs:14:5
+  --> $DIR/associated-type-bound-fail.rs:13:5
    |
 LL |     type Assoc: Bar<N>;
    |                 ------ required by this bound in `Foo::Assoc`
diff --git a/src/test/ui/const-generics/associated-type-bound-fail.min.stderr b/src/test/ui/const-generics/associated-type-bound-fail.min.stderr
index 8ccbe5dee0e..6644e74f97a 100644
--- a/src/test/ui/const-generics/associated-type-bound-fail.min.stderr
+++ b/src/test/ui/const-generics/associated-type-bound-fail.min.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `u16: Bar<N>` is not satisfied
-  --> $DIR/associated-type-bound-fail.rs:14:5
+  --> $DIR/associated-type-bound-fail.rs:13:5
    |
 LL |     type Assoc: Bar<N>;
    |                 ------ required by this bound in `Foo::Assoc`
diff --git a/src/test/ui/const-generics/associated-type-bound-fail.rs b/src/test/ui/const-generics/associated-type-bound-fail.rs
index 3440b1356c2..83b26700805 100644
--- a/src/test/ui/const-generics/associated-type-bound-fail.rs
+++ b/src/test/ui/const-generics/associated-type-bound-fail.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait Bar<const N: usize> {}
 
diff --git a/src/test/ui/const-generics/associated-type-bound.rs b/src/test/ui/const-generics/associated-type-bound.rs
index 374a49194b1..02f77396c0b 100644
--- a/src/test/ui/const-generics/associated-type-bound.rs
+++ b/src/test/ui/const-generics/associated-type-bound.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait Bar<const N: usize> {}
 
diff --git a/src/test/ui/const-generics/auxiliary/const_generic_lib.rs b/src/test/ui/const-generics/auxiliary/const_generic_lib.rs
index 899a5a1836c..8d4cd9c0d6b 100644
--- a/src/test/ui/const-generics/auxiliary/const_generic_lib.rs
+++ b/src/test/ui/const-generics/auxiliary/const_generic_lib.rs
@@ -1,6 +1,5 @@
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub struct Struct<const N: usize>(pub [u8; N]);
 
diff --git a/src/test/ui/const-generics/auxiliary/crayte.rs b/src/test/ui/const-generics/auxiliary/crayte.rs
index 725005971e1..d9baab956c9 100644
--- a/src/test/ui/const-generics/auxiliary/crayte.rs
+++ b/src/test/ui/const-generics/auxiliary/crayte.rs
@@ -1,7 +1,6 @@
 // edition:2018
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub trait Foo<const N: usize> {}
 struct Local;
diff --git a/src/test/ui/const-generics/auxiliary/impl-const.rs b/src/test/ui/const-generics/auxiliary/impl-const.rs
index 2e25dadf119..4a6b5784221 100644
--- a/src/test/ui/const-generics/auxiliary/impl-const.rs
+++ b/src/test/ui/const-generics/auxiliary/impl-const.rs
@@ -1,6 +1,5 @@
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub struct Num<const N: usize>;
 
diff --git a/src/test/ui/const-generics/broken-mir-1.rs b/src/test/ui/const-generics/broken-mir-1.rs
index d13ae12c03b..34255fa9f58 100644
--- a/src/test/ui/const-generics/broken-mir-1.rs
+++ b/src/test/ui/const-generics/broken-mir-1.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub trait Foo {
     fn foo(&self);
diff --git a/src/test/ui/const-generics/broken-mir-2.rs b/src/test/ui/const-generics/broken-mir-2.rs
index 2f9afe0b464..ac358b01672 100644
--- a/src/test/ui/const-generics/broken-mir-2.rs
+++ b/src/test/ui/const-generics/broken-mir-2.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 use std::fmt::Debug;
 
diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs
index 931f6ade7f1..44aef859f2d 100644
--- a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs
+++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 // This test confirms that the types can be inferred correctly for this example with const
 // generics. Previously this would ICE, and more recently error.
diff --git a/src/test/ui/const-generics/closing-args-token.full.stderr b/src/test/ui/const-generics/closing-args-token.full.stderr
index 1c3ddd345a5..7737705440e 100644
--- a/src/test/ui/const-generics/closing-args-token.full.stderr
+++ b/src/test/ui/const-generics/closing-args-token.full.stderr
@@ -1,5 +1,5 @@
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/closing-args-token.rs:11:9
+  --> $DIR/closing-args-token.rs:10:9
    |
 LL |     S::<5 + 2 >> 7>;
    |         ^^^^^
@@ -10,7 +10,7 @@ LL |     S::<{ 5 + 2 } >> 7>;
    |         ^       ^
 
 error: comparison operators cannot be chained
-  --> $DIR/closing-args-token.rs:11:16
+  --> $DIR/closing-args-token.rs:10:16
    |
 LL |     S::<5 + 2 >> 7>;
    |                ^  ^
@@ -21,7 +21,7 @@ LL |     S::<5 + 2 >> 7 && 7>;
    |                    ^^^^
 
 error: comparison operators cannot be chained
-  --> $DIR/closing-args-token.rs:17:20
+  --> $DIR/closing-args-token.rs:16:20
    |
 LL |     S::<{ 5 + 2 } >> 7>;
    |                    ^  ^
@@ -32,13 +32,13 @@ LL |     S::<{ 5 + 2 } >> 7 && 7>;
    |                        ^^^^
 
 error: expected expression, found `;`
-  --> $DIR/closing-args-token.rs:22:16
+  --> $DIR/closing-args-token.rs:21:16
    |
 LL |     T::<0 >= 3>;
    |                ^ expected expression
 
 error: comparison operators cannot be chained
-  --> $DIR/closing-args-token.rs:28:12
+  --> $DIR/closing-args-token.rs:27:12
    |
 LL |     T::<x >>= 2 > 0>;
    |            ^^   ^
diff --git a/src/test/ui/const-generics/closing-args-token.min.stderr b/src/test/ui/const-generics/closing-args-token.min.stderr
index 1c3ddd345a5..7737705440e 100644
--- a/src/test/ui/const-generics/closing-args-token.min.stderr
+++ b/src/test/ui/const-generics/closing-args-token.min.stderr
@@ -1,5 +1,5 @@
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/closing-args-token.rs:11:9
+  --> $DIR/closing-args-token.rs:10:9
    |
 LL |     S::<5 + 2 >> 7>;
    |         ^^^^^
@@ -10,7 +10,7 @@ LL |     S::<{ 5 + 2 } >> 7>;
    |         ^       ^
 
 error: comparison operators cannot be chained
-  --> $DIR/closing-args-token.rs:11:16
+  --> $DIR/closing-args-token.rs:10:16
    |
 LL |     S::<5 + 2 >> 7>;
    |                ^  ^
@@ -21,7 +21,7 @@ LL |     S::<5 + 2 >> 7 && 7>;
    |                    ^^^^
 
 error: comparison operators cannot be chained
-  --> $DIR/closing-args-token.rs:17:20
+  --> $DIR/closing-args-token.rs:16:20
    |
 LL |     S::<{ 5 + 2 } >> 7>;
    |                    ^  ^
@@ -32,13 +32,13 @@ LL |     S::<{ 5 + 2 } >> 7 && 7>;
    |                        ^^^^
 
 error: expected expression, found `;`
-  --> $DIR/closing-args-token.rs:22:16
+  --> $DIR/closing-args-token.rs:21:16
    |
 LL |     T::<0 >= 3>;
    |                ^ expected expression
 
 error: comparison operators cannot be chained
-  --> $DIR/closing-args-token.rs:28:12
+  --> $DIR/closing-args-token.rs:27:12
    |
 LL |     T::<x >>= 2 > 0>;
    |            ^^   ^
diff --git a/src/test/ui/const-generics/closing-args-token.rs b/src/test/ui/const-generics/closing-args-token.rs
index 8699637c54e..a9b552ebed7 100644
--- a/src/test/ui/const-generics/closing-args-token.rs
+++ b/src/test/ui/const-generics/closing-args-token.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct S<const X: u32>;
 struct T<const X: bool>;
diff --git a/src/test/ui/const-generics/coerce_unsized_array.rs b/src/test/ui/const-generics/coerce_unsized_array.rs
index a3c295f73c7..8e20df28103 100644
--- a/src/test/ui/const-generics/coerce_unsized_array.rs
+++ b/src/test/ui/const-generics/coerce_unsized_array.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn foo<const N: usize>(v: &[u8; N]) -> &[u8] {
     v
diff --git a/src/test/ui/const-generics/concrete-const-as-fn-arg.rs b/src/test/ui/const-generics/concrete-const-as-fn-arg.rs
index 7771bf33601..8c31c8651a2 100644
--- a/src/test/ui/const-generics/concrete-const-as-fn-arg.rs
+++ b/src/test/ui/const-generics/concrete-const-as-fn-arg.rs
@@ -4,7 +4,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct A<const N: usize>; // ok
 
diff --git a/src/test/ui/const-generics/concrete-const-impl-method.rs b/src/test/ui/const-generics/concrete-const-impl-method.rs
index edb403ce8fd..3d3bd2664c8 100644
--- a/src/test/ui/const-generics/concrete-const-impl-method.rs
+++ b/src/test/ui/const-generics/concrete-const-impl-method.rs
@@ -5,7 +5,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub struct A<const N: u32>;
 
diff --git a/src/test/ui/const-generics/condition-in-trait-const-arg.rs b/src/test/ui/const-generics/condition-in-trait-const-arg.rs
index 77b68052fc0..ad40b48afe5 100644
--- a/src/test/ui/const-generics/condition-in-trait-const-arg.rs
+++ b/src/test/ui/const-generics/condition-in-trait-const-arg.rs
@@ -4,7 +4,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait IsZeroTrait<const IS_ZERO: bool>{}
 
diff --git a/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr b/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr
index 042fa9ad958..bfa4ba30686 100644
--- a/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr
+++ b/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:14:23
+  --> $DIR/const-arg-in-const-arg.rs:13:23
    |
 LL |     let _: [u8; foo::<T>()];
    |                       ^ cannot perform const operation using `T`
@@ -8,7 +8,7 @@ LL |     let _: [u8; foo::<T>()];
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:15:23
+  --> $DIR/const-arg-in-const-arg.rs:14:23
    |
 LL |     let _: [u8; bar::<N>()];
    |                       ^ cannot perform const operation using `N`
@@ -17,7 +17,7 @@ LL |     let _: [u8; bar::<N>()];
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:25:23
+  --> $DIR/const-arg-in-const-arg.rs:24:23
    |
 LL |     let _ = [0; bar::<N>()];
    |                       ^ cannot perform const operation using `N`
@@ -26,7 +26,7 @@ LL |     let _ = [0; bar::<N>()];
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:30:24
+  --> $DIR/const-arg-in-const-arg.rs:29:24
    |
 LL |     let _: Foo<{ foo::<T>() }>;
    |                        ^ cannot perform const operation using `T`
@@ -35,7 +35,7 @@ LL |     let _: Foo<{ foo::<T>() }>;
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:31:24
+  --> $DIR/const-arg-in-const-arg.rs:30:24
    |
 LL |     let _: Foo<{ bar::<N>() }>;
    |                        ^ cannot perform const operation using `N`
@@ -44,7 +44,7 @@ LL |     let _: Foo<{ bar::<N>() }>;
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:36:27
+  --> $DIR/const-arg-in-const-arg.rs:35:27
    |
 LL |     let _ = Foo::<{ foo::<T>() }>;
    |                           ^ cannot perform const operation using `T`
@@ -53,7 +53,7 @@ LL |     let _ = Foo::<{ foo::<T>() }>;
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/const-arg-in-const-arg.rs:37:27
+  --> $DIR/const-arg-in-const-arg.rs:36:27
    |
 LL |     let _ = Foo::<{ bar::<N>() }>;
    |                           ^ cannot perform const operation using `N`
@@ -62,7 +62,7 @@ LL |     let _ = Foo::<{ bar::<N>() }>;
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:16:23
+  --> $DIR/const-arg-in-const-arg.rs:15:23
    |
 LL |     let _: [u8; faz::<'a>(&())];
    |                       ^^
@@ -71,7 +71,7 @@ LL |     let _: [u8; faz::<'a>(&())];
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:17:23
+  --> $DIR/const-arg-in-const-arg.rs:16:23
    |
 LL |     let _: [u8; baz::<'a>(&())];
    |                       ^^
@@ -80,7 +80,7 @@ LL |     let _: [u8; baz::<'a>(&())];
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:18:23
+  --> $DIR/const-arg-in-const-arg.rs:17:23
    |
 LL |     let _: [u8; faz::<'b>(&())];
    |                       ^^
@@ -89,7 +89,7 @@ LL |     let _: [u8; faz::<'b>(&())];
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:19:23
+  --> $DIR/const-arg-in-const-arg.rs:18:23
    |
 LL |     let _: [u8; baz::<'b>(&())];
    |                       ^^
@@ -98,7 +98,7 @@ LL |     let _: [u8; baz::<'b>(&())];
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:26:23
+  --> $DIR/const-arg-in-const-arg.rs:25:23
    |
 LL |     let _ = [0; faz::<'a>(&())];
    |                       ^^
@@ -107,7 +107,7 @@ LL |     let _ = [0; faz::<'a>(&())];
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:27:23
+  --> $DIR/const-arg-in-const-arg.rs:26:23
    |
 LL |     let _ = [0; baz::<'a>(&())];
    |                       ^^
@@ -116,7 +116,7 @@ LL |     let _ = [0; baz::<'a>(&())];
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:28:23
+  --> $DIR/const-arg-in-const-arg.rs:27:23
    |
 LL |     let _ = [0; faz::<'b>(&())];
    |                       ^^
@@ -125,7 +125,7 @@ LL |     let _ = [0; faz::<'b>(&())];
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:29:23
+  --> $DIR/const-arg-in-const-arg.rs:28:23
    |
 LL |     let _ = [0; baz::<'b>(&())];
    |                       ^^
@@ -134,7 +134,7 @@ LL |     let _ = [0; baz::<'b>(&())];
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:32:24
+  --> $DIR/const-arg-in-const-arg.rs:31:24
    |
 LL |     let _: Foo<{ faz::<'a>(&()) }>;
    |                        ^^
@@ -143,7 +143,7 @@ LL |     let _: Foo<{ faz::<'a>(&()) }>;
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:33:24
+  --> $DIR/const-arg-in-const-arg.rs:32:24
    |
 LL |     let _: Foo<{ baz::<'a>(&()) }>;
    |                        ^^
@@ -152,7 +152,7 @@ LL |     let _: Foo<{ baz::<'a>(&()) }>;
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:34:24
+  --> $DIR/const-arg-in-const-arg.rs:33:24
    |
 LL |     let _: Foo<{ faz::<'b>(&()) }>;
    |                        ^^
@@ -161,7 +161,7 @@ LL |     let _: Foo<{ faz::<'b>(&()) }>;
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:35:24
+  --> $DIR/const-arg-in-const-arg.rs:34:24
    |
 LL |     let _: Foo<{ baz::<'b>(&()) }>;
    |                        ^^
@@ -170,7 +170,7 @@ LL |     let _: Foo<{ baz::<'b>(&()) }>;
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:38:27
+  --> $DIR/const-arg-in-const-arg.rs:37:27
    |
 LL |     let _ = Foo::<{ faz::<'a>(&()) }>;
    |                           ^^
@@ -179,7 +179,7 @@ LL |     let _ = Foo::<{ faz::<'a>(&()) }>;
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:39:27
+  --> $DIR/const-arg-in-const-arg.rs:38:27
    |
 LL |     let _ = Foo::<{ baz::<'a>(&()) }>;
    |                           ^^
@@ -188,7 +188,7 @@ LL |     let _ = Foo::<{ baz::<'a>(&()) }>;
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:40:27
+  --> $DIR/const-arg-in-const-arg.rs:39:27
    |
 LL |     let _ = Foo::<{ faz::<'b>(&()) }>;
    |                           ^^
@@ -197,7 +197,7 @@ LL |     let _ = Foo::<{ faz::<'b>(&()) }>;
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/const-arg-in-const-arg.rs:41:27
+  --> $DIR/const-arg-in-const-arg.rs:40:27
    |
 LL |     let _ = Foo::<{ baz::<'b>(&()) }>;
    |                           ^^
diff --git a/src/test/ui/const-generics/const-arg-in-const-arg.rs b/src/test/ui/const-generics/const-arg-in-const-arg.rs
index 9927538ef50..8279f4a3f61 100644
--- a/src/test/ui/const-generics/const-arg-in-const-arg.rs
+++ b/src/test/ui/const-generics/const-arg-in-const-arg.rs
@@ -2,7 +2,6 @@
 // FIXME(const_generics): This test currently causes an ICE because
 // we don't yet correctly deal with lifetimes, reenable this test once
 // this is fixed.
-#![cfg_attr(min, feature(min_const_generics))]
 
 const fn foo<T>() -> usize { std::mem::size_of::<T>() }
 const fn bar<const N: usize>() -> usize { N }
diff --git a/src/test/ui/const-generics/const-arg-in-fn.rs b/src/test/ui/const-generics/const-arg-in-fn.rs
index 5c438efd82a..43ed12efb89 100644
--- a/src/test/ui/const-generics/const-arg-in-fn.rs
+++ b/src/test/ui/const-generics/const-arg-in-fn.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn const_u32_identity<const X: u32>() -> u32 {
     X
diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.full.stderr b/src/test/ui/const-generics/const-arg-type-arg-misordered.full.stderr
index 3827002ff4b..d0ea51ea417 100644
--- a/src/test/ui/const-generics/const-arg-type-arg-misordered.full.stderr
+++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.full.stderr
@@ -1,5 +1,5 @@
 error[E0747]: constant provided when a type was expected
-  --> $DIR/const-arg-type-arg-misordered.rs:8:35
+  --> $DIR/const-arg-type-arg-misordered.rs:7:35
    |
 LL | fn foo<const N: usize>() -> Array<N, ()> {
    |                                   ^
diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr b/src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr
index 2c5fc8dcc01..d7b7df0eb55 100644
--- a/src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr
+++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.min.stderr
@@ -1,5 +1,5 @@
 error[E0747]: constant provided when a type was expected
-  --> $DIR/const-arg-type-arg-misordered.rs:8:35
+  --> $DIR/const-arg-type-arg-misordered.rs:7:35
    |
 LL | fn foo<const N: usize>() -> Array<N, ()> {
    |                                   ^
diff --git a/src/test/ui/const-generics/const-arg-type-arg-misordered.rs b/src/test/ui/const-generics/const-arg-type-arg-misordered.rs
index 6680f772fa3..5415791d21b 100644
--- a/src/test/ui/const-generics/const-arg-type-arg-misordered.rs
+++ b/src/test/ui/const-generics/const-arg-type-arg-misordered.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 type Array<T, const N: usize> = [T; N];
 
diff --git a/src/test/ui/const-generics/const-argument-if-length.full.stderr b/src/test/ui/const-generics/const-argument-if-length.full.stderr
index 4d627f05adc..5dca01f0dc0 100644
--- a/src/test/ui/const-generics/const-argument-if-length.full.stderr
+++ b/src/test/ui/const-generics/const-argument-if-length.full.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the size for values of type `T` cannot be known at compilation time
-  --> $DIR/const-argument-if-length.rs:8:28
+  --> $DIR/const-argument-if-length.rs:7:28
    |
 LL | pub const fn is_zst<T: ?Sized>() -> usize {
    |                     - this type parameter needs to be `Sized`
@@ -12,7 +12,7 @@ LL | pub const fn size_of<T>() -> usize {
    |                      - required by this bound in `std::mem::size_of`
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
-  --> $DIR/const-argument-if-length.rs:17:12
+  --> $DIR/const-argument-if-length.rs:16:12
    |
 LL | pub struct AtLeastByte<T: ?Sized> {
    |                        - this type parameter needs to be `Sized`
diff --git a/src/test/ui/const-generics/const-argument-if-length.min.stderr b/src/test/ui/const-generics/const-argument-if-length.min.stderr
index 8a1074392a5..ea177c19746 100644
--- a/src/test/ui/const-generics/const-argument-if-length.min.stderr
+++ b/src/test/ui/const-generics/const-argument-if-length.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/const-argument-if-length.rs:19:24
+  --> $DIR/const-argument-if-length.rs:18:24
    |
 LL |     pad: [u8; is_zst::<T>()],
    |                        ^ cannot perform const operation using `T`
@@ -8,7 +8,7 @@ LL |     pad: [u8; is_zst::<T>()],
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
-  --> $DIR/const-argument-if-length.rs:17:12
+  --> $DIR/const-argument-if-length.rs:16:12
    |
 LL | pub struct AtLeastByte<T: ?Sized> {
    |                        - this type parameter needs to be `Sized`
diff --git a/src/test/ui/const-generics/const-argument-if-length.rs b/src/test/ui/const-generics/const-argument-if-length.rs
index 80907383124..67ed85f96af 100644
--- a/src/test/ui/const-generics/const-argument-if-length.rs
+++ b/src/test/ui/const-generics/const-argument-if-length.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub const fn is_zst<T: ?Sized>() -> usize {
     if std::mem::size_of::<T>() == 0 {
diff --git a/src/test/ui/const-generics/const-expression-parameter.full.stderr b/src/test/ui/const-generics/const-expression-parameter.full.stderr
index 0615a4c206d..93c5173554f 100644
--- a/src/test/ui/const-generics/const-expression-parameter.full.stderr
+++ b/src/test/ui/const-generics/const-expression-parameter.full.stderr
@@ -1,5 +1,5 @@
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/const-expression-parameter.rs:16:20
+  --> $DIR/const-expression-parameter.rs:15:20
    |
 LL |     i32_identity::<1 + 2>();
    |                    ^^^^^
diff --git a/src/test/ui/const-generics/const-expression-parameter.min.stderr b/src/test/ui/const-generics/const-expression-parameter.min.stderr
index 0615a4c206d..93c5173554f 100644
--- a/src/test/ui/const-generics/const-expression-parameter.min.stderr
+++ b/src/test/ui/const-generics/const-expression-parameter.min.stderr
@@ -1,5 +1,5 @@
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/const-expression-parameter.rs:16:20
+  --> $DIR/const-expression-parameter.rs:15:20
    |
 LL |     i32_identity::<1 + 2>();
    |                    ^^^^^
diff --git a/src/test/ui/const-generics/const-expression-parameter.rs b/src/test/ui/const-generics/const-expression-parameter.rs
index 3ef7c8b32e0..cb609a56416 100644
--- a/src/test/ui/const-generics/const-expression-parameter.rs
+++ b/src/test/ui/const-generics/const-expression-parameter.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn i32_identity<const X: i32>() -> i32 {
     5
diff --git a/src/test/ui/const-generics/const-fn-with-const-param.rs b/src/test/ui/const-generics/const-fn-with-const-param.rs
index add1290b1d9..5c1ee4e0d5a 100644
--- a/src/test/ui/const-generics/const-fn-with-const-param.rs
+++ b/src/test/ui/const-generics/const-fn-with-const-param.rs
@@ -4,7 +4,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 const fn const_u32_identity<const X: u32>() -> u32 {
     X
diff --git a/src/test/ui/const-generics/const-generic-array-wrapper.rs b/src/test/ui/const-generics/const-generic-array-wrapper.rs
index 34edd0b4a8e..224fc794e32 100644
--- a/src/test/ui/const-generics/const-generic-array-wrapper.rs
+++ b/src/test/ui/const-generics/const-generic-array-wrapper.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo<T, const N: usize>([T; N]);
 
diff --git a/src/test/ui/const-generics/const-generic-type_name.rs b/src/test/ui/const-generics/const-generic-type_name.rs
index a954c026352..95632f79896 100644
--- a/src/test/ui/const-generics/const-generic-type_name.rs
+++ b/src/test/ui/const-generics/const-generic-type_name.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 #[derive(Debug)]
 struct S<const N: usize>;
diff --git a/src/test/ui/const-generics/const-param-after-const-literal-arg.rs b/src/test/ui/const-generics/const-param-after-const-literal-arg.rs
index 3982f7a7f12..6c2b14f2770 100644
--- a/src/test/ui/const-generics/const-param-after-const-literal-arg.rs
+++ b/src/test/ui/const-generics/const-param-after-const-literal-arg.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo<const A: usize, const B: usize>;
 
diff --git a/src/test/ui/const-generics/const-param-before-other-params.full.stderr b/src/test/ui/const-generics/const-param-before-other-params.full.stderr
index c2acaabbd88..09a4f66de39 100644
--- a/src/test/ui/const-generics/const-param-before-other-params.full.stderr
+++ b/src/test/ui/const-generics/const-param-before-other-params.full.stderr
@@ -1,5 +1,5 @@
 error: lifetime parameters must be declared prior to const parameters
-  --> $DIR/const-param-before-other-params.rs:6:21
+  --> $DIR/const-param-before-other-params.rs:5:21
    |
 LL | fn bar<const X: (), 'a>(_: &'a ()) {
    |       --------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const X: ()>`
diff --git a/src/test/ui/const-generics/const-param-before-other-params.min.stderr b/src/test/ui/const-generics/const-param-before-other-params.min.stderr
index 354c6d0615f..1e49588f1b4 100644
--- a/src/test/ui/const-generics/const-param-before-other-params.min.stderr
+++ b/src/test/ui/const-generics/const-param-before-other-params.min.stderr
@@ -1,17 +1,17 @@
 error: lifetime parameters must be declared prior to const parameters
-  --> $DIR/const-param-before-other-params.rs:6:21
+  --> $DIR/const-param-before-other-params.rs:5:21
    |
 LL | fn bar<const X: (), 'a>(_: &'a ()) {
    |       --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>`
 
 error: type parameters must be declared prior to const parameters
-  --> $DIR/const-param-before-other-params.rs:11:21
+  --> $DIR/const-param-before-other-params.rs:10:21
    |
 LL | fn foo<const X: (), T>(_: &T) {}
    |       --------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const X: ()>`
 
 error: `()` is forbidden as the type of a const generic parameter
-  --> $DIR/const-param-before-other-params.rs:6:17
+  --> $DIR/const-param-before-other-params.rs:5:17
    |
 LL | fn bar<const X: (), 'a>(_: &'a ()) {
    |                 ^^
@@ -20,7 +20,7 @@ LL | fn bar<const X: (), 'a>(_: &'a ()) {
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `()` is forbidden as the type of a const generic parameter
-  --> $DIR/const-param-before-other-params.rs:11:17
+  --> $DIR/const-param-before-other-params.rs:10:17
    |
 LL | fn foo<const X: (), T>(_: &T) {}
    |                 ^^
diff --git a/src/test/ui/const-generics/const-param-before-other-params.rs b/src/test/ui/const-generics/const-param-before-other-params.rs
index f1be90cf2e4..508bb3e6a68 100644
--- a/src/test/ui/const-generics/const-param-before-other-params.rs
+++ b/src/test/ui/const-generics/const-param-before-other-params.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn bar<const X: (), 'a>(_: &'a ()) {
     //~^ ERROR lifetime parameters must be declared prior to const parameters
diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.full.stderr b/src/test/ui/const-generics/const-param-elided-lifetime.full.stderr
index aa29d61d917..119f932745b 100644
--- a/src/test/ui/const-generics/const-param-elided-lifetime.full.stderr
+++ b/src/test/ui/const-generics/const-param-elided-lifetime.full.stderr
@@ -1,29 +1,29 @@
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/const-param-elided-lifetime.rs:11:19
+  --> $DIR/const-param-elided-lifetime.rs:10:19
    |
 LL | struct A<const N: &u8>;
    |                   ^ explicit lifetime name needed here
 
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/const-param-elided-lifetime.rs:16:15
+  --> $DIR/const-param-elided-lifetime.rs:15:15
    |
 LL | impl<const N: &u8> A<N> {
    |               ^ explicit lifetime name needed here
 
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/const-param-elided-lifetime.rs:19:21
+  --> $DIR/const-param-elided-lifetime.rs:18:21
    |
 LL |     fn foo<const M: &u8>(&self) {}
    |                     ^ explicit lifetime name needed here
 
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/const-param-elided-lifetime.rs:24:15
+  --> $DIR/const-param-elided-lifetime.rs:23:15
    |
 LL | impl<const N: &u8> B for A<N> {}
    |               ^ explicit lifetime name needed here
 
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/const-param-elided-lifetime.rs:28:17
+  --> $DIR/const-param-elided-lifetime.rs:27:17
    |
 LL | fn bar<const N: &u8>() {}
    |                 ^ explicit lifetime name needed here
diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.min.stderr b/src/test/ui/const-generics/const-param-elided-lifetime.min.stderr
index ed30182690a..5d3c8f7b2e6 100644
--- a/src/test/ui/const-generics/const-param-elided-lifetime.min.stderr
+++ b/src/test/ui/const-generics/const-param-elided-lifetime.min.stderr
@@ -1,35 +1,35 @@
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/const-param-elided-lifetime.rs:11:19
+  --> $DIR/const-param-elided-lifetime.rs:10:19
    |
 LL | struct A<const N: &u8>;
    |                   ^ explicit lifetime name needed here
 
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/const-param-elided-lifetime.rs:16:15
+  --> $DIR/const-param-elided-lifetime.rs:15:15
    |
 LL | impl<const N: &u8> A<N> {
    |               ^ explicit lifetime name needed here
 
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/const-param-elided-lifetime.rs:19:21
+  --> $DIR/const-param-elided-lifetime.rs:18:21
    |
 LL |     fn foo<const M: &u8>(&self) {}
    |                     ^ explicit lifetime name needed here
 
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/const-param-elided-lifetime.rs:24:15
+  --> $DIR/const-param-elided-lifetime.rs:23:15
    |
 LL | impl<const N: &u8> B for A<N> {}
    |               ^ explicit lifetime name needed here
 
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/const-param-elided-lifetime.rs:28:17
+  --> $DIR/const-param-elided-lifetime.rs:27:17
    |
 LL | fn bar<const N: &u8>() {}
    |                 ^ explicit lifetime name needed here
 
 error: `&'static u8` is forbidden as the type of a const generic parameter
-  --> $DIR/const-param-elided-lifetime.rs:11:19
+  --> $DIR/const-param-elided-lifetime.rs:10:19
    |
 LL | struct A<const N: &u8>;
    |                   ^^^
@@ -38,7 +38,7 @@ LL | struct A<const N: &u8>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `&'static u8` is forbidden as the type of a const generic parameter
-  --> $DIR/const-param-elided-lifetime.rs:16:15
+  --> $DIR/const-param-elided-lifetime.rs:15:15
    |
 LL | impl<const N: &u8> A<N> {
    |               ^^^
@@ -47,7 +47,7 @@ LL | impl<const N: &u8> A<N> {
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `&'static u8` is forbidden as the type of a const generic parameter
-  --> $DIR/const-param-elided-lifetime.rs:24:15
+  --> $DIR/const-param-elided-lifetime.rs:23:15
    |
 LL | impl<const N: &u8> B for A<N> {}
    |               ^^^
@@ -56,7 +56,7 @@ LL | impl<const N: &u8> B for A<N> {}
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `&'static u8` is forbidden as the type of a const generic parameter
-  --> $DIR/const-param-elided-lifetime.rs:28:17
+  --> $DIR/const-param-elided-lifetime.rs:27:17
    |
 LL | fn bar<const N: &u8>() {}
    |                 ^^^
@@ -65,7 +65,7 @@ LL | fn bar<const N: &u8>() {}
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `&'static u8` is forbidden as the type of a const generic parameter
-  --> $DIR/const-param-elided-lifetime.rs:19:21
+  --> $DIR/const-param-elided-lifetime.rs:18:21
    |
 LL |     fn foo<const M: &u8>(&self) {}
    |                     ^^^
diff --git a/src/test/ui/const-generics/const-param-elided-lifetime.rs b/src/test/ui/const-generics/const-param-elided-lifetime.rs
index 633e876f1d7..89715a7b8e9 100644
--- a/src/test/ui/const-generics/const-param-elided-lifetime.rs
+++ b/src/test/ui/const-generics/const-param-elided-lifetime.rs
@@ -6,7 +6,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct A<const N: &u8>;
 //~^ ERROR `&` without an explicit lifetime name cannot be used here
diff --git a/src/test/ui/const-generics/const-param-from-outer-fn.full.stderr b/src/test/ui/const-generics/const-param-from-outer-fn.full.stderr
index 5a126f5c3c6..c2ec7359c9f 100644
--- a/src/test/ui/const-generics/const-param-from-outer-fn.full.stderr
+++ b/src/test/ui/const-generics/const-param-from-outer-fn.full.stderr
@@ -1,5 +1,5 @@
 error[E0401]: can't use generic parameters from outer function
-  --> $DIR/const-param-from-outer-fn.rs:9:9
+  --> $DIR/const-param-from-outer-fn.rs:8:9
    |
 LL | fn foo<const X: u32>() {
    |              - const parameter from outer function
diff --git a/src/test/ui/const-generics/const-param-from-outer-fn.min.stderr b/src/test/ui/const-generics/const-param-from-outer-fn.min.stderr
index 5a126f5c3c6..c2ec7359c9f 100644
--- a/src/test/ui/const-generics/const-param-from-outer-fn.min.stderr
+++ b/src/test/ui/const-generics/const-param-from-outer-fn.min.stderr
@@ -1,5 +1,5 @@
 error[E0401]: can't use generic parameters from outer function
-  --> $DIR/const-param-from-outer-fn.rs:9:9
+  --> $DIR/const-param-from-outer-fn.rs:8:9
    |
 LL | fn foo<const X: u32>() {
    |              - const parameter from outer function
diff --git a/src/test/ui/const-generics/const-param-from-outer-fn.rs b/src/test/ui/const-generics/const-param-from-outer-fn.rs
index e1376c6e108..27b9ca9c291 100644
--- a/src/test/ui/const-generics/const-param-from-outer-fn.rs
+++ b/src/test/ui/const-generics/const-param-from-outer-fn.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn foo<const X: u32>() {
     fn bar() -> u32 {
diff --git a/src/test/ui/const-generics/const-param-hygiene.rs b/src/test/ui/const-generics/const-param-hygiene.rs
index c8cefc36732..9cafb05fbcb 100644
--- a/src/test/ui/const-generics/const-param-hygiene.rs
+++ b/src/test/ui/const-generics/const-param-hygiene.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 macro_rules! bar {
     ($($t:tt)*) => { impl<const N: usize> $($t)* };
diff --git a/src/test/ui/const-generics/const-param-in-async.rs b/src/test/ui/const-generics/const-param-in-async.rs
index e8601985287..9dc9c80241d 100644
--- a/src/test/ui/const-generics/const-param-in-async.rs
+++ b/src/test/ui/const-generics/const-param-in-async.rs
@@ -3,7 +3,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 async fn foo<const N: usize>(arg: [u8; N]) -> usize { arg.len() }
 
diff --git a/src/test/ui/const-generics/const-param-in-trait-ungated.rs b/src/test/ui/const-generics/const-param-in-trait-ungated.rs
deleted file mode 100644
index 8a81bcc1a80..00000000000
--- a/src/test/ui/const-generics/const-param-in-trait-ungated.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-trait Trait<const T: ()> {} //~ ERROR const generics are unstable
-
-fn main() {}
diff --git a/src/test/ui/const-generics/const-param-in-trait-ungated.stderr b/src/test/ui/const-generics/const-param-in-trait-ungated.stderr
deleted file mode 100644
index d53a4ac2d4c..00000000000
--- a/src/test/ui/const-generics/const-param-in-trait-ungated.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: const generics are unstable
-  --> $DIR/const-param-in-trait-ungated.rs:1:19
-   |
-LL | trait Trait<const T: ()> {}
-   |                   ^
-   |
-   = note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
-   = help: add `#![feature(min_const_generics)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/const-generics/const-param-in-trait.rs b/src/test/ui/const-generics/const-param-in-trait.rs
index 9d31162c1c6..79b3ae2037e 100644
--- a/src/test/ui/const-generics/const-param-in-trait.rs
+++ b/src/test/ui/const-generics/const-param-in-trait.rs
@@ -4,7 +4,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 
 trait Trait<const T: u8> {}
diff --git a/src/test/ui/const-generics/const-param-shadowing.rs b/src/test/ui/const-generics/const-param-shadowing.rs
index 8440e47968e..ddd15dbc41b 100644
--- a/src/test/ui/const-generics/const-param-shadowing.rs
+++ b/src/test/ui/const-generics/const-param-shadowing.rs
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 type N = u32;
 struct Foo<const M: usize>;
 fn test<const N: usize>() -> Foo<N> { //~ ERROR type provided when
diff --git a/src/test/ui/const-generics/const-param-shadowing.stderr b/src/test/ui/const-generics/const-param-shadowing.stderr
index df170278026..7447ca3ff36 100644
--- a/src/test/ui/const-generics/const-param-shadowing.stderr
+++ b/src/test/ui/const-generics/const-param-shadowing.stderr
@@ -1,5 +1,5 @@
 error[E0747]: type provided when a constant was expected
-  --> $DIR/const-param-shadowing.rs:5:34
+  --> $DIR/const-param-shadowing.rs:3:34
    |
 LL | fn test<const N: usize>() -> Foo<N> {
    |                                  ^
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.full.stderr b/src/test/ui/const-generics/const-param-type-depends-on-const-param.full.stderr
index f7ad579dbca..f639e276f46 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-const-param.full.stderr
+++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.full.stderr
@@ -1,11 +1,11 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/const-param-type-depends-on-const-param.rs:12:52
+  --> $DIR/const-param-type-depends-on-const-param.rs:11:52
    |
 LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
    |                                                    ^ the type must not depend on the parameter `N`
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/const-param-type-depends-on-const-param.rs:16:40
+  --> $DIR/const-param-type-depends-on-const-param.rs:15:40
    |
 LL | pub struct SelfDependent<const N: [u8; N]>;
    |                                        ^ the type must not depend on the parameter `N`
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.min.stderr b/src/test/ui/const-generics/const-param-type-depends-on-const-param.min.stderr
index 6b7a218ada5..d63bc236320 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-const-param.min.stderr
+++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.min.stderr
@@ -1,17 +1,17 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/const-param-type-depends-on-const-param.rs:12:52
+  --> $DIR/const-param-type-depends-on-const-param.rs:11:52
    |
 LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
    |                                                    ^ the type must not depend on the parameter `N`
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/const-param-type-depends-on-const-param.rs:16:40
+  --> $DIR/const-param-type-depends-on-const-param.rs:15:40
    |
 LL | pub struct SelfDependent<const N: [u8; N]>;
    |                                        ^ the type must not depend on the parameter `N`
 
 error: `[u8; _]` is forbidden as the type of a const generic parameter
-  --> $DIR/const-param-type-depends-on-const-param.rs:12:47
+  --> $DIR/const-param-type-depends-on-const-param.rs:11:47
    |
 LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
    |                                               ^^^^^^^
@@ -20,7 +20,7 @@ LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `[u8; _]` is forbidden as the type of a const generic parameter
-  --> $DIR/const-param-type-depends-on-const-param.rs:16:35
+  --> $DIR/const-param-type-depends-on-const-param.rs:15:35
    |
 LL | pub struct SelfDependent<const N: [u8; N]>;
    |                                   ^^^^^^^
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs
index 29371eeb21d..62b146e016a 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs
+++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 // Currently, const parameters cannot depend on other generic parameters,
 // as our current implementation can't really support this.
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs
index ea75a3d0403..781f50e6173 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs
@@ -3,7 +3,7 @@
 
 use std::marker::PhantomData;
 
-struct B<T, const N: T>(PhantomData<[T; N]>); //~ ERROR const generics are unstable
+struct B<T, const N: T>(PhantomData<[T; N]>);
 //~^ ERROR the type of const parameters must not depend on other generic parameters
 
 fn main() {}
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
index 5d379ff083c..8e14defd65d 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
@@ -4,16 +4,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
 LL | struct B<T, const N: T>(PhantomData<[T; N]>);
    |                      ^ the type must not depend on the parameter `T`
 
-error[E0658]: const generics are unstable
-  --> $DIR/const-param-type-depends-on-type-param-ungated.rs:6:19
-   |
-LL | struct B<T, const N: T>(PhantomData<[T; N]>);
-   |                   ^
-   |
-   = note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
-   = help: add `#![feature(min_const_generics)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0658, E0770.
-For more information about an error, try `rustc --explain E0658`.
+For more information about this error, try `rustc --explain E0770`.
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.full.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.full.stderr
index f860788e778..a83ee627187 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.full.stderr
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.full.stderr
@@ -1,11 +1,11 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/const-param-type-depends-on-type-param.rs:12:34
+  --> $DIR/const-param-type-depends-on-type-param.rs:11:34
    |
 LL | pub struct Dependent<T, const X: T>([(); X]);
    |                                  ^ the type must not depend on the parameter `T`
 
 error[E0392]: parameter `T` is never used
-  --> $DIR/const-param-type-depends-on-type-param.rs:12:22
+  --> $DIR/const-param-type-depends-on-type-param.rs:11:22
    |
 LL | pub struct Dependent<T, const X: T>([(); X]);
    |                      ^ unused parameter
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.min.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.min.stderr
index f860788e778..a83ee627187 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.min.stderr
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.min.stderr
@@ -1,11 +1,11 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/const-param-type-depends-on-type-param.rs:12:34
+  --> $DIR/const-param-type-depends-on-type-param.rs:11:34
    |
 LL | pub struct Dependent<T, const X: T>([(); X]);
    |                                  ^ the type must not depend on the parameter `T`
 
 error[E0392]: parameter `T` is never used
-  --> $DIR/const-param-type-depends-on-type-param.rs:12:22
+  --> $DIR/const-param-type-depends-on-type-param.rs:11:22
    |
 LL | pub struct Dependent<T, const X: T>([(); X]);
    |                      ^ unused parameter
diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs
index 93ae1117512..910a9643502 100644
--- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs
+++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 // Currently, const parameters cannot depend on other generic parameters,
 // as our current implementation can't really support this.
diff --git a/src/test/ui/const-generics/const-parameter-uppercase-lint.full.stderr b/src/test/ui/const-generics/const-parameter-uppercase-lint.full.stderr
index 0f4f007f9d2..923964a4070 100644
--- a/src/test/ui/const-generics/const-parameter-uppercase-lint.full.stderr
+++ b/src/test/ui/const-generics/const-parameter-uppercase-lint.full.stderr
@@ -1,11 +1,11 @@
 error: const parameter `x` should have an upper case name
-  --> $DIR/const-parameter-uppercase-lint.rs:9:15
+  --> $DIR/const-parameter-uppercase-lint.rs:8:15
    |
 LL | fn noop<const x: u32>() {
    |               ^ help: convert the identifier to upper case (notice the capitalization): `X`
    |
 note: the lint level is defined here
-  --> $DIR/const-parameter-uppercase-lint.rs:7:9
+  --> $DIR/const-parameter-uppercase-lint.rs:6:9
    |
 LL | #![deny(non_upper_case_globals)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/const-parameter-uppercase-lint.min.stderr b/src/test/ui/const-generics/const-parameter-uppercase-lint.min.stderr
index 0f4f007f9d2..923964a4070 100644
--- a/src/test/ui/const-generics/const-parameter-uppercase-lint.min.stderr
+++ b/src/test/ui/const-generics/const-parameter-uppercase-lint.min.stderr
@@ -1,11 +1,11 @@
 error: const parameter `x` should have an upper case name
-  --> $DIR/const-parameter-uppercase-lint.rs:9:15
+  --> $DIR/const-parameter-uppercase-lint.rs:8:15
    |
 LL | fn noop<const x: u32>() {
    |               ^ help: convert the identifier to upper case (notice the capitalization): `X`
    |
 note: the lint level is defined here
-  --> $DIR/const-parameter-uppercase-lint.rs:7:9
+  --> $DIR/const-parameter-uppercase-lint.rs:6:9
    |
 LL | #![deny(non_upper_case_globals)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/const-parameter-uppercase-lint.rs b/src/test/ui/const-generics/const-parameter-uppercase-lint.rs
index b9bd6666af3..5d97907c2e7 100644
--- a/src/test/ui/const-generics/const-parameter-uppercase-lint.rs
+++ b/src/test/ui/const-generics/const-parameter-uppercase-lint.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 #![deny(non_upper_case_globals)]
 
diff --git a/src/test/ui/const-generics/const-types.rs b/src/test/ui/const-generics/const-types.rs
index cd34cfc0478..fb150f892ed 100644
--- a/src/test/ui/const-generics/const-types.rs
+++ b/src/test/ui/const-generics/const-types.rs
@@ -4,7 +4,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 #![allow(dead_code, unused_variables)]
 
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.full.stderr b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.full.stderr
index b2816367ea1..d6a54ead131 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.full.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/feature-gate-const_evaluatable_checked.rs:9:30
+  --> $DIR/feature-gate-const_evaluatable_checked.rs:8:30
    |
 LL | fn test<const N: usize>() -> Arr<N> where Arr<N>: Default {
    |                              ^^^^^^
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.min.stderr b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.min.stderr
index 573bc66b7c7..7de4bfcdd05 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.min.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/feature-gate-const_evaluatable_checked.rs:6:33
+  --> $DIR/feature-gate-const_evaluatable_checked.rs:5:33
    |
 LL | type Arr<const N: usize> = [u8; N - 1];
    |                                 ^ cannot perform const operation using `N`
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs
index 9746adab29b..f49ca0251aa 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs
+++ b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 type Arr<const N: usize> = [u8; N - 1];
 //[min]~^ ERROR generic parameters may not be used in const operations
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/simple.min.stderr b/src/test/ui/const-generics/const_evaluatable_checked/simple.min.stderr
index d476a7eb645..9f3d94bbd8a 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/simple.min.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/simple.rs:8:53
+  --> $DIR/simple.rs:7:53
    |
 LL | fn test<const N: usize>() -> [u8; N - 1] where [u8; N - 1]: Default {
    |                                                     ^ cannot perform const operation using `N`
@@ -8,7 +8,7 @@ LL | fn test<const N: usize>() -> [u8; N - 1] where [u8; N - 1]: Default {
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/simple.rs:8:35
+  --> $DIR/simple.rs:7:35
    |
 LL | fn test<const N: usize>() -> [u8; N - 1] where [u8; N - 1]: Default {
    |                                   ^ cannot perform const operation using `N`
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/simple.rs b/src/test/ui/const-generics/const_evaluatable_checked/simple.rs
index dcf0071cb29..94ad71b6c1a 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/simple.rs
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple.rs
@@ -1,7 +1,6 @@
 // [full] run-pass
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 #![feature(const_evaluatable_checked)]
 #![allow(incomplete_features)]
 
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.full.stderr b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.full.stderr
index f95d6d2d570..c8549f101da 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.full.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.full.stderr
@@ -1,5 +1,5 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/simple_fail.rs:7:33
+  --> $DIR/simple_fail.rs:6:33
    |
 LL | type Arr<const N: usize> = [u8; N - 1];
    |                                 ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.min.stderr b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.min.stderr
index bd81e0bc5a8..df54b4cbca5 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.min.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/simple_fail.rs:7:33
+  --> $DIR/simple_fail.rs:6:33
    |
 LL | type Arr<const N: usize> = [u8; N - 1];
    |                                 ^ cannot perform const operation using `N`
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs
index 5e2c080927f..3cbc077f4f1 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs
@@ -1,6 +1,5 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 #![feature(const_evaluatable_checked)]
 #![allow(incomplete_features)]
 
diff --git a/src/test/ui/const-generics/core-types.rs b/src/test/ui/const-generics/core-types.rs
index c4351e059de..b6fa478f48d 100644
--- a/src/test/ui/const-generics/core-types.rs
+++ b/src/test/ui/const-generics/core-types.rs
@@ -4,7 +4,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct A<const N: u8>;
 struct B<const N: u16>;
diff --git a/src/test/ui/const-generics/cross_crate_complex.rs b/src/test/ui/const-generics/cross_crate_complex.rs
index 30749b8bc6d..1d495c9562d 100644
--- a/src/test/ui/const-generics/cross_crate_complex.rs
+++ b/src/test/ui/const-generics/cross_crate_complex.rs
@@ -5,7 +5,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 extern crate crayte;
 
 use crayte::*;
diff --git a/src/test/ui/const-generics/defaults/complex-unord-param.min.stderr b/src/test/ui/const-generics/defaults/complex-unord-param.min.stderr
index 0574ddfb255..8e8d26a0004 100644
--- a/src/test/ui/const-generics/defaults/complex-unord-param.min.stderr
+++ b/src/test/ui/const-generics/defaults/complex-unord-param.min.stderr
@@ -1,8 +1,8 @@
 error: type parameters must be declared prior to const parameters
-  --> $DIR/complex-unord-param.rs:9:41
+  --> $DIR/complex-unord-param.rs:8:41
    |
 LL | struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> {
-   |                    ---------------------^----------------------^--------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, A: 'a, T: 'a, const N: usize, const M: usize>`
+   |                    ---------------------^----------------------^--------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, A: 'a, T: 'a = u32, const N: usize, const M: usize>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/defaults/complex-unord-param.rs b/src/test/ui/const-generics/defaults/complex-unord-param.rs
index e83a96388c1..82b3627d22f 100644
--- a/src/test/ui/const-generics/defaults/complex-unord-param.rs
+++ b/src/test/ui/const-generics/defaults/complex-unord-param.rs
@@ -3,7 +3,6 @@
 // Checks a complicated usage of unordered params
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 #![allow(dead_code)]
 
 struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> {
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr
index 9cc3e9c0da6..c4a666a829d 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr
@@ -1,14 +1,14 @@
 error: lifetime parameters must be declared prior to const parameters
-  --> $DIR/intermixed-lifetime.rs:7:28
+  --> $DIR/intermixed-lifetime.rs:6:28
    |
 LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
-   |           -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
+   |           -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>`
 
 error: lifetime parameters must be declared prior to type parameters
-  --> $DIR/intermixed-lifetime.rs:11:37
+  --> $DIR/intermixed-lifetime.rs:10:37
    |
 LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
-   |           --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
+   |           --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
index 4d80fdb5bcb..69a490978d1 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
@@ -1,26 +1,26 @@
 error: lifetime parameters must be declared prior to const parameters
-  --> $DIR/intermixed-lifetime.rs:7:28
+  --> $DIR/intermixed-lifetime.rs:6:28
    |
 LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
-   |           -----------------^^---------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
+   |           -----------------^^---------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
 
 error: type parameters must be declared prior to const parameters
-  --> $DIR/intermixed-lifetime.rs:7:32
+  --> $DIR/intermixed-lifetime.rs:6:32
    |
 LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
-   |           ---------------------^------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
+   |           ---------------------^------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
 
 error: lifetime parameters must be declared prior to const parameters
-  --> $DIR/intermixed-lifetime.rs:11:37
+  --> $DIR/intermixed-lifetime.rs:10:37
    |
 LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
-   |           --------------------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
+   |           --------------------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
 
 error: type parameters must be declared prior to const parameters
-  --> $DIR/intermixed-lifetime.rs:11:28
+  --> $DIR/intermixed-lifetime.rs:10:28
    |
 LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
-   |           -----------------^----------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
+   |           -----------------^----------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.rs b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
index cc0d1c6c0c9..9e83bf92a59 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
@@ -2,7 +2,6 @@
 // Checks that lifetimes cannot be interspersed between consts and types.
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
 //~^ Error lifetime parameters must be declared prior to const parameters
diff --git a/src/test/ui/const-generics/defaults/needs-feature.min.stderr b/src/test/ui/const-generics/defaults/needs-feature.min.stderr
index 7058327fdce..a4006203e4a 100644
--- a/src/test/ui/const-generics/defaults/needs-feature.min.stderr
+++ b/src/test/ui/const-generics/defaults/needs-feature.min.stderr
@@ -1,8 +1,8 @@
 error: type parameters must be declared prior to const parameters
-  --> $DIR/needs-feature.rs:10:26
+  --> $DIR/needs-feature.rs:9:26
    |
 LL | struct A<const N: usize, T=u32>(T);
-   |         -----------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
+   |         -----------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<T = u32, const N: usize>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/defaults/needs-feature.none.stderr b/src/test/ui/const-generics/defaults/needs-feature.none.stderr
index 3b6f63a8efe..a4006203e4a 100644
--- a/src/test/ui/const-generics/defaults/needs-feature.none.stderr
+++ b/src/test/ui/const-generics/defaults/needs-feature.none.stderr
@@ -1,18 +1,8 @@
 error: type parameters must be declared prior to const parameters
-  --> $DIR/needs-feature.rs:10:26
+  --> $DIR/needs-feature.rs:9:26
    |
 LL | struct A<const N: usize, T=u32>(T);
-   |         -----------------^----- help: reorder the parameters: lifetimes, then types: `<T, const N: usize>`
+   |         -----------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<T = u32, const N: usize>`
 
-error[E0658]: const generics are unstable
-  --> $DIR/needs-feature.rs:10:16
-   |
-LL | struct A<const N: usize, T=u32>(T);
-   |                ^
-   |
-   = note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
-   = help: add `#![feature(min_const_generics)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/const-generics/defaults/needs-feature.rs b/src/test/ui/const-generics/defaults/needs-feature.rs
index ec02dbf407d..7eb7764a644 100644
--- a/src/test/ui/const-generics/defaults/needs-feature.rs
+++ b/src/test/ui/const-generics/defaults/needs-feature.rs
@@ -1,16 +1,13 @@
 //[full] run-pass
 // Verifies that having generic parameters after constants is not permitted without the
 // `const_generics` feature.
-// revisions: none min full
+// revisions: min full
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct A<const N: usize, T=u32>(T);
-//[none]~^ ERROR type parameters must be declared prior
-//[none]~| ERROR const generics are unstable
-//[min]~^^^ ERROR type parameters must be declared prior
+//[min]~^ ERROR type parameters must be declared prior
 
 fn main() {
   let _: A<3> = A(0);
diff --git a/src/test/ui/const-generics/defaults/simple-defaults.min.stderr b/src/test/ui/const-generics/defaults/simple-defaults.min.stderr
index 59cc6f28af8..0746c64ac8c 100644
--- a/src/test/ui/const-generics/defaults/simple-defaults.min.stderr
+++ b/src/test/ui/const-generics/defaults/simple-defaults.min.stderr
@@ -1,8 +1,8 @@
 error: type parameters must be declared prior to const parameters
-  --> $DIR/simple-defaults.rs:9:40
+  --> $DIR/simple-defaults.rs:8:40
    |
 LL | struct FixedOutput<'a, const N: usize, T=u32> {
-   |                   ---------------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
+   |                   ---------------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/defaults/simple-defaults.rs b/src/test/ui/const-generics/defaults/simple-defaults.rs
index 78abe351998..1f1b6c2260d 100644
--- a/src/test/ui/const-generics/defaults/simple-defaults.rs
+++ b/src/test/ui/const-generics/defaults/simple-defaults.rs
@@ -3,7 +3,6 @@
 // Checks some basic test cases for defaults.
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 #![allow(dead_code)]
 
 struct FixedOutput<'a, const N: usize, T=u32> {
diff --git a/src/test/ui/const-generics/defaults/wrong-order.full.stderr b/src/test/ui/const-generics/defaults/wrong-order.full.stderr
index 99f46309bf6..96deb4a8b5a 100644
--- a/src/test/ui/const-generics/defaults/wrong-order.full.stderr
+++ b/src/test/ui/const-generics/defaults/wrong-order.full.stderr
@@ -1,5 +1,5 @@
 error: type parameters with a default must be trailing
-  --> $DIR/wrong-order.rs:5:10
+  --> $DIR/wrong-order.rs:4:10
    |
 LL | struct A<T = u32, const N: usize> {
    |          ^
@@ -14,7 +14,6 @@ LL | #![cfg_attr(full, feature(const_generics))]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/const-generics/defaults/wrong-order.min.stderr b/src/test/ui/const-generics/defaults/wrong-order.min.stderr
index 29a46367004..b19da76f415 100644
--- a/src/test/ui/const-generics/defaults/wrong-order.min.stderr
+++ b/src/test/ui/const-generics/defaults/wrong-order.min.stderr
@@ -1,5 +1,5 @@
 error: type parameters with a default must be trailing
-  --> $DIR/wrong-order.rs:5:10
+  --> $DIR/wrong-order.rs:4:10
    |
 LL | struct A<T = u32, const N: usize> {
    |          ^
diff --git a/src/test/ui/const-generics/defaults/wrong-order.rs b/src/test/ui/const-generics/defaults/wrong-order.rs
index cb36d456f38..4f1c05011b0 100644
--- a/src/test/ui/const-generics/defaults/wrong-order.rs
+++ b/src/test/ui/const-generics/defaults/wrong-order.rs
@@ -1,6 +1,5 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct A<T = u32, const N: usize> {
     //~^ ERROR type parameters with a default must be trailing
diff --git a/src/test/ui/const-generics/derive-debug-array-wrapper.rs b/src/test/ui/const-generics/derive-debug-array-wrapper.rs
index 13fd87f1e3e..ce1481d97e9 100644
--- a/src/test/ui/const-generics/derive-debug-array-wrapper.rs
+++ b/src/test/ui/const-generics/derive-debug-array-wrapper.rs
@@ -4,7 +4,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 #[derive(Debug)]
 struct X<const N: usize> {
diff --git a/src/test/ui/const-generics/different_byref.full.stderr b/src/test/ui/const-generics/different_byref.full.stderr
index 4463ed7fcdd..d6b32323e2d 100644
--- a/src/test/ui/const-generics/different_byref.full.stderr
+++ b/src/test/ui/const-generics/different_byref.full.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/different_byref.rs:13:9
+  --> $DIR/different_byref.rs:12:9
    |
 LL |     x = Const::<{ [4] }> {};
    |         ^^^^^^^^^^^^^^^^^^^ expected `3_usize`, found `4_usize`
diff --git a/src/test/ui/const-generics/different_byref.min.stderr b/src/test/ui/const-generics/different_byref.min.stderr
index e5b393ffe99..05720d15404 100644
--- a/src/test/ui/const-generics/different_byref.min.stderr
+++ b/src/test/ui/const-generics/different_byref.min.stderr
@@ -1,5 +1,5 @@
 error: `[usize; 1]` is forbidden as the type of a const generic parameter
-  --> $DIR/different_byref.rs:8:23
+  --> $DIR/different_byref.rs:7:23
    |
 LL | struct Const<const V: [usize; 1]> {}
    |                       ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/different_byref.rs b/src/test/ui/const-generics/different_byref.rs
index cd3960eeb8e..7977560ecbc 100644
--- a/src/test/ui/const-generics/different_byref.rs
+++ b/src/test/ui/const-generics/different_byref.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Const<const V: [usize; 1]> {}
 //[min]~^ ERROR `[usize; 1]` is forbidden
diff --git a/src/test/ui/const-generics/different_byref_simple.full.stderr b/src/test/ui/const-generics/different_byref_simple.full.stderr
index b6729c852ab..027e282c398 100644
--- a/src/test/ui/const-generics/different_byref_simple.full.stderr
+++ b/src/test/ui/const-generics/different_byref_simple.full.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/different_byref_simple.rs:12:9
+  --> $DIR/different_byref_simple.rs:11:9
    |
 LL |     u = ConstUsize::<4> {};
    |         ^^^^^^^^^^^^^^^^^^ expected `3_usize`, found `4_usize`
diff --git a/src/test/ui/const-generics/different_byref_simple.min.stderr b/src/test/ui/const-generics/different_byref_simple.min.stderr
index b6729c852ab..027e282c398 100644
--- a/src/test/ui/const-generics/different_byref_simple.min.stderr
+++ b/src/test/ui/const-generics/different_byref_simple.min.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/different_byref_simple.rs:12:9
+  --> $DIR/different_byref_simple.rs:11:9
    |
 LL |     u = ConstUsize::<4> {};
    |         ^^^^^^^^^^^^^^^^^^ expected `3_usize`, found `4_usize`
diff --git a/src/test/ui/const-generics/different_byref_simple.rs b/src/test/ui/const-generics/different_byref_simple.rs
index 93289f93331..b48189fc2cb 100644
--- a/src/test/ui/const-generics/different_byref_simple.rs
+++ b/src/test/ui/const-generics/different_byref_simple.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct ConstUsize<const V: usize> {}
 
diff --git a/src/test/ui/const-generics/dyn-supertraits.rs b/src/test/ui/const-generics/dyn-supertraits.rs
index 0295255d809..73ed23521c3 100644
--- a/src/test/ui/const-generics/dyn-supertraits.rs
+++ b/src/test/ui/const-generics/dyn-supertraits.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait Foo<const N: usize> {
     fn myfun(&self) -> usize;
diff --git a/src/test/ui/const-generics/exhaustive-value.full.stderr b/src/test/ui/const-generics/exhaustive-value.full.stderr
index fdea1fb0c3e..e0e1423ba01 100644
--- a/src/test/ui/const-generics/exhaustive-value.full.stderr
+++ b/src/test/ui/const-generics/exhaustive-value.full.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `(): Foo<N>` is not satisfied
-  --> $DIR/exhaustive-value.rs:267:5
+  --> $DIR/exhaustive-value.rs:266:5
    |
 LL |     fn test() {}
    |     --------- required by `Foo::test`
diff --git a/src/test/ui/const-generics/exhaustive-value.min.stderr b/src/test/ui/const-generics/exhaustive-value.min.stderr
index fdea1fb0c3e..e0e1423ba01 100644
--- a/src/test/ui/const-generics/exhaustive-value.min.stderr
+++ b/src/test/ui/const-generics/exhaustive-value.min.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `(): Foo<N>` is not satisfied
-  --> $DIR/exhaustive-value.rs:267:5
+  --> $DIR/exhaustive-value.rs:266:5
    |
 LL |     fn test() {}
    |     --------- required by `Foo::test`
diff --git a/src/test/ui/const-generics/exhaustive-value.rs b/src/test/ui/const-generics/exhaustive-value.rs
index fce036b0da6..921f9a46707 100644
--- a/src/test/ui/const-generics/exhaustive-value.rs
+++ b/src/test/ui/const-generics/exhaustive-value.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait Foo<const N: u8> {
     fn test() {}
diff --git a/src/test/ui/const-generics/fn-const-param-call.full.stderr b/src/test/ui/const-generics/fn-const-param-call.full.stderr
index f1bd8def9ff..d984449e6ca 100644
--- a/src/test/ui/const-generics/fn-const-param-call.full.stderr
+++ b/src/test/ui/const-generics/fn-const-param-call.full.stderr
@@ -1,11 +1,11 @@
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/fn-const-param-call.rs:12:25
+  --> $DIR/fn-const-param-call.rs:11:25
    |
 LL | struct Wrapper<const F: fn() -> u32>;
    |                         ^^^^^^^^^^^
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/fn-const-param-call.rs:14:15
+  --> $DIR/fn-const-param-call.rs:13:15
    |
 LL | impl<const F: fn() -> u32> Wrapper<F> {
    |               ^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/fn-const-param-call.min.stderr b/src/test/ui/const-generics/fn-const-param-call.min.stderr
index f1bd8def9ff..d984449e6ca 100644
--- a/src/test/ui/const-generics/fn-const-param-call.min.stderr
+++ b/src/test/ui/const-generics/fn-const-param-call.min.stderr
@@ -1,11 +1,11 @@
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/fn-const-param-call.rs:12:25
+  --> $DIR/fn-const-param-call.rs:11:25
    |
 LL | struct Wrapper<const F: fn() -> u32>;
    |                         ^^^^^^^^^^^
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/fn-const-param-call.rs:14:15
+  --> $DIR/fn-const-param-call.rs:13:15
    |
 LL | impl<const F: fn() -> u32> Wrapper<F> {
    |               ^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/fn-const-param-call.rs b/src/test/ui/const-generics/fn-const-param-call.rs
index bba6c1f7a16..70a104e2222 100644
--- a/src/test/ui/const-generics/fn-const-param-call.rs
+++ b/src/test/ui/const-generics/fn-const-param-call.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn function() -> u32 {
     17
diff --git a/src/test/ui/const-generics/fn-const-param-infer.full.stderr b/src/test/ui/const-generics/fn-const-param-infer.full.stderr
index 4bdc9b89af6..f0767a10994 100644
--- a/src/test/ui/const-generics/fn-const-param-infer.full.stderr
+++ b/src/test/ui/const-generics/fn-const-param-infer.full.stderr
@@ -1,5 +1,5 @@
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/fn-const-param-infer.rs:7:25
+  --> $DIR/fn-const-param-infer.rs:6:25
    |
 LL | struct Checked<const F: fn(usize) -> bool>;
    |                         ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/fn-const-param-infer.min.stderr b/src/test/ui/const-generics/fn-const-param-infer.min.stderr
index 4bdc9b89af6..f0767a10994 100644
--- a/src/test/ui/const-generics/fn-const-param-infer.min.stderr
+++ b/src/test/ui/const-generics/fn-const-param-infer.min.stderr
@@ -1,5 +1,5 @@
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/fn-const-param-infer.rs:7:25
+  --> $DIR/fn-const-param-infer.rs:6:25
    |
 LL | struct Checked<const F: fn(usize) -> bool>;
    |                         ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/fn-const-param-infer.rs b/src/test/ui/const-generics/fn-const-param-infer.rs
index 3ed75e7b00d..d090479d4c3 100644
--- a/src/test/ui/const-generics/fn-const-param-infer.rs
+++ b/src/test/ui/const-generics/fn-const-param-infer.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Checked<const F: fn(usize) -> bool>;
 //~^ ERROR: using function pointers as const generic parameters
diff --git a/src/test/ui/const-generics/fn-taking-const-generic-array.rs b/src/test/ui/const-generics/fn-taking-const-generic-array.rs
index 950684aaa8d..58c1b95893e 100644
--- a/src/test/ui/const-generics/fn-taking-const-generic-array.rs
+++ b/src/test/ui/const-generics/fn-taking-const-generic-array.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 use std::fmt::Display;
 
diff --git a/src/test/ui/const-generics/forbid-non-structural_match-types.full.stderr b/src/test/ui/const-generics/forbid-non-structural_match-types.full.stderr
index adcaa759963..5c0f17537fa 100644
--- a/src/test/ui/const-generics/forbid-non-structural_match-types.full.stderr
+++ b/src/test/ui/const-generics/forbid-non-structural_match-types.full.stderr
@@ -1,5 +1,5 @@
 error[E0741]: `C` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
-  --> $DIR/forbid-non-structural_match-types.rs:15:19
+  --> $DIR/forbid-non-structural_match-types.rs:14:19
    |
 LL | struct D<const X: C>;
    |                   ^ `C` doesn't derive both `PartialEq` and `Eq`
diff --git a/src/test/ui/const-generics/forbid-non-structural_match-types.min.stderr b/src/test/ui/const-generics/forbid-non-structural_match-types.min.stderr
index 014200178b9..3912cf57751 100644
--- a/src/test/ui/const-generics/forbid-non-structural_match-types.min.stderr
+++ b/src/test/ui/const-generics/forbid-non-structural_match-types.min.stderr
@@ -1,5 +1,5 @@
 error: `A` is forbidden as the type of a const generic parameter
-  --> $DIR/forbid-non-structural_match-types.rs:10:19
+  --> $DIR/forbid-non-structural_match-types.rs:9:19
    |
 LL | struct B<const X: A>; // ok
    |                   ^
@@ -8,7 +8,7 @@ LL | struct B<const X: A>; // ok
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `C` is forbidden as the type of a const generic parameter
-  --> $DIR/forbid-non-structural_match-types.rs:15:19
+  --> $DIR/forbid-non-structural_match-types.rs:14:19
    |
 LL | struct D<const X: C>;
    |                   ^
@@ -17,7 +17,7 @@ LL | struct D<const X: C>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error[E0741]: `C` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
-  --> $DIR/forbid-non-structural_match-types.rs:15:19
+  --> $DIR/forbid-non-structural_match-types.rs:14:19
    |
 LL | struct D<const X: C>;
    |                   ^ `C` doesn't derive both `PartialEq` and `Eq`
diff --git a/src/test/ui/const-generics/forbid-non-structural_match-types.rs b/src/test/ui/const-generics/forbid-non-structural_match-types.rs
index e7356d485db..0fdb3ed4a5a 100644
--- a/src/test/ui/const-generics/forbid-non-structural_match-types.rs
+++ b/src/test/ui/const-generics/forbid-non-structural_match-types.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 #[derive(PartialEq, Eq)]
 struct A;
diff --git a/src/test/ui/const-generics/foreign-item-const-parameter.full.stderr b/src/test/ui/const-generics/foreign-item-const-parameter.full.stderr
index 0ac51e8c9e6..b827e482977 100644
--- a/src/test/ui/const-generics/foreign-item-const-parameter.full.stderr
+++ b/src/test/ui/const-generics/foreign-item-const-parameter.full.stderr
@@ -1,5 +1,5 @@
 error[E0044]: foreign items may not have const parameters
-  --> $DIR/foreign-item-const-parameter.rs:8:5
+  --> $DIR/foreign-item-const-parameter.rs:7:5
    |
 LL |     fn foo<const X: usize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters
@@ -7,7 +7,7 @@ LL |     fn foo<const X: usize>();
    = help: replace the const parameters with concrete consts
 
 error[E0044]: foreign items may not have type or const parameters
-  --> $DIR/foreign-item-const-parameter.rs:10:5
+  --> $DIR/foreign-item-const-parameter.rs:9:5
    |
 LL |     fn bar<T, const X: usize>(_: T);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have type or const parameters
diff --git a/src/test/ui/const-generics/foreign-item-const-parameter.min.stderr b/src/test/ui/const-generics/foreign-item-const-parameter.min.stderr
index 0ac51e8c9e6..b827e482977 100644
--- a/src/test/ui/const-generics/foreign-item-const-parameter.min.stderr
+++ b/src/test/ui/const-generics/foreign-item-const-parameter.min.stderr
@@ -1,5 +1,5 @@
 error[E0044]: foreign items may not have const parameters
-  --> $DIR/foreign-item-const-parameter.rs:8:5
+  --> $DIR/foreign-item-const-parameter.rs:7:5
    |
 LL |     fn foo<const X: usize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters
@@ -7,7 +7,7 @@ LL |     fn foo<const X: usize>();
    = help: replace the const parameters with concrete consts
 
 error[E0044]: foreign items may not have type or const parameters
-  --> $DIR/foreign-item-const-parameter.rs:10:5
+  --> $DIR/foreign-item-const-parameter.rs:9:5
    |
 LL |     fn bar<T, const X: usize>(_: T);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have type or const parameters
diff --git a/src/test/ui/const-generics/foreign-item-const-parameter.rs b/src/test/ui/const-generics/foreign-item-const-parameter.rs
index 44b6d0332c3..83caa89f033 100644
--- a/src/test/ui/const-generics/foreign-item-const-parameter.rs
+++ b/src/test/ui/const-generics/foreign-item-const-parameter.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 extern "C" {
     fn foo<const X: usize>(); //~ ERROR foreign items may not have const parameters
diff --git a/src/test/ui/const-generics/generic-function-call-in-array-length.full.stderr b/src/test/ui/const-generics/generic-function-call-in-array-length.full.stderr
index 43b42d82d0c..2d19a58a145 100644
--- a/src/test/ui/const-generics/generic-function-call-in-array-length.full.stderr
+++ b/src/test/ui/const-generics/generic-function-call-in-array-length.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/generic-function-call-in-array-length.rs:9:29
+  --> $DIR/generic-function-call-in-array-length.rs:8:29
    |
 LL | fn bar<const N: usize>() -> [u32; foo(N)] {
    |                             ^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/generic-function-call-in-array-length.min.stderr b/src/test/ui/const-generics/generic-function-call-in-array-length.min.stderr
index 526f98fe8cd..d7a3f04a8da 100644
--- a/src/test/ui/const-generics/generic-function-call-in-array-length.min.stderr
+++ b/src/test/ui/const-generics/generic-function-call-in-array-length.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/generic-function-call-in-array-length.rs:9:39
+  --> $DIR/generic-function-call-in-array-length.rs:8:39
    |
 LL | fn bar<const N: usize>() -> [u32; foo(N)] {
    |                                       ^ cannot perform const operation using `N`
@@ -8,7 +8,7 @@ LL | fn bar<const N: usize>() -> [u32; foo(N)] {
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/generic-function-call-in-array-length.rs:12:13
+  --> $DIR/generic-function-call-in-array-length.rs:11:13
    |
 LL |     [0; foo(N)]
    |             ^ cannot perform const operation using `N`
diff --git a/src/test/ui/const-generics/generic-function-call-in-array-length.rs b/src/test/ui/const-generics/generic-function-call-in-array-length.rs
index c838070dc95..a6d2bbd17ea 100644
--- a/src/test/ui/const-generics/generic-function-call-in-array-length.rs
+++ b/src/test/ui/const-generics/generic-function-call-in-array-length.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 const fn foo(n: usize) -> usize { n * 2 }
 
diff --git a/src/test/ui/const-generics/generic-param-mismatch.full.stderr b/src/test/ui/const-generics/generic-param-mismatch.full.stderr
index 6befa9d1f69..aff8780fb0d 100644
--- a/src/test/ui/const-generics/generic-param-mismatch.full.stderr
+++ b/src/test/ui/const-generics/generic-param-mismatch.full.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/generic-param-mismatch.rs:7:5
+  --> $DIR/generic-param-mismatch.rs:6:5
    |
 LL | fn test<const N: usize, const M: usize>() -> [u8; M] {
    |                                              ------- expected `[u8; M]` because of return type
diff --git a/src/test/ui/const-generics/generic-param-mismatch.min.stderr b/src/test/ui/const-generics/generic-param-mismatch.min.stderr
index 6befa9d1f69..aff8780fb0d 100644
--- a/src/test/ui/const-generics/generic-param-mismatch.min.stderr
+++ b/src/test/ui/const-generics/generic-param-mismatch.min.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/generic-param-mismatch.rs:7:5
+  --> $DIR/generic-param-mismatch.rs:6:5
    |
 LL | fn test<const N: usize, const M: usize>() -> [u8; M] {
    |                                              ------- expected `[u8; M]` because of return type
diff --git a/src/test/ui/const-generics/generic-param-mismatch.rs b/src/test/ui/const-generics/generic-param-mismatch.rs
index e409094eb73..22fffe47dcc 100644
--- a/src/test/ui/const-generics/generic-param-mismatch.rs
+++ b/src/test/ui/const-generics/generic-param-mismatch.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn test<const N: usize, const M: usize>() -> [u8; M] {
     [0; N] //~ ERROR mismatched types
diff --git a/src/test/ui/const-generics/generic-sum-in-array-length.full.stderr b/src/test/ui/const-generics/generic-sum-in-array-length.full.stderr
index d311e1c0bae..c13882e7fe1 100644
--- a/src/test/ui/const-generics/generic-sum-in-array-length.full.stderr
+++ b/src/test/ui/const-generics/generic-sum-in-array-length.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/generic-sum-in-array-length.rs:7:45
+  --> $DIR/generic-sum-in-array-length.rs:6:45
    |
 LL | fn foo<const A: usize, const B: usize>(bar: [usize; A + B]) {}
    |                                             ^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/generic-sum-in-array-length.min.stderr b/src/test/ui/const-generics/generic-sum-in-array-length.min.stderr
index e531b612b56..cff5a62193c 100644
--- a/src/test/ui/const-generics/generic-sum-in-array-length.min.stderr
+++ b/src/test/ui/const-generics/generic-sum-in-array-length.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/generic-sum-in-array-length.rs:7:53
+  --> $DIR/generic-sum-in-array-length.rs:6:53
    |
 LL | fn foo<const A: usize, const B: usize>(bar: [usize; A + B]) {}
    |                                                     ^ cannot perform const operation using `A`
@@ -8,7 +8,7 @@ LL | fn foo<const A: usize, const B: usize>(bar: [usize; A + B]) {}
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/generic-sum-in-array-length.rs:7:57
+  --> $DIR/generic-sum-in-array-length.rs:6:57
    |
 LL | fn foo<const A: usize, const B: usize>(bar: [usize; A + B]) {}
    |                                                         ^ cannot perform const operation using `B`
diff --git a/src/test/ui/const-generics/generic-sum-in-array-length.rs b/src/test/ui/const-generics/generic-sum-in-array-length.rs
index 84ddfe055dc..7ee0394ba14 100644
--- a/src/test/ui/const-generics/generic-sum-in-array-length.rs
+++ b/src/test/ui/const-generics/generic-sum-in-array-length.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn foo<const A: usize, const B: usize>(bar: [usize; A + B]) {}
 //[min]~^ ERROR generic parameters may not be used in const operations
diff --git a/src/test/ui/const-generics/impl-const-generic-struct.rs b/src/test/ui/const-generics/impl-const-generic-struct.rs
index 05cabc46baa..1aa22698b64 100644
--- a/src/test/ui/const-generics/impl-const-generic-struct.rs
+++ b/src/test/ui/const-generics/impl-const-generic-struct.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct S<const X: u32>;
 
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 a587cb61873..26b965901a4 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
@@ -1,5 +1,5 @@
 error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
-  --> $DIR/impl-trait-with-const-arguments.rs:24:20
+  --> $DIR/impl-trait-with-const-arguments.rs:23:20
    |
 LL |     assert_eq!(f::<4usize>(Usizable), 20usize);
    |                    ^^^^^^ explicit generic argument not allowed
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 a587cb61873..26b965901a4 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
@@ -1,5 +1,5 @@
 error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
-  --> $DIR/impl-trait-with-const-arguments.rs:24:20
+  --> $DIR/impl-trait-with-const-arguments.rs:23:20
    |
 LL |     assert_eq!(f::<4usize>(Usizable), 20usize);
    |                    ^^^^^^ explicit generic argument not allowed
diff --git a/src/test/ui/const-generics/impl-trait-with-const-arguments.rs b/src/test/ui/const-generics/impl-trait-with-const-arguments.rs
index a4c75792ee3..2e6e49b9c0a 100644
--- a/src/test/ui/const-generics/impl-trait-with-const-arguments.rs
+++ b/src/test/ui/const-generics/impl-trait-with-const-arguments.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait Usizer {
     fn m(self) -> usize;
diff --git a/src/test/ui/const-generics/incorrect-number-of-const-args.full.stderr b/src/test/ui/const-generics/incorrect-number-of-const-args.full.stderr
index 6b902e2d658..9c8359b08a5 100644
--- a/src/test/ui/const-generics/incorrect-number-of-const-args.full.stderr
+++ b/src/test/ui/const-generics/incorrect-number-of-const-args.full.stderr
@@ -1,11 +1,11 @@
 error[E0107]: wrong number of const arguments: expected 2, found 1
-  --> $DIR/incorrect-number-of-const-args.rs:12:5
+  --> $DIR/incorrect-number-of-const-args.rs:11:5
    |
 LL |     foo::<0>();
    |     ^^^^^^^^ expected 2 const arguments
 
 error[E0107]: wrong number of const arguments: expected 2, found 3
-  --> $DIR/incorrect-number-of-const-args.rs:13:17
+  --> $DIR/incorrect-number-of-const-args.rs:12:17
    |
 LL |     foo::<0, 0, 0>();
    |                 ^ unexpected const argument
diff --git a/src/test/ui/const-generics/incorrect-number-of-const-args.min.stderr b/src/test/ui/const-generics/incorrect-number-of-const-args.min.stderr
index 6b902e2d658..9c8359b08a5 100644
--- a/src/test/ui/const-generics/incorrect-number-of-const-args.min.stderr
+++ b/src/test/ui/const-generics/incorrect-number-of-const-args.min.stderr
@@ -1,11 +1,11 @@
 error[E0107]: wrong number of const arguments: expected 2, found 1
-  --> $DIR/incorrect-number-of-const-args.rs:12:5
+  --> $DIR/incorrect-number-of-const-args.rs:11:5
    |
 LL |     foo::<0>();
    |     ^^^^^^^^ expected 2 const arguments
 
 error[E0107]: wrong number of const arguments: expected 2, found 3
-  --> $DIR/incorrect-number-of-const-args.rs:13:17
+  --> $DIR/incorrect-number-of-const-args.rs:12:17
    |
 LL |     foo::<0, 0, 0>();
    |                 ^ unexpected const argument
diff --git a/src/test/ui/const-generics/incorrect-number-of-const-args.rs b/src/test/ui/const-generics/incorrect-number-of-const-args.rs
index f7bdf761f7d..3c4290df056 100644
--- a/src/test/ui/const-generics/incorrect-number-of-const-args.rs
+++ b/src/test/ui/const-generics/incorrect-number-of-const-args.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn foo<const X: usize, const Y: usize>() -> usize {
     0
diff --git a/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr b/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr
index 05bf67a5ff7..e85bf8829ae 100644
--- a/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr
+++ b/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/cannot-infer-const-args.rs:12:5
+  --> $DIR/cannot-infer-const-args.rs:11:5
    |
 LL |     foo();
    |     ^^^ cannot infer the value of const parameter `X` declared on the function `foo`
diff --git a/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr b/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr
index 05bf67a5ff7..e85bf8829ae 100644
--- a/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr
+++ b/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/cannot-infer-const-args.rs:12:5
+  --> $DIR/cannot-infer-const-args.rs:11:5
    |
 LL |     foo();
    |     ^^^ cannot infer the value of const parameter `X` declared on the function `foo`
diff --git a/src/test/ui/const-generics/infer/cannot-infer-const-args.rs b/src/test/ui/const-generics/infer/cannot-infer-const-args.rs
index 2d74b4788bf..cc52892bd04 100644
--- a/src/test/ui/const-generics/infer/cannot-infer-const-args.rs
+++ b/src/test/ui/const-generics/infer/cannot-infer-const-args.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn foo<const X: usize>() -> usize {
     0
diff --git a/src/test/ui/const-generics/infer/issue-77092.rs b/src/test/ui/const-generics/infer/issue-77092.rs
index 9a1dd1a8258..fcf7d3282b4 100644
--- a/src/test/ui/const-generics/infer/issue-77092.rs
+++ b/src/test/ui/const-generics/infer/issue-77092.rs
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 use std::convert::TryInto;
 
 fn take_array_from_mut<T, const N: usize>(data: &mut [T], start: usize) -> &mut [T; N] {
diff --git a/src/test/ui/const-generics/infer/issue-77092.stderr b/src/test/ui/const-generics/infer/issue-77092.stderr
index 99894173bc8..5857a421198 100644
--- a/src/test/ui/const-generics/infer/issue-77092.stderr
+++ b/src/test/ui/const-generics/infer/issue-77092.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/issue-77092.rs:13:26
+  --> $DIR/issue-77092.rs:11:26
    |
 LL |         println!("{:?}", take_array_from_mut(&mut arr, i));
    |                          ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `take_array_from_mut`
diff --git a/src/test/ui/const-generics/infer/method-chain.full.stderr b/src/test/ui/const-generics/infer/method-chain.full.stderr
index 7aa3bd44df8..f6d9c4a2645 100644
--- a/src/test/ui/const-generics/infer/method-chain.full.stderr
+++ b/src/test/ui/const-generics/infer/method-chain.full.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/method-chain.rs:21:33
+  --> $DIR/method-chain.rs:20:33
    |
 LL |     Foo.bar().bar().bar().bar().baz();
    |                                 ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`
diff --git a/src/test/ui/const-generics/infer/method-chain.min.stderr b/src/test/ui/const-generics/infer/method-chain.min.stderr
index 7aa3bd44df8..f6d9c4a2645 100644
--- a/src/test/ui/const-generics/infer/method-chain.min.stderr
+++ b/src/test/ui/const-generics/infer/method-chain.min.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/method-chain.rs:21:33
+  --> $DIR/method-chain.rs:20:33
    |
 LL |     Foo.bar().bar().bar().bar().baz();
    |                                 ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`
diff --git a/src/test/ui/const-generics/infer/method-chain.rs b/src/test/ui/const-generics/infer/method-chain.rs
index 9389ca20d10..8ac6a7d6267 100644
--- a/src/test/ui/const-generics/infer/method-chain.rs
+++ b/src/test/ui/const-generics/infer/method-chain.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo;
 
diff --git a/src/test/ui/const-generics/infer/uninferred-consts.full.stderr b/src/test/ui/const-generics/infer/uninferred-consts.full.stderr
index 4be625ba909..254a28f70e2 100644
--- a/src/test/ui/const-generics/infer/uninferred-consts.full.stderr
+++ b/src/test/ui/const-generics/infer/uninferred-consts.full.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/uninferred-consts.rs:14:9
+  --> $DIR/uninferred-consts.rs:13:9
    |
 LL |     Foo.foo();
    |         ^^^ cannot infer the value of const parameter `A` declared on the associated function `foo`
diff --git a/src/test/ui/const-generics/infer/uninferred-consts.min.stderr b/src/test/ui/const-generics/infer/uninferred-consts.min.stderr
index 4be625ba909..254a28f70e2 100644
--- a/src/test/ui/const-generics/infer/uninferred-consts.min.stderr
+++ b/src/test/ui/const-generics/infer/uninferred-consts.min.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/uninferred-consts.rs:14:9
+  --> $DIR/uninferred-consts.rs:13:9
    |
 LL |     Foo.foo();
    |         ^^^ cannot infer the value of const parameter `A` declared on the associated function `foo`
diff --git a/src/test/ui/const-generics/infer/uninferred-consts.rs b/src/test/ui/const-generics/infer/uninferred-consts.rs
index 00fb6eac992..bcd9aadb78a 100644
--- a/src/test/ui/const-generics/infer/uninferred-consts.rs
+++ b/src/test/ui/const-generics/infer/uninferred-consts.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 // taken from https://github.com/rust-lang/rust/issues/70507#issuecomment-615268893
 struct Foo;
diff --git a/src/test/ui/const-generics/infer_arg_from_pat.rs b/src/test/ui/const-generics/infer_arg_from_pat.rs
index 609fdb35cf1..5e2a3eaff54 100644
--- a/src/test/ui/const-generics/infer_arg_from_pat.rs
+++ b/src/test/ui/const-generics/infer_arg_from_pat.rs
@@ -5,7 +5,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct A<const N: usize> {
     arr: [u8; N],
diff --git a/src/test/ui/const-generics/infer_arr_len_from_pat.rs b/src/test/ui/const-generics/infer_arr_len_from_pat.rs
index cbf48e3d249..0273383856f 100644
--- a/src/test/ui/const-generics/infer_arr_len_from_pat.rs
+++ b/src/test/ui/const-generics/infer_arr_len_from_pat.rs
@@ -5,7 +5,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn as_chunks<const N: usize>() -> [u8; N] {
     loop {}
diff --git a/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs
index bdbf338295c..96e5976e44b 100644
--- a/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs
+++ b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn takes_closure_of_array_3<F>(f: F) where F: Fn([i32; 3]) {
     f([1, 2, 3]);
diff --git a/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.full.stderr b/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.full.stderr
index c09d16d0ab0..3e90dbeece9 100644
--- a/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.full.stderr
+++ b/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/intrinsics-type_name-as-const-argument.rs:15:8
+  --> $DIR/intrinsics-type_name-as-const-argument.rs:14:8
    |
 LL |     T: Trait<{std::intrinsics::type_name::<T>()}>
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr b/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr
index 02467df193c..4c2aaef3493 100644
--- a/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr
+++ b/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/intrinsics-type_name-as-const-argument.rs:15:44
+  --> $DIR/intrinsics-type_name-as-const-argument.rs:14:44
    |
 LL |     T: Trait<{std::intrinsics::type_name::<T>()}>
    |                                            ^ cannot perform const operation using `T`
@@ -8,7 +8,7 @@ LL |     T: Trait<{std::intrinsics::type_name::<T>()}>
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: `&'static str` is forbidden as the type of a const generic parameter
-  --> $DIR/intrinsics-type_name-as-const-argument.rs:10:22
+  --> $DIR/intrinsics-type_name-as-const-argument.rs:9:22
    |
 LL | trait Trait<const S: &'static str> {}
    |                      ^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.rs b/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.rs
index 8971c00ed5a..f24dd42eb2d 100644
--- a/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.rs
+++ b/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 #![feature(core_intrinsics)]
 #![feature(const_type_name)]
diff --git a/src/test/ui/const-generics/issue-61522-array-len-succ.full.stderr b/src/test/ui/const-generics/issue-61522-array-len-succ.full.stderr
index 8855f187e97..56deec16548 100644
--- a/src/test/ui/const-generics/issue-61522-array-len-succ.full.stderr
+++ b/src/test/ui/const-generics/issue-61522-array-len-succ.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-61522-array-len-succ.rs:7:40
+  --> $DIR/issue-61522-array-len-succ.rs:6:40
    |
 LL | pub struct MyArray<const COUNT: usize>([u8; COUNT + 1]);
    |                                        ^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | pub struct MyArray<const COUNT: usize>([u8; COUNT + 1]);
    = note: this may fail depending on what value the parameter takes
 
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-61522-array-len-succ.rs:12:24
+  --> $DIR/issue-61522-array-len-succ.rs:11:24
    |
 LL |     fn inner(&self) -> &[u8; COUNT + 1] {
    |                        ^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issue-61522-array-len-succ.min.stderr b/src/test/ui/const-generics/issue-61522-array-len-succ.min.stderr
index 2eaef95c232..36a0a37ae9c 100644
--- a/src/test/ui/const-generics/issue-61522-array-len-succ.min.stderr
+++ b/src/test/ui/const-generics/issue-61522-array-len-succ.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-61522-array-len-succ.rs:7:45
+  --> $DIR/issue-61522-array-len-succ.rs:6:45
    |
 LL | pub struct MyArray<const COUNT: usize>([u8; COUNT + 1]);
    |                                             ^^^^^ cannot perform const operation using `COUNT`
@@ -8,7 +8,7 @@ LL | pub struct MyArray<const COUNT: usize>([u8; COUNT + 1]);
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-61522-array-len-succ.rs:12:30
+  --> $DIR/issue-61522-array-len-succ.rs:11:30
    |
 LL |     fn inner(&self) -> &[u8; COUNT + 1] {
    |                              ^^^^^ cannot perform const operation using `COUNT`
diff --git a/src/test/ui/const-generics/issue-61522-array-len-succ.rs b/src/test/ui/const-generics/issue-61522-array-len-succ.rs
index 8c0a3a03774..d4a948b9259 100644
--- a/src/test/ui/const-generics/issue-61522-array-len-succ.rs
+++ b/src/test/ui/const-generics/issue-61522-array-len-succ.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub struct MyArray<const COUNT: usize>([u8; COUNT + 1]);
 //[full]~^ ERROR constant expression depends on a generic parameter
diff --git a/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.min.stderr b/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.min.stderr
index 1c2e7e069a1..b6c6e6fe374 100644
--- a/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.min.stderr
+++ b/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.min.stderr
@@ -1,5 +1,5 @@
 error: `&'static str` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-66596-impl-trait-for-str-const-arg.rs:9:25
+  --> $DIR/issue-66596-impl-trait-for-str-const-arg.rs:8:25
    |
 LL | trait Trait<const NAME: &'static str> {
    |                         ^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs b/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs
index 11d4bf4c3e6..2a741ba87a9 100644
--- a/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs
+++ b/src/test/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 
 trait Trait<const NAME: &'static str> {
diff --git a/src/test/ui/const-generics/issue-67375.full.stderr b/src/test/ui/const-generics/issue-67375.full.stderr
index e15d65f197e..2f004f75de5 100644
--- a/src/test/ui/const-generics/issue-67375.full.stderr
+++ b/src/test/ui/const-generics/issue-67375.full.stderr
@@ -1,5 +1,5 @@
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/issue-67375.rs:9:12
+  --> $DIR/issue-67375.rs:8:12
    |
 LL |     inner: [(); { [|_: &T| {}; 0].len() }],
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     inner: [(); { [|_: &T| {}; 0].len() }],
    = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>
 
 error[E0392]: parameter `T` is never used
-  --> $DIR/issue-67375.rs:7:12
+  --> $DIR/issue-67375.rs:6:12
    |
 LL | struct Bug<T> {
    |            ^ unused parameter
diff --git a/src/test/ui/const-generics/issue-67375.min.stderr b/src/test/ui/const-generics/issue-67375.min.stderr
index da96b5374a5..337e7bc1409 100644
--- a/src/test/ui/const-generics/issue-67375.min.stderr
+++ b/src/test/ui/const-generics/issue-67375.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-67375.rs:9:25
+  --> $DIR/issue-67375.rs:8:25
    |
 LL |     inner: [(); { [|_: &T| {}; 0].len() }],
    |                         ^ cannot perform const operation using `T`
@@ -8,7 +8,7 @@ LL |     inner: [(); { [|_: &T| {}; 0].len() }],
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error[E0392]: parameter `T` is never used
-  --> $DIR/issue-67375.rs:7:12
+  --> $DIR/issue-67375.rs:6:12
    |
 LL | struct Bug<T> {
    |            ^ unused parameter
diff --git a/src/test/ui/const-generics/issue-67375.rs b/src/test/ui/const-generics/issue-67375.rs
index ecc76bcae06..a8875b8b6bf 100644
--- a/src/test/ui/const-generics/issue-67375.rs
+++ b/src/test/ui/const-generics/issue-67375.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Bug<T> {
     //~^ ERROR parameter `T` is never used
diff --git a/src/test/ui/const-generics/issue-67945-1.full.stderr b/src/test/ui/const-generics/issue-67945-1.full.stderr
index e79c4f5374e..5cdcefe3501 100644
--- a/src/test/ui/const-generics/issue-67945-1.full.stderr
+++ b/src/test/ui/const-generics/issue-67945-1.full.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-67945-1.rs:14:20
+  --> $DIR/issue-67945-1.rs:13:20
    |
 LL | struct Bug<S> {
    |            - this type parameter
@@ -13,7 +13,7 @@ LL |         let x: S = MaybeUninit::uninit();
                        found union `MaybeUninit<_>`
 
 error[E0392]: parameter `S` is never used
-  --> $DIR/issue-67945-1.rs:11:12
+  --> $DIR/issue-67945-1.rs:10:12
    |
 LL | struct Bug<S> {
    |            ^ unused parameter
diff --git a/src/test/ui/const-generics/issue-67945-1.min.stderr b/src/test/ui/const-generics/issue-67945-1.min.stderr
index 8fea130baa5..a3e086ea954 100644
--- a/src/test/ui/const-generics/issue-67945-1.min.stderr
+++ b/src/test/ui/const-generics/issue-67945-1.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-67945-1.rs:14:16
+  --> $DIR/issue-67945-1.rs:13:16
    |
 LL |         let x: S = MaybeUninit::uninit();
    |                ^ cannot perform const operation using `S`
@@ -8,7 +8,7 @@ LL |         let x: S = MaybeUninit::uninit();
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-67945-1.rs:17:45
+  --> $DIR/issue-67945-1.rs:16:45
    |
 LL |         let b = &*(&x as *const _ as *const S);
    |                                             ^ cannot perform const operation using `S`
@@ -17,7 +17,7 @@ LL |         let b = &*(&x as *const _ as *const S);
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error[E0392]: parameter `S` is never used
-  --> $DIR/issue-67945-1.rs:11:12
+  --> $DIR/issue-67945-1.rs:10:12
    |
 LL | struct Bug<S> {
    |            ^ unused parameter
diff --git a/src/test/ui/const-generics/issue-67945-1.rs b/src/test/ui/const-generics/issue-67945-1.rs
index 6771603f259..84737e4e985 100644
--- a/src/test/ui/const-generics/issue-67945-1.rs
+++ b/src/test/ui/const-generics/issue-67945-1.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 use std::marker::PhantomData;
 
diff --git a/src/test/ui/const-generics/issue-67945-2.full.stderr b/src/test/ui/const-generics/issue-67945-2.full.stderr
index 2f54b802df8..4d96058b395 100644
--- a/src/test/ui/const-generics/issue-67945-2.full.stderr
+++ b/src/test/ui/const-generics/issue-67945-2.full.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-67945-2.rs:12:20
+  --> $DIR/issue-67945-2.rs:11:20
    |
 LL | struct Bug<S> {
    |            - this type parameter
@@ -13,7 +13,7 @@ LL |         let x: S = MaybeUninit::uninit();
                        found union `MaybeUninit<_>`
 
 error[E0392]: parameter `S` is never used
-  --> $DIR/issue-67945-2.rs:9:12
+  --> $DIR/issue-67945-2.rs:8:12
    |
 LL | struct Bug<S> {
    |            ^ unused parameter
diff --git a/src/test/ui/const-generics/issue-67945-2.min.stderr b/src/test/ui/const-generics/issue-67945-2.min.stderr
index 50633772b75..860be4a9b6a 100644
--- a/src/test/ui/const-generics/issue-67945-2.min.stderr
+++ b/src/test/ui/const-generics/issue-67945-2.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-67945-2.rs:12:16
+  --> $DIR/issue-67945-2.rs:11:16
    |
 LL |         let x: S = MaybeUninit::uninit();
    |                ^ cannot perform const operation using `S`
@@ -8,7 +8,7 @@ LL |         let x: S = MaybeUninit::uninit();
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-67945-2.rs:15:45
+  --> $DIR/issue-67945-2.rs:14:45
    |
 LL |         let b = &*(&x as *const _ as *const S);
    |                                             ^ cannot perform const operation using `S`
@@ -17,7 +17,7 @@ LL |         let b = &*(&x as *const _ as *const S);
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error[E0392]: parameter `S` is never used
-  --> $DIR/issue-67945-2.rs:9:12
+  --> $DIR/issue-67945-2.rs:8:12
    |
 LL | struct Bug<S> {
    |            ^ unused parameter
diff --git a/src/test/ui/const-generics/issue-67945-2.rs b/src/test/ui/const-generics/issue-67945-2.rs
index 72dbb674e66..4a46786e9a9 100644
--- a/src/test/ui/const-generics/issue-67945-2.rs
+++ b/src/test/ui/const-generics/issue-67945-2.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 use std::mem::MaybeUninit;
 
diff --git a/src/test/ui/const-generics/issue-67945-3.full.stderr b/src/test/ui/const-generics/issue-67945-3.full.stderr
index c33b88588c0..fa66252bd69 100644
--- a/src/test/ui/const-generics/issue-67945-3.full.stderr
+++ b/src/test/ui/const-generics/issue-67945-3.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-67945-3.rs:8:8
+  --> $DIR/issue-67945-3.rs:7:8
    |
 LL |       A: [(); {
    |  ________^
diff --git a/src/test/ui/const-generics/issue-67945-3.min.stderr b/src/test/ui/const-generics/issue-67945-3.min.stderr
index 9c6e101ece8..5c30429c895 100644
--- a/src/test/ui/const-generics/issue-67945-3.min.stderr
+++ b/src/test/ui/const-generics/issue-67945-3.min.stderr
@@ -1,5 +1,5 @@
 error: generic `Self` types are currently not permitted in anonymous constants
-  --> $DIR/issue-67945-3.rs:10:27
+  --> $DIR/issue-67945-3.rs:9:27
    |
 LL |         let x: Option<Box<Self>> = None;
    |                           ^^^^
diff --git a/src/test/ui/const-generics/issue-67945-3.rs b/src/test/ui/const-generics/issue-67945-3.rs
index bca079101e2..5bad61cfc76 100644
--- a/src/test/ui/const-generics/issue-67945-3.rs
+++ b/src/test/ui/const-generics/issue-67945-3.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Bug<S: ?Sized> {
     A: [(); {
diff --git a/src/test/ui/const-generics/issue-68104-print-stack-overflow.rs b/src/test/ui/const-generics/issue-68104-print-stack-overflow.rs
index eab63d3a6e6..43c3999133c 100644
--- a/src/test/ui/const-generics/issue-68104-print-stack-overflow.rs
+++ b/src/test/ui/const-generics/issue-68104-print-stack-overflow.rs
@@ -4,7 +4,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 extern crate impl_const;
 
diff --git a/src/test/ui/const-generics/issue-70180-1-stalled_on.rs b/src/test/ui/const-generics/issue-70180-1-stalled_on.rs
index 9cfa57006d5..f0554823273 100644
--- a/src/test/ui/const-generics/issue-70180-1-stalled_on.rs
+++ b/src/test/ui/const-generics/issue-70180-1-stalled_on.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub fn works() {
     let array/*: [_; _]*/ = default_array();
diff --git a/src/test/ui/const-generics/issue-70180-2-stalled_on.rs b/src/test/ui/const-generics/issue-70180-2-stalled_on.rs
index bbde404966c..21cefc09c25 100644
--- a/src/test/ui/const-generics/issue-70180-2-stalled_on.rs
+++ b/src/test/ui/const-generics/issue-70180-2-stalled_on.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn works() {
     let array/*: [u8; _]*/ = default_byte_array();
diff --git a/src/test/ui/const-generics/issue-71986.rs b/src/test/ui/const-generics/issue-71986.rs
index d4c962452d1..6bfdba5711e 100644
--- a/src/test/ui/const-generics/issue-71986.rs
+++ b/src/test/ui/const-generics/issue-71986.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub trait Foo<const B: bool> {}
 pub fn bar<T: Foo<{ true }>>() {}
diff --git a/src/test/ui/const-generics/issue-74906.rs b/src/test/ui/const-generics/issue-74906.rs
index 9162d1142b6..dc3c33736da 100644
--- a/src/test/ui/const-generics/issue-74906.rs
+++ b/src/test/ui/const-generics/issue-74906.rs
@@ -3,7 +3,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 const SIZE: usize = 16;
 
diff --git a/src/test/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs b/src/test/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs
index 7ea8d936d61..f59eb60cb38 100644
--- a/src/test/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs
+++ b/src/test/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs
@@ -1,6 +1,5 @@
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 // All of these three items must be in `lib2` to reproduce the error
 
diff --git a/src/test/ui/const-generics/issues/issue-56445.full.stderr b/src/test/ui/const-generics/issues/issue-56445.full.stderr
index 50e91418551..61fba92c196 100644
--- a/src/test/ui/const-generics/issues/issue-56445.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-56445.full.stderr
@@ -6,10 +6,9 @@ LL | #![cfg_attr(full, feature(const_generics))]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error[E0771]: use of non-static lifetime `'a` in const generic
-  --> $DIR/issue-56445.rs:9:26
+  --> $DIR/issue-56445.rs:8:26
    |
 LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
    |                          ^^
diff --git a/src/test/ui/const-generics/issues/issue-56445.min.stderr b/src/test/ui/const-generics/issues/issue-56445.min.stderr
index bcb27d8d1e1..80702dd4bc3 100644
--- a/src/test/ui/const-generics/issues/issue-56445.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-56445.min.stderr
@@ -1,5 +1,5 @@
 error[E0771]: use of non-static lifetime `'a` in const generic
-  --> $DIR/issue-56445.rs:9:26
+  --> $DIR/issue-56445.rs:8:26
    |
 LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
    |                          ^^
diff --git a/src/test/ui/const-generics/issues/issue-56445.rs b/src/test/ui/const-generics/issues/issue-56445.rs
index 0bcde348b05..bc9e1dee853 100644
--- a/src/test/ui/const-generics/issues/issue-56445.rs
+++ b/src/test/ui/const-generics/issues/issue-56445.rs
@@ -1,7 +1,6 @@
 // Regression test for https://github.com/rust-lang/rust/issues/56445#issuecomment-518402995.
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete
-#![cfg_attr(min, feature(min_const_generics))]
 #![crate_type = "lib"]
 
 use std::marker::PhantomData;
diff --git a/src/test/ui/const-generics/issues/issue-60263.rs b/src/test/ui/const-generics/issues/issue-60263.rs
deleted file mode 100644
index 70cbc242c41..00000000000
--- a/src/test/ui/const-generics/issues/issue-60263.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-struct B<const I: u8>; //~ ERROR const generics are unstable
-
-impl B<0> {
-    fn bug() -> Self {
-        panic!()
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-60263.stderr b/src/test/ui/const-generics/issues/issue-60263.stderr
deleted file mode 100644
index aeef296f385..00000000000
--- a/src/test/ui/const-generics/issues/issue-60263.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: const generics are unstable
-  --> $DIR/issue-60263.rs:1:16
-   |
-LL | struct B<const I: u8>;
-   |                ^
-   |
-   = note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
-   = help: add `#![feature(min_const_generics)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/const-generics/issues/issue-60818-struct-constructors.full.stderr b/src/test/ui/const-generics/issues/issue-60818-struct-constructors.full.stderr
index cc014ea429d..c03b7252a3c 100644
--- a/src/test/ui/const-generics/issues/issue-60818-struct-constructors.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-60818-struct-constructors.full.stderr
@@ -6,7 +6,6 @@ LL | #![cfg_attr(full, feature(const_generics))]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/const-generics/issues/issue-60818-struct-constructors.rs b/src/test/ui/const-generics/issues/issue-60818-struct-constructors.rs
index ae2b0520fb1..6e64c78cd8c 100644
--- a/src/test/ui/const-generics/issues/issue-60818-struct-constructors.rs
+++ b/src/test/ui/const-generics/issues/issue-60818-struct-constructors.rs
@@ -1,7 +1,6 @@
 // check-pass
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Generic<const V: usize>;
 
diff --git a/src/test/ui/const-generics/issues/issue-61336-1.full.stderr b/src/test/ui/const-generics/issues/issue-61336-1.full.stderr
index 3a9f819a626..f18728eabbb 100644
--- a/src/test/ui/const-generics/issues/issue-61336-1.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-61336-1.full.stderr
@@ -6,7 +6,6 @@ LL | #![cfg_attr(full, feature(const_generics))]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/const-generics/issues/issue-61336-1.rs b/src/test/ui/const-generics/issues/issue-61336-1.rs
index 201c0d039d9..c93b296dbb5 100644
--- a/src/test/ui/const-generics/issues/issue-61336-1.rs
+++ b/src/test/ui/const-generics/issues/issue-61336-1.rs
@@ -1,7 +1,6 @@
 // build-pass
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
     [x; N]
diff --git a/src/test/ui/const-generics/issues/issue-61336-2.full.stderr b/src/test/ui/const-generics/issues/issue-61336-2.full.stderr
index 883ebbef3e8..9f8e68d211d 100644
--- a/src/test/ui/const-generics/issues/issue-61336-2.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-61336-2.full.stderr
@@ -6,10 +6,9 @@ LL | #![cfg_attr(full, feature(const_generics))]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error[E0277]: the trait bound `T: Copy` is not satisfied
-  --> $DIR/issue-61336-2.rs:10:5
+  --> $DIR/issue-61336-2.rs:9:5
    |
 LL |     [x; { N }]
    |     ^^^^^^^^^^ the trait `Copy` is not implemented for `T`
diff --git a/src/test/ui/const-generics/issues/issue-61336-2.min.stderr b/src/test/ui/const-generics/issues/issue-61336-2.min.stderr
index 40863a4f718..82d17a87e0a 100644
--- a/src/test/ui/const-generics/issues/issue-61336-2.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-61336-2.min.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `T: Copy` is not satisfied
-  --> $DIR/issue-61336-2.rs:10:5
+  --> $DIR/issue-61336-2.rs:9:5
    |
 LL |     [x; { N }]
    |     ^^^^^^^^^^ the trait `Copy` is not implemented for `T`
diff --git a/src/test/ui/const-generics/issues/issue-61336-2.rs b/src/test/ui/const-generics/issues/issue-61336-2.rs
index 44995157cc9..a1cf641ff74 100644
--- a/src/test/ui/const-generics/issues/issue-61336-2.rs
+++ b/src/test/ui/const-generics/issues/issue-61336-2.rs
@@ -1,6 +1,5 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
     [x; { N }]
diff --git a/src/test/ui/const-generics/issues/issue-61336.full.stderr b/src/test/ui/const-generics/issues/issue-61336.full.stderr
index 3863da8da05..974e2af6fd2 100644
--- a/src/test/ui/const-generics/issues/issue-61336.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-61336.full.stderr
@@ -6,10 +6,9 @@ LL | #![cfg_attr(full, feature(const_generics))]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error[E0277]: the trait bound `T: Copy` is not satisfied
-  --> $DIR/issue-61336.rs:10:5
+  --> $DIR/issue-61336.rs:9:5
    |
 LL |     [x; N]
    |     ^^^^^^ the trait `Copy` is not implemented for `T`
diff --git a/src/test/ui/const-generics/issues/issue-61336.min.stderr b/src/test/ui/const-generics/issues/issue-61336.min.stderr
index 6c57f9ccbf5..19c7153582c 100644
--- a/src/test/ui/const-generics/issues/issue-61336.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-61336.min.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `T: Copy` is not satisfied
-  --> $DIR/issue-61336.rs:10:5
+  --> $DIR/issue-61336.rs:9:5
    |
 LL |     [x; N]
    |     ^^^^^^ the trait `Copy` is not implemented for `T`
diff --git a/src/test/ui/const-generics/issues/issue-61336.rs b/src/test/ui/const-generics/issues/issue-61336.rs
index 7c34250e6b2..c0106ee38c2 100644
--- a/src/test/ui/const-generics/issues/issue-61336.rs
+++ b/src/test/ui/const-generics/issues/issue-61336.rs
@@ -1,6 +1,5 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
     [x; N]
diff --git a/src/test/ui/const-generics/issues/issue-61422.full.stderr b/src/test/ui/const-generics/issues/issue-61422.full.stderr
index 294378a6690..ac6c378295d 100644
--- a/src/test/ui/const-generics/issues/issue-61422.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-61422.full.stderr
@@ -6,7 +6,6 @@ LL | #![cfg_attr(full, feature(const_generics))]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/const-generics/issues/issue-61422.rs b/src/test/ui/const-generics/issues/issue-61422.rs
index 649f8b4255b..421f696f3fd 100644
--- a/src/test/ui/const-generics/issues/issue-61422.rs
+++ b/src/test/ui/const-generics/issues/issue-61422.rs
@@ -1,7 +1,6 @@
 // check-pass
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete
-#![cfg_attr(min, feature(min_const_generics))]
 
 use std::mem;
 
diff --git a/src/test/ui/const-generics/issues/issue-61432.full.stderr b/src/test/ui/const-generics/issues/issue-61432.full.stderr
index eec1b20254e..82b36de45a2 100644
--- a/src/test/ui/const-generics/issues/issue-61432.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-61432.full.stderr
@@ -6,7 +6,6 @@ LL | #![cfg_attr(full, feature(const_generics))]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/const-generics/issues/issue-61432.rs b/src/test/ui/const-generics/issues/issue-61432.rs
index 91a4794099c..0e228126d77 100644
--- a/src/test/ui/const-generics/issues/issue-61432.rs
+++ b/src/test/ui/const-generics/issues/issue-61432.rs
@@ -1,7 +1,6 @@
 // run-pass
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn promote<const N: i32>() {
     // works:
diff --git a/src/test/ui/const-generics/issues/issue-61747.full.stderr b/src/test/ui/const-generics/issues/issue-61747.full.stderr
index 3a266c8e974..b7f66345c4a 100644
--- a/src/test/ui/const-generics/issues/issue-61747.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-61747.full.stderr
@@ -6,10 +6,9 @@ LL | #![cfg_attr(full, feature(const_generics))]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-61747.rs:8:23
+  --> $DIR/issue-61747.rs:7:23
    |
 LL |     fn successor() -> Const<{C + 1}> {
    |                       ^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-61747.min.stderr b/src/test/ui/const-generics/issues/issue-61747.min.stderr
index 1de9e71b6eb..b85533ccb46 100644
--- a/src/test/ui/const-generics/issues/issue-61747.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-61747.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-61747.rs:8:30
+  --> $DIR/issue-61747.rs:7:30
    |
 LL |     fn successor() -> Const<{C + 1}> {
    |                              ^ cannot perform const operation using `C`
diff --git a/src/test/ui/const-generics/issues/issue-61747.rs b/src/test/ui/const-generics/issues/issue-61747.rs
index 3a4dd1cdd18..3aa2e6a5c31 100644
--- a/src/test/ui/const-generics/issues/issue-61747.rs
+++ b/src/test/ui/const-generics/issues/issue-61747.rs
@@ -1,6 +1,5 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Const<const N: usize>;
 
diff --git a/src/test/ui/const-generics/issues/issue-61935.full.stderr b/src/test/ui/const-generics/issues/issue-61935.full.stderr
index b805bc0db7e..b970f4e4c8e 100644
--- a/src/test/ui/const-generics/issues/issue-61935.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-61935.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-61935.rs:10:14
+  --> $DIR/issue-61935.rs:9:14
    |
 LL |         Self:FooImpl<{N==0}>
    |              ^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-61935.min.stderr b/src/test/ui/const-generics/issues/issue-61935.min.stderr
index b1d92056a54..9382dca3153 100644
--- a/src/test/ui/const-generics/issues/issue-61935.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-61935.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-61935.rs:10:23
+  --> $DIR/issue-61935.rs:9:23
    |
 LL |         Self:FooImpl<{N==0}>
    |                       ^ cannot perform const operation using `N`
diff --git a/src/test/ui/const-generics/issues/issue-61935.rs b/src/test/ui/const-generics/issues/issue-61935.rs
index 9fa02329a71..ed861c63bf1 100644
--- a/src/test/ui/const-generics/issues/issue-61935.rs
+++ b/src/test/ui/const-generics/issues/issue-61935.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait Foo {}
 
diff --git a/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs b/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs
index a8fa3780356..1a0e46e599d 100644
--- a/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs
+++ b/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs
@@ -3,7 +3,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub trait BitLen: Sized {
     const BIT_LEN: usize;
diff --git a/src/test/ui/const-generics/issues/issue-62220.full.stderr b/src/test/ui/const-generics/issues/issue-62220.full.stderr
index 120aa8e4af5..373360c7ced 100644
--- a/src/test/ui/const-generics/issues/issue-62220.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-62220.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-62220.rs:13:27
+  --> $DIR/issue-62220.rs:12:27
    |
 LL |     pub fn trunc(self) -> (TruncatedVector<T, { N }>, T) {
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-62220.min.stderr b/src/test/ui/const-generics/issues/issue-62220.min.stderr
index b338cdb87e1..72311d030cf 100644
--- a/src/test/ui/const-generics/issues/issue-62220.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-62220.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-62220.rs:8:59
+  --> $DIR/issue-62220.rs:7:59
    |
 LL | pub type TruncatedVector<T, const N: usize> = Vector<T, { N - 1 }>;
    |                                                           ^ cannot perform const operation using `N`
diff --git a/src/test/ui/const-generics/issues/issue-62220.rs b/src/test/ui/const-generics/issues/issue-62220.rs
index 2017473fa9e..c26784c9813 100644
--- a/src/test/ui/const-generics/issues/issue-62220.rs
+++ b/src/test/ui/const-generics/issues/issue-62220.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub struct Vector<T, const N: usize>([T; N]);
 
diff --git a/src/test/ui/const-generics/issues/issue-62456.full.stderr b/src/test/ui/const-generics/issues/issue-62456.full.stderr
index a8d44074db9..833e70ca6d3 100644
--- a/src/test/ui/const-generics/issues/issue-62456.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-62456.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-62456.rs:7:20
+  --> $DIR/issue-62456.rs:6:20
    |
 LL |     let _ = [0u64; N + 1];
    |                    ^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-62456.min.stderr b/src/test/ui/const-generics/issues/issue-62456.min.stderr
index a4b501a7bb1..920318fa0ac 100644
--- a/src/test/ui/const-generics/issues/issue-62456.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-62456.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-62456.rs:7:20
+  --> $DIR/issue-62456.rs:6:20
    |
 LL |     let _ = [0u64; N + 1];
    |                    ^ cannot perform const operation using `N`
diff --git a/src/test/ui/const-generics/issues/issue-62456.rs b/src/test/ui/const-generics/issues/issue-62456.rs
index cbb2a11a931..e24cf36c8ce 100644
--- a/src/test/ui/const-generics/issues/issue-62456.rs
+++ b/src/test/ui/const-generics/issues/issue-62456.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn foo<const N: usize>() {
     let _ = [0u64; N + 1];
diff --git a/src/test/ui/const-generics/issues/issue-62504.full.stderr b/src/test/ui/const-generics/issues/issue-62504.full.stderr
index 9c84f06ce9f..f09af76325e 100644
--- a/src/test/ui/const-generics/issues/issue-62504.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-62504.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-62504.rs:19:25
+  --> $DIR/issue-62504.rs:18:25
    |
 LL |         ArrayHolder([0; Self::SIZE])
    |                         ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-62504.min.stderr b/src/test/ui/const-generics/issues/issue-62504.min.stderr
index 865eaf74932..5d45e302888 100644
--- a/src/test/ui/const-generics/issues/issue-62504.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-62504.min.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-62504.rs:19:21
+  --> $DIR/issue-62504.rs:18:21
    |
 LL |         ArrayHolder([0; Self::SIZE])
    |                     ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE`
@@ -8,7 +8,7 @@ LL |         ArrayHolder([0; Self::SIZE])
               found array `[u32; _]`
 
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-62504.rs:19:25
+  --> $DIR/issue-62504.rs:18:25
    |
 LL |         ArrayHolder([0; Self::SIZE])
    |                         ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-62504.rs b/src/test/ui/const-generics/issues/issue-62504.rs
index 5630962ff53..0b95754cab4 100644
--- a/src/test/ui/const-generics/issues/issue-62504.rs
+++ b/src/test/ui/const-generics/issues/issue-62504.rs
@@ -2,7 +2,6 @@
 #![allow(incomplete_features)]
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait HasSize {
     const SIZE: usize;
diff --git a/src/test/ui/const-generics/issues/issue-62579-no-match.min.stderr b/src/test/ui/const-generics/issues/issue-62579-no-match.min.stderr
index 5117e20d626..a0aee4821c6 100644
--- a/src/test/ui/const-generics/issues/issue-62579-no-match.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-62579-no-match.min.stderr
@@ -1,5 +1,5 @@
 error: `NoMatch` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-62579-no-match.rs:10:17
+  --> $DIR/issue-62579-no-match.rs:9:17
    |
 LL | fn foo<const T: NoMatch>() -> bool {
    |                 ^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-62579-no-match.rs b/src/test/ui/const-generics/issues/issue-62579-no-match.rs
index c9853aa9162..46813f5256e 100644
--- a/src/test/ui/const-generics/issues/issue-62579-no-match.rs
+++ b/src/test/ui/const-generics/issues/issue-62579-no-match.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 #[derive(PartialEq, Eq)]
 struct NoMatch;
diff --git a/src/test/ui/const-generics/issues/issue-62878.full.stderr b/src/test/ui/const-generics/issues/issue-62878.full.stderr
index dce2e27c71a..6e6aa196633 100644
--- a/src/test/ui/const-generics/issues/issue-62878.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-62878.full.stderr
@@ -1,11 +1,11 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-62878.rs:6:38
+  --> $DIR/issue-62878.rs:5:38
    |
 LL | fn foo<const N: usize, const A: [u8; N]>() {}
    |                                      ^ the type must not depend on the parameter `N`
 
 error[E0747]: type provided when a constant was expected
-  --> $DIR/issue-62878.rs:11:11
+  --> $DIR/issue-62878.rs:10:11
    |
 LL |     foo::<_, {[1]}>();
    |           ^
@@ -13,7 +13,7 @@ LL |     foo::<_, {[1]}>();
    = help: const arguments cannot yet be inferred with `_`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-62878.rs:11:15
+  --> $DIR/issue-62878.rs:10:15
    |
 LL |     foo::<_, {[1]}>();
    |               ^^^ expected `usize`, found array `[{integer}; 1]`
diff --git a/src/test/ui/const-generics/issues/issue-62878.min.stderr b/src/test/ui/const-generics/issues/issue-62878.min.stderr
index 9f95e5d8862..920d7e43b9b 100644
--- a/src/test/ui/const-generics/issues/issue-62878.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-62878.min.stderr
@@ -1,11 +1,11 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-62878.rs:6:38
+  --> $DIR/issue-62878.rs:5:38
    |
 LL | fn foo<const N: usize, const A: [u8; N]>() {}
    |                                      ^ the type must not depend on the parameter `N`
 
 error: `[u8; _]` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-62878.rs:6:33
+  --> $DIR/issue-62878.rs:5:33
    |
 LL | fn foo<const N: usize, const A: [u8; N]>() {}
    |                                 ^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-62878.rs b/src/test/ui/const-generics/issues/issue-62878.rs
index c087711e5f9..a70606c4a7d 100644
--- a/src/test/ui/const-generics/issues/issue-62878.rs
+++ b/src/test/ui/const-generics/issues/issue-62878.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn foo<const N: usize, const A: [u8; N]>() {}
 //~^ ERROR the type of const parameters must not
diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr
index a20c7264acf..e1c20e6ae78 100644
--- a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr
@@ -1,5 +1,5 @@
 error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
-  --> $DIR/issue-63322-forbid-dyn.rs:10:18
+  --> $DIR/issue-63322-forbid-dyn.rs:9:18
    |
 LL | fn test<const T: &'static dyn A>() {
    |                  ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq`
diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr
index 5dbfdc6d652..543e4b29a16 100644
--- a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr
@@ -1,5 +1,5 @@
 error: `&'static (dyn A + 'static)` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-63322-forbid-dyn.rs:10:18
+  --> $DIR/issue-63322-forbid-dyn.rs:9:18
    |
 LL | fn test<const T: &'static dyn A>() {
    |                  ^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | fn test<const T: &'static dyn A>() {
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
-  --> $DIR/issue-63322-forbid-dyn.rs:10:18
+  --> $DIR/issue-63322-forbid-dyn.rs:9:18
    |
 LL | fn test<const T: &'static dyn A>() {
    |                  ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq`
diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs
index 2194eb97a41..334e2aac02a 100644
--- a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs
+++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait A {}
 struct B;
diff --git a/src/test/ui/const-generics/issues/issue-64494.full.stderr b/src/test/ui/const-generics/issues/issue-64494.full.stderr
index a97ec9308f8..abb26d6cf17 100644
--- a/src/test/ui/const-generics/issues/issue-64494.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-64494.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-64494.rs:16:53
+  --> $DIR/issue-64494.rs:15:53
    |
 LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
    |                                                     ^^^^
@@ -7,7 +7,7 @@ LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
    = note: this may fail depending on what value the parameter takes
 
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-64494.rs:19:53
+  --> $DIR/issue-64494.rs:18:53
    |
 LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {}
    |                                                     ^^^^
diff --git a/src/test/ui/const-generics/issues/issue-64494.min.stderr b/src/test/ui/const-generics/issues/issue-64494.min.stderr
index 681166b1d2b..936ab7f6e7e 100644
--- a/src/test/ui/const-generics/issues/issue-64494.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-64494.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-64494.rs:16:38
+  --> $DIR/issue-64494.rs:15:38
    |
 LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
    |                                      ^^^^^^ cannot perform const operation using `T`
@@ -8,7 +8,7 @@ LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-64494.rs:19:38
+  --> $DIR/issue-64494.rs:18:38
    |
 LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {}
    |                                      ^^^^^^ cannot perform const operation using `T`
@@ -17,7 +17,7 @@ LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {}
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error[E0119]: conflicting implementations of trait `MyTrait`:
-  --> $DIR/issue-64494.rs:19:1
+  --> $DIR/issue-64494.rs:18:1
    |
 LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
    | ------------------------------------ first implementation here
diff --git a/src/test/ui/const-generics/issues/issue-64494.rs b/src/test/ui/const-generics/issues/issue-64494.rs
index 014742be03d..96d19203109 100644
--- a/src/test/ui/const-generics/issues/issue-64494.rs
+++ b/src/test/ui/const-generics/issues/issue-64494.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait Foo {
     const VAL: usize;
diff --git a/src/test/ui/const-generics/issues/issue-64519.rs b/src/test/ui/const-generics/issues/issue-64519.rs
index 1ca709d0975..8c603b74b90 100644
--- a/src/test/ui/const-generics/issues/issue-64519.rs
+++ b/src/test/ui/const-generics/issues/issue-64519.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo<const D: usize> {
     state: Option<[u8; D]>,
diff --git a/src/test/ui/const-generics/issues/issue-66205.full.stderr b/src/test/ui/const-generics/issues/issue-66205.full.stderr
index a1520912e4e..7e150f5f6db 100644
--- a/src/test/ui/const-generics/issues/issue-66205.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-66205.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-66205.rs:8:12
+  --> $DIR/issue-66205.rs:7:12
    |
 LL |     fact::<{ N - 1 }>();
    |            ^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-66205.min.stderr b/src/test/ui/const-generics/issues/issue-66205.min.stderr
index ecd96ac37e4..b41793b62d2 100644
--- a/src/test/ui/const-generics/issues/issue-66205.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-66205.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-66205.rs:8:14
+  --> $DIR/issue-66205.rs:7:14
    |
 LL |     fact::<{ N - 1 }>();
    |              ^ cannot perform const operation using `N`
diff --git a/src/test/ui/const-generics/issues/issue-66205.rs b/src/test/ui/const-generics/issues/issue-66205.rs
index 4e37c247d00..14249b62cee 100644
--- a/src/test/ui/const-generics/issues/issue-66205.rs
+++ b/src/test/ui/const-generics/issues/issue-66205.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 #![allow(dead_code, unconditional_recursion)]
 
 fn fact<const N: usize>() {
diff --git a/src/test/ui/const-generics/issues/issue-66906.rs b/src/test/ui/const-generics/issues/issue-66906.rs
index 3e048593c9b..a871b118dcc 100644
--- a/src/test/ui/const-generics/issues/issue-66906.rs
+++ b/src/test/ui/const-generics/issues/issue-66906.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub struct Tuple;
 
diff --git a/src/test/ui/const-generics/issues/issue-67185-1.rs b/src/test/ui/const-generics/issues/issue-67185-1.rs
index 09d88ef89a3..ed35a5f7c0a 100644
--- a/src/test/ui/const-generics/issues/issue-67185-1.rs
+++ b/src/test/ui/const-generics/issues/issue-67185-1.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait Baz {
     type Quaks;
diff --git a/src/test/ui/const-generics/issues/issue-67185-2.full.stderr b/src/test/ui/const-generics/issues/issue-67185-2.full.stderr
index 78c7ebff059..fa9c680d4b8 100644
--- a/src/test/ui/const-generics/issues/issue-67185-2.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-67185-2.full.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:17:1
+  --> $DIR/issue-67185-2.rs:16:1
    |
 LL | / trait Foo
 LL | |
@@ -17,7 +17,7 @@ LL | | }
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
 error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:17:1
+  --> $DIR/issue-67185-2.rs:16:1
    |
 LL | / trait Foo
 LL | |
@@ -35,7 +35,7 @@ LL | | }
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
 error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:27:6
+  --> $DIR/issue-67185-2.rs:26:6
    |
 LL | trait Foo
    |       --- required by a bound in this
@@ -51,7 +51,7 @@ LL | impl Foo for FooImpl {}
              <[u16; 4] as Bar>
 
 error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:27:6
+  --> $DIR/issue-67185-2.rs:26:6
    |
 LL | trait Foo
    |       --- required by a bound in this
@@ -67,7 +67,7 @@ LL | impl Foo for FooImpl {}
              <[u16; 4] as Bar>
 
 error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:31:14
+  --> $DIR/issue-67185-2.rs:30:14
    |
 LL | trait Foo
    |       --- required by a bound in this
@@ -83,7 +83,7 @@ LL | fn f(_: impl Foo) {}
              <[u16; 4] as Bar>
 
 error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:31:14
+  --> $DIR/issue-67185-2.rs:30:14
    |
 LL | trait Foo
    |       --- required by a bound in this
diff --git a/src/test/ui/const-generics/issues/issue-67185-2.min.stderr b/src/test/ui/const-generics/issues/issue-67185-2.min.stderr
index 78c7ebff059..fa9c680d4b8 100644
--- a/src/test/ui/const-generics/issues/issue-67185-2.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-67185-2.min.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:17:1
+  --> $DIR/issue-67185-2.rs:16:1
    |
 LL | / trait Foo
 LL | |
@@ -17,7 +17,7 @@ LL | | }
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
 error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:17:1
+  --> $DIR/issue-67185-2.rs:16:1
    |
 LL | / trait Foo
 LL | |
@@ -35,7 +35,7 @@ LL | | }
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
 error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:27:6
+  --> $DIR/issue-67185-2.rs:26:6
    |
 LL | trait Foo
    |       --- required by a bound in this
@@ -51,7 +51,7 @@ LL | impl Foo for FooImpl {}
              <[u16; 4] as Bar>
 
 error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:27:6
+  --> $DIR/issue-67185-2.rs:26:6
    |
 LL | trait Foo
    |       --- required by a bound in this
@@ -67,7 +67,7 @@ LL | impl Foo for FooImpl {}
              <[u16; 4] as Bar>
 
 error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:31:14
+  --> $DIR/issue-67185-2.rs:30:14
    |
 LL | trait Foo
    |       --- required by a bound in this
@@ -83,7 +83,7 @@ LL | fn f(_: impl Foo) {}
              <[u16; 4] as Bar>
 
 error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
-  --> $DIR/issue-67185-2.rs:31:14
+  --> $DIR/issue-67185-2.rs:30:14
    |
 LL | trait Foo
    |       --- required by a bound in this
diff --git a/src/test/ui/const-generics/issues/issue-67185-2.rs b/src/test/ui/const-generics/issues/issue-67185-2.rs
index 1176d0c6904..94a713d7cf9 100644
--- a/src/test/ui/const-generics/issues/issue-67185-2.rs
+++ b/src/test/ui/const-generics/issues/issue-67185-2.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait Baz {
     type Quaks;
diff --git a/src/test/ui/const-generics/issues/issue-67739.full.stderr b/src/test/ui/const-generics/issues/issue-67739.full.stderr
index 27a56b8eb02..dcbe5b94a62 100644
--- a/src/test/ui/const-generics/issues/issue-67739.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-67739.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-67739.rs:12:15
+  --> $DIR/issue-67739.rs:11:15
    |
 LL |         [0u8; mem::size_of::<Self::Associated>()];
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-67739.min.stderr b/src/test/ui/const-generics/issues/issue-67739.min.stderr
index 27a56b8eb02..dcbe5b94a62 100644
--- a/src/test/ui/const-generics/issues/issue-67739.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-67739.min.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-67739.rs:12:15
+  --> $DIR/issue-67739.rs:11:15
    |
 LL |         [0u8; mem::size_of::<Self::Associated>()];
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-67739.rs b/src/test/ui/const-generics/issues/issue-67739.rs
index 0f5860f22fd..e4960e56c9e 100644
--- a/src/test/ui/const-generics/issues/issue-67739.rs
+++ b/src/test/ui/const-generics/issues/issue-67739.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 use std::mem;
 
diff --git a/src/test/ui/const-generics/issues/issue-68366.full.stderr b/src/test/ui/const-generics/issues/issue-68366.full.stderr
index ac774f50c74..4015fb090b9 100644
--- a/src/test/ui/const-generics/issues/issue-68366.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-68366.full.stderr
@@ -1,5 +1,5 @@
 error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/issue-68366.rs:12:13
+  --> $DIR/issue-68366.rs:11:13
    |
 LL | impl <const N: usize> Collatz<{Some(N)}> {}
    |             ^ unconstrained const parameter
@@ -8,7 +8,7 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {}
    = note: proving the result of expressions other than the parameter are unique is not supported
 
 error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/issue-68366.rs:18:12
+  --> $DIR/issue-68366.rs:17:12
    |
 LL | impl<const N: usize> Foo {}
    |            ^ unconstrained const parameter
diff --git a/src/test/ui/const-generics/issues/issue-68366.min.stderr b/src/test/ui/const-generics/issues/issue-68366.min.stderr
index acaf4a33ee0..da4cbd3081f 100644
--- a/src/test/ui/const-generics/issues/issue-68366.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-68366.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-68366.rs:12:37
+  --> $DIR/issue-68366.rs:11:37
    |
 LL | impl <const N: usize> Collatz<{Some(N)}> {}
    |                                     ^ cannot perform const operation using `N`
@@ -8,7 +8,7 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {}
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/issue-68366.rs:12:13
+  --> $DIR/issue-68366.rs:11:13
    |
 LL | impl <const N: usize> Collatz<{Some(N)}> {}
    |             ^ unconstrained const parameter
@@ -17,7 +17,7 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {}
    = note: proving the result of expressions other than the parameter are unique is not supported
 
 error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/issue-68366.rs:18:12
+  --> $DIR/issue-68366.rs:17:12
    |
 LL | impl<const N: usize> Foo {}
    |            ^ unconstrained const parameter
diff --git a/src/test/ui/const-generics/issues/issue-68366.rs b/src/test/ui/const-generics/issues/issue-68366.rs
index 474cdb7258d..37afed62327 100644
--- a/src/test/ui/const-generics/issues/issue-68366.rs
+++ b/src/test/ui/const-generics/issues/issue-68366.rs
@@ -5,7 +5,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Collatz<const N: Option<usize>>;
 
diff --git a/src/test/ui/const-generics/issues/issue-68596.rs b/src/test/ui/const-generics/issues/issue-68596.rs
index 3b27d4d68c5..0bb23be1eb4 100644
--- a/src/test/ui/const-generics/issues/issue-68596.rs
+++ b/src/test/ui/const-generics/issues/issue-68596.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub struct S(u8);
 
diff --git a/src/test/ui/const-generics/issues/issue-68615-adt.min.stderr b/src/test/ui/const-generics/issues/issue-68615-adt.min.stderr
index 59653114a6b..2de8ada2766 100644
--- a/src/test/ui/const-generics/issues/issue-68615-adt.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-68615-adt.min.stderr
@@ -1,5 +1,5 @@
 error: `[usize; 0]` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-68615-adt.rs:7:23
+  --> $DIR/issue-68615-adt.rs:6:23
    |
 LL | struct Const<const V: [usize; 0]> {}
    |                       ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-68615-adt.rs b/src/test/ui/const-generics/issues/issue-68615-adt.rs
index d616f3ab95a..ddea3e8ab65 100644
--- a/src/test/ui/const-generics/issues/issue-68615-adt.rs
+++ b/src/test/ui/const-generics/issues/issue-68615-adt.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Const<const V: [usize; 0]> {}
 //[min]~^ ERROR `[usize; 0]` is forbidden as the type of a const generic parameter
diff --git a/src/test/ui/const-generics/issues/issue-68615-array.min.stderr b/src/test/ui/const-generics/issues/issue-68615-array.min.stderr
index 1ee881b96ec..0d17b04a5cd 100644
--- a/src/test/ui/const-generics/issues/issue-68615-array.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-68615-array.min.stderr
@@ -1,5 +1,5 @@
 error: `[usize; 0]` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-68615-array.rs:7:21
+  --> $DIR/issue-68615-array.rs:6:21
    |
 LL | struct Foo<const V: [usize; 0] > {}
    |                     ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-68615-array.rs b/src/test/ui/const-generics/issues/issue-68615-array.rs
index 24c9a59a185..56afd9b2a15 100644
--- a/src/test/ui/const-generics/issues/issue-68615-array.rs
+++ b/src/test/ui/const-generics/issues/issue-68615-array.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo<const V: [usize; 0] > {}
 //[min]~^ ERROR `[usize; 0]` is forbidden as the type of a const generic parameter
diff --git a/src/test/ui/const-generics/issues/issue-68977.full.stderr b/src/test/ui/const-generics/issues/issue-68977.full.stderr
index 3690bac3eb3..25dcd88a4af 100644
--- a/src/test/ui/const-generics/issues/issue-68977.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-68977.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-68977.rs:35:44
+  --> $DIR/issue-68977.rs:34:44
    |
 LL |     FxpStorageHelper<INT_BITS, FRAC_BITS>: FxpStorage,
    |                                            ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-68977.min.stderr b/src/test/ui/const-generics/issues/issue-68977.min.stderr
index ea91df1e0bf..0b3d5b9a760 100644
--- a/src/test/ui/const-generics/issues/issue-68977.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-68977.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-68977.rs:29:17
+  --> $DIR/issue-68977.rs:28:17
    |
 LL |     PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>;
    |                 ^^^^^^^^ cannot perform const operation using `INT_BITS`
@@ -8,7 +8,7 @@ LL |     PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>;
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-68977.rs:29:28
+  --> $DIR/issue-68977.rs:28:28
    |
 LL |     PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>;
    |                            ^^^^^^^^^ cannot perform const operation using `FRAC_BITS`
diff --git a/src/test/ui/const-generics/issues/issue-68977.rs b/src/test/ui/const-generics/issues/issue-68977.rs
index 4fea94cb465..a0ffcc84c7a 100644
--- a/src/test/ui/const-generics/issues/issue-68977.rs
+++ b/src/test/ui/const-generics/issues/issue-68977.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct PhantomU8<const X: u8>;
 
diff --git a/src/test/ui/const-generics/issues/issue-70125-1.rs b/src/test/ui/const-generics/issues/issue-70125-1.rs
index 04175089dc0..5c118d245a1 100644
--- a/src/test/ui/const-generics/issues/issue-70125-1.rs
+++ b/src/test/ui/const-generics/issues/issue-70125-1.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 const L: usize = 4;
 
diff --git a/src/test/ui/const-generics/issues/issue-70125-2.rs b/src/test/ui/const-generics/issues/issue-70125-2.rs
index ceefc2dcb32..f82131262d6 100644
--- a/src/test/ui/const-generics/issues/issue-70125-2.rs
+++ b/src/test/ui/const-generics/issues/issue-70125-2.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn main() {
     <()>::foo();
diff --git a/src/test/ui/const-generics/issues/issue-70167.rs b/src/test/ui/const-generics/issues/issue-70167.rs
index 04c76a4dcaf..9e912b69177 100644
--- a/src/test/ui/const-generics/issues/issue-70167.rs
+++ b/src/test/ui/const-generics/issues/issue-70167.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub trait Trait<const N: usize>: From<<Self as Trait<N>>::Item> {
   type Item;
diff --git a/src/test/ui/const-generics/issues/issue-71169.full.stderr b/src/test/ui/const-generics/issues/issue-71169.full.stderr
index b87825d20ce..7b1a2f98dfe 100644
--- a/src/test/ui/const-generics/issues/issue-71169.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-71169.full.stderr
@@ -1,11 +1,11 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71169.rs:6:43
+  --> $DIR/issue-71169.rs:5:43
    |
 LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
    |                                           ^^^ the type must not depend on the parameter `LEN`
 
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-71169.rs:11:14
+  --> $DIR/issue-71169.rs:10:14
    |
 LL |     foo::<4, DATA>();
    |              ^^^^
diff --git a/src/test/ui/const-generics/issues/issue-71169.min.stderr b/src/test/ui/const-generics/issues/issue-71169.min.stderr
index 9b0a2946ca6..68ac47460b3 100644
--- a/src/test/ui/const-generics/issues/issue-71169.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-71169.min.stderr
@@ -1,11 +1,11 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71169.rs:6:43
+  --> $DIR/issue-71169.rs:5:43
    |
 LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
    |                                           ^^^ the type must not depend on the parameter `LEN`
 
 error: `[u8; _]` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-71169.rs:6:38
+  --> $DIR/issue-71169.rs:5:38
    |
 LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
    |                                      ^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-71169.rs b/src/test/ui/const-generics/issues/issue-71169.rs
index 7007ec222ca..a574da4b6b3 100644
--- a/src/test/ui/const-generics/issues/issue-71169.rs
+++ b/src/test/ui/const-generics/issues/issue-71169.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
 //~^ ERROR the type of const parameters must not
diff --git a/src/test/ui/const-generics/issues/issue-71381.full.stderr b/src/test/ui/const-generics/issues/issue-71381.full.stderr
index 453ef00e6dc..3950317b370 100644
--- a/src/test/ui/const-generics/issues/issue-71381.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-71381.full.stderr
@@ -1,23 +1,23 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71381.rs:15:82
+  --> $DIR/issue-71381.rs:14:82
    |
 LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
    |                                                                                  ^^^^ the type must not depend on the parameter `Args`
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71381.rs:24:40
+  --> $DIR/issue-71381.rs:23:40
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                                        ^^^^ the type must not depend on the parameter `Args`
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71381.rs:15:61
+  --> $DIR/issue-71381.rs:14:61
    |
 LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
    |                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71381.rs:24:19
+  --> $DIR/issue-71381.rs:23:19
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-71381.min.stderr b/src/test/ui/const-generics/issues/issue-71381.min.stderr
index 453ef00e6dc..3950317b370 100644
--- a/src/test/ui/const-generics/issues/issue-71381.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-71381.min.stderr
@@ -1,23 +1,23 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71381.rs:15:82
+  --> $DIR/issue-71381.rs:14:82
    |
 LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
    |                                                                                  ^^^^ the type must not depend on the parameter `Args`
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71381.rs:24:40
+  --> $DIR/issue-71381.rs:23:40
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                                        ^^^^ the type must not depend on the parameter `Args`
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71381.rs:15:61
+  --> $DIR/issue-71381.rs:14:61
    |
 LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
    |                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71381.rs:24:19
+  --> $DIR/issue-71381.rs:23:19
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-71381.rs b/src/test/ui/const-generics/issues/issue-71381.rs
index 65d88e553b9..f015d694695 100644
--- a/src/test/ui/const-generics/issues/issue-71381.rs
+++ b/src/test/ui/const-generics/issues/issue-71381.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Test(*const usize);
 
diff --git a/src/test/ui/const-generics/issues/issue-71382.full.stderr b/src/test/ui/const-generics/issues/issue-71382.full.stderr
index 3da85ee040d..715037bd5f1 100644
--- a/src/test/ui/const-generics/issues/issue-71382.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-71382.full.stderr
@@ -1,5 +1,5 @@
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71382.rs:17:23
+  --> $DIR/issue-71382.rs:16:23
    |
 LL |     fn test<const FN: fn()>(&self) {
    |                       ^^^^
diff --git a/src/test/ui/const-generics/issues/issue-71382.min.stderr b/src/test/ui/const-generics/issues/issue-71382.min.stderr
index 3da85ee040d..715037bd5f1 100644
--- a/src/test/ui/const-generics/issues/issue-71382.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-71382.min.stderr
@@ -1,5 +1,5 @@
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71382.rs:17:23
+  --> $DIR/issue-71382.rs:16:23
    |
 LL |     fn test<const FN: fn()>(&self) {
    |                       ^^^^
diff --git a/src/test/ui/const-generics/issues/issue-71382.rs b/src/test/ui/const-generics/issues/issue-71382.rs
index 12a7d08382a..3a56db937de 100644
--- a/src/test/ui/const-generics/issues/issue-71382.rs
+++ b/src/test/ui/const-generics/issues/issue-71382.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Test();
 
diff --git a/src/test/ui/const-generics/issues/issue-71611.full.stderr b/src/test/ui/const-generics/issues/issue-71611.full.stderr
index 48d4bb361a1..01a85b745ce 100644
--- a/src/test/ui/const-generics/issues/issue-71611.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-71611.full.stderr
@@ -1,11 +1,11 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71611.rs:6:31
+  --> $DIR/issue-71611.rs:5:31
    |
 LL | fn func<A, const F: fn(inner: A)>(outer: A) {
    |                               ^ the type must not depend on the parameter `A`
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71611.rs:6:21
+  --> $DIR/issue-71611.rs:5:21
    |
 LL | fn func<A, const F: fn(inner: A)>(outer: A) {
    |                     ^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-71611.min.stderr b/src/test/ui/const-generics/issues/issue-71611.min.stderr
index 48d4bb361a1..01a85b745ce 100644
--- a/src/test/ui/const-generics/issues/issue-71611.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-71611.min.stderr
@@ -1,11 +1,11 @@
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71611.rs:6:31
+  --> $DIR/issue-71611.rs:5:31
    |
 LL | fn func<A, const F: fn(inner: A)>(outer: A) {
    |                               ^ the type must not depend on the parameter `A`
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71611.rs:6:21
+  --> $DIR/issue-71611.rs:5:21
    |
 LL | fn func<A, const F: fn(inner: A)>(outer: A) {
    |                     ^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-71611.rs b/src/test/ui/const-generics/issues/issue-71611.rs
index 9b8e8be6bc6..6468d0b6bda 100644
--- a/src/test/ui/const-generics/issues/issue-71611.rs
+++ b/src/test/ui/const-generics/issues/issue-71611.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn func<A, const F: fn(inner: A)>(outer: A) {
     //~^ ERROR: using function pointers as const generic parameters is forbidden
diff --git a/src/test/ui/const-generics/issues/issue-72352.full.stderr b/src/test/ui/const-generics/issues/issue-72352.full.stderr
index 51f94678467..eedd73c4dcc 100644
--- a/src/test/ui/const-generics/issues/issue-72352.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-72352.full.stderr
@@ -1,5 +1,5 @@
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-72352.rs:8:42
+  --> $DIR/issue-72352.rs:7:42
    |
 LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize {
    |                                          ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-72352.min.stderr b/src/test/ui/const-generics/issues/issue-72352.min.stderr
index 51f94678467..eedd73c4dcc 100644
--- a/src/test/ui/const-generics/issues/issue-72352.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-72352.min.stderr
@@ -1,5 +1,5 @@
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-72352.rs:8:42
+  --> $DIR/issue-72352.rs:7:42
    |
 LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize {
    |                                          ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-72352.rs b/src/test/ui/const-generics/issues/issue-72352.rs
index 1517f3dae4f..9cd95c11026 100644
--- a/src/test/ui/const-generics/issues/issue-72352.rs
+++ b/src/test/ui/const-generics/issues/issue-72352.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 use std::ffi::{CStr, CString};
 
diff --git a/src/test/ui/const-generics/issues/issue-72787.full.stderr b/src/test/ui/const-generics/issues/issue-72787.full.stderr
index b4c79d4171b..fbb7ae59bef 100644
--- a/src/test/ui/const-generics/issues/issue-72787.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-72787.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-72787.rs:11:32
+  --> $DIR/issue-72787.rs:10:32
    |
 LL |     Condition<{ LHS <= RHS }>: True
    |                                ^^^^
@@ -7,7 +7,7 @@ LL |     Condition<{ LHS <= RHS }>: True
    = note: this may fail depending on what value the parameter takes
 
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-72787.rs:26:42
+  --> $DIR/issue-72787.rs:25:42
    |
 LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    |                                          ^^^^
@@ -15,7 +15,7 @@ LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    = note: this may fail depending on what value the parameter takes
 
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-72787.rs:26:42
+  --> $DIR/issue-72787.rs:25:42
    |
 LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    |                                          ^^^^
@@ -23,7 +23,7 @@ LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    = note: this may fail depending on what value the parameter takes
 
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-72787.rs:26:42
+  --> $DIR/issue-72787.rs:25:42
    |
 LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    |                                          ^^^^
@@ -31,7 +31,7 @@ LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    = note: this may fail depending on what value the parameter takes
 
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-72787.rs:26:42
+  --> $DIR/issue-72787.rs:25:42
    |
 LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    |                                          ^^^^
diff --git a/src/test/ui/const-generics/issues/issue-72787.min.stderr b/src/test/ui/const-generics/issues/issue-72787.min.stderr
index 27bbc28011f..aadf19ba6b6 100644
--- a/src/test/ui/const-generics/issues/issue-72787.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-72787.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-72787.rs:11:17
+  --> $DIR/issue-72787.rs:10:17
    |
 LL |     Condition<{ LHS <= RHS }>: True
    |                 ^^^ cannot perform const operation using `LHS`
@@ -8,7 +8,7 @@ LL |     Condition<{ LHS <= RHS }>: True
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-72787.rs:11:24
+  --> $DIR/issue-72787.rs:10:24
    |
 LL |     Condition<{ LHS <= RHS }>: True
    |                        ^^^ cannot perform const operation using `RHS`
@@ -17,7 +17,7 @@ LL |     Condition<{ LHS <= RHS }>: True
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-72787.rs:26:25
+  --> $DIR/issue-72787.rs:25:25
    |
 LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    |                         ^ cannot perform const operation using `I`
@@ -26,7 +26,7 @@ LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-72787.rs:26:36
+  --> $DIR/issue-72787.rs:25:36
    |
 LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    |                                    ^ cannot perform const operation using `J`
@@ -35,7 +35,7 @@ LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error[E0283]: type annotations needed
-  --> $DIR/issue-72787.rs:22:26
+  --> $DIR/issue-72787.rs:21:26
    |
 LL | pub trait True {}
    | -------------- required by this bound in `True`
@@ -46,7 +46,7 @@ LL |     IsLessOrEqual<I, 8>: True,
    = note: cannot satisfy `IsLessOrEqual<I, 8_u32>: True`
 
 error[E0283]: type annotations needed
-  --> $DIR/issue-72787.rs:22:26
+  --> $DIR/issue-72787.rs:21:26
    |
 LL | pub trait True {}
    | -------------- required by this bound in `True`
diff --git a/src/test/ui/const-generics/issues/issue-72787.rs b/src/test/ui/const-generics/issues/issue-72787.rs
index 57572e23aa4..16bc9470470 100644
--- a/src/test/ui/const-generics/issues/issue-72787.rs
+++ b/src/test/ui/const-generics/issues/issue-72787.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub struct IsLessOrEqual<const LHS: u32, const RHS: u32>;
 pub struct Condition<const CONDITION: bool>;
diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.full.stderr b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.full.stderr
index b4994004721..82f9b9d346d 100644
--- a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-72819-generic-in-const-eval.rs:9:39
+  --> $DIR/issue-72819-generic-in-const-eval.rs:8:39
    |
 LL | where Assert::<{N < usize::MAX / 2}>: IsTrue,
    |                                       ^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr
index 8df3c85ec1f..6646be47b31 100644
--- a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-72819-generic-in-const-eval.rs:9:17
+  --> $DIR/issue-72819-generic-in-const-eval.rs:8:17
    |
 LL | where Assert::<{N < usize::MAX / 2}>: IsTrue,
    |                 ^ cannot perform const operation using `N`
diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs
index 4c0004795f0..f612d8bd3f6 100644
--- a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs
+++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs
@@ -3,7 +3,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Arr<const N: usize>
 where Assert::<{N < usize::MAX / 2}>: IsTrue,
diff --git a/src/test/ui/const-generics/issues/issue-73491.min.stderr b/src/test/ui/const-generics/issues/issue-73491.min.stderr
index 3ff0563acc7..aeab9e26772 100644
--- a/src/test/ui/const-generics/issues/issue-73491.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-73491.min.stderr
@@ -1,5 +1,5 @@
 error: `[u32; _]` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-73491.rs:9:19
+  --> $DIR/issue-73491.rs:8:19
    |
 LL | fn hoge<const IN: [u32; LEN]>() {}
    |                   ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-73491.rs b/src/test/ui/const-generics/issues/issue-73491.rs
index 4f6c44ad2cd..c7cb92baf30 100644
--- a/src/test/ui/const-generics/issues/issue-73491.rs
+++ b/src/test/ui/const-generics/issues/issue-73491.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 const LEN: usize = 1024;
 
diff --git a/src/test/ui/const-generics/issues/issue-73508.full.stderr b/src/test/ui/const-generics/issues/issue-73508.full.stderr
index 0816bad35b2..81691a14ef6 100644
--- a/src/test/ui/const-generics/issues/issue-73508.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-73508.full.stderr
@@ -1,5 +1,5 @@
 error: using raw pointers as const generic parameters is forbidden
-  --> $DIR/issue-73508.rs:6:33
+  --> $DIR/issue-73508.rs:5:33
    |
 LL | pub const fn func_name<const X: *const u32>() {}
    |                                 ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-73508.min.stderr b/src/test/ui/const-generics/issues/issue-73508.min.stderr
index 0816bad35b2..81691a14ef6 100644
--- a/src/test/ui/const-generics/issues/issue-73508.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-73508.min.stderr
@@ -1,5 +1,5 @@
 error: using raw pointers as const generic parameters is forbidden
-  --> $DIR/issue-73508.rs:6:33
+  --> $DIR/issue-73508.rs:5:33
    |
 LL | pub const fn func_name<const X: *const u32>() {}
    |                                 ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-73508.rs b/src/test/ui/const-generics/issues/issue-73508.rs
index 21b87f7f901..f02c4161dc1 100644
--- a/src/test/ui/const-generics/issues/issue-73508.rs
+++ b/src/test/ui/const-generics/issues/issue-73508.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub const fn func_name<const X: *const u32>() {}
 //~^ ERROR using raw pointers
diff --git a/src/test/ui/const-generics/issues/issue-74101.min.stderr b/src/test/ui/const-generics/issues/issue-74101.min.stderr
index 1351246667e..6561183f7ca 100644
--- a/src/test/ui/const-generics/issues/issue-74101.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-74101.min.stderr
@@ -1,5 +1,5 @@
 error: `[u8; _]` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74101.rs:7:18
+  --> $DIR/issue-74101.rs:6:18
    |
 LL | fn test<const N: [u8; 1 + 2]>() {}
    |                  ^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | fn test<const N: [u8; 1 + 2]>() {}
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `[u8; _]` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74101.rs:10:21
+  --> $DIR/issue-74101.rs:9:21
    |
 LL | struct Foo<const N: [u8; 1 + 2]>;
    |                     ^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-74101.rs b/src/test/ui/const-generics/issues/issue-74101.rs
index 2a7d31ac8dd..d4fd72eb6da 100644
--- a/src/test/ui/const-generics/issues/issue-74101.rs
+++ b/src/test/ui/const-generics/issues/issue-74101.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn test<const N: [u8; 1 + 2]>() {}
 //[min]~^ ERROR `[u8; _]` is forbidden as the type of a const generic parameter
diff --git a/src/test/ui/const-generics/issues/issue-74255.min.stderr b/src/test/ui/const-generics/issues/issue-74255.min.stderr
index e3e8502ae63..2b6aa7dad97 100644
--- a/src/test/ui/const-generics/issues/issue-74255.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-74255.min.stderr
@@ -1,5 +1,5 @@
 error: `IceEnum` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74255.rs:15:31
+  --> $DIR/issue-74255.rs:14:31
    |
 LL |     fn ice_struct_fn<const I: IceEnum>() {}
    |                               ^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-74255.rs b/src/test/ui/const-generics/issues/issue-74255.rs
index b277c273461..75a876c27e5 100644
--- a/src/test/ui/const-generics/issues/issue-74255.rs
+++ b/src/test/ui/const-generics/issues/issue-74255.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 #[derive(PartialEq, Eq)]
 enum IceEnum {
diff --git a/src/test/ui/const-generics/issues/issue-74950.min.stderr b/src/test/ui/const-generics/issues/issue-74950.min.stderr
index 12947a2ab37..27393d38c6b 100644
--- a/src/test/ui/const-generics/issues/issue-74950.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-74950.min.stderr
@@ -1,5 +1,5 @@
 error: `Inner` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74950.rs:18:23
+  --> $DIR/issue-74950.rs:17:23
    |
 LL | struct Outer<const I: Inner>;
    |                       ^^^^^
@@ -8,7 +8,7 @@ LL | struct Outer<const I: Inner>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `Inner` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74950.rs:18:23
+  --> $DIR/issue-74950.rs:17:23
    |
 LL | struct Outer<const I: Inner>;
    |                       ^^^^^
@@ -17,7 +17,7 @@ LL | struct Outer<const I: Inner>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `Inner` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74950.rs:18:23
+  --> $DIR/issue-74950.rs:17:23
    |
 LL | struct Outer<const I: Inner>;
    |                       ^^^^^
@@ -26,7 +26,7 @@ LL | struct Outer<const I: Inner>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `Inner` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74950.rs:18:23
+  --> $DIR/issue-74950.rs:17:23
    |
 LL | struct Outer<const I: Inner>;
    |                       ^^^^^
@@ -35,7 +35,7 @@ LL | struct Outer<const I: Inner>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `Inner` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74950.rs:18:23
+  --> $DIR/issue-74950.rs:17:23
    |
 LL | struct Outer<const I: Inner>;
    |                       ^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-74950.rs b/src/test/ui/const-generics/issues/issue-74950.rs
index 39f91f2b83d..91e5cc776fa 100644
--- a/src/test/ui/const-generics/issues/issue-74950.rs
+++ b/src/test/ui/const-generics/issues/issue-74950.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 
 #[derive(PartialEq, Eq)]
diff --git a/src/test/ui/const-generics/issues/issue-75047.min.stderr b/src/test/ui/const-generics/issues/issue-75047.min.stderr
index b87bb18a5a6..4ab90dd1ec6 100644
--- a/src/test/ui/const-generics/issues/issue-75047.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-75047.min.stderr
@@ -1,5 +1,5 @@
 error: `[u8; _]` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-75047.rs:15:21
+  --> $DIR/issue-75047.rs:14:21
    |
 LL | struct Foo<const N: [u8; Bar::<u32>::value()]>;
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-75047.rs b/src/test/ui/const-generics/issues/issue-75047.rs
index 7bab7cdd098..97437748177 100644
--- a/src/test/ui/const-generics/issues/issue-75047.rs
+++ b/src/test/ui/const-generics/issues/issue-75047.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Bar<T>(T);
 
diff --git a/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.full.stderr b/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.full.stderr
index 089937e66ca..88b8ff89ffe 100644
--- a/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-76701-ty-param-in-const.rs:6:21
+  --> $DIR/issue-76701-ty-param-in-const.rs:5:21
    |
 LL | fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] {
    = note: this may fail depending on what value the parameter takes
 
 error: constant expression depends on a generic parameter
-  --> $DIR/issue-76701-ty-param-in-const.rs:12:37
+  --> $DIR/issue-76701-ty-param-in-const.rs:11:37
    |
 LL | fn const_param<const N: usize>() -> [u8; N + 1] {
    |                                     ^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.min.stderr b/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.min.stderr
index 551b8e43e1d..32f70fa3007 100644
--- a/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-76701-ty-param-in-const.rs:6:46
+  --> $DIR/issue-76701-ty-param-in-const.rs:5:46
    |
 LL | fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] {
    |                                              ^ cannot perform const operation using `T`
@@ -8,7 +8,7 @@ LL | fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] {
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-76701-ty-param-in-const.rs:12:42
+  --> $DIR/issue-76701-ty-param-in-const.rs:11:42
    |
 LL | fn const_param<const N: usize>() -> [u8; N + 1] {
    |                                          ^ cannot perform const operation using `N`
diff --git a/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.rs b/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.rs
index 9051c36fe81..99489826563 100644
--- a/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.rs
+++ b/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] {
     //[full]~^ ERROR constant expression depends on a generic parameter
diff --git a/src/test/ui/const-generics/issues/issue-80062.rs b/src/test/ui/const-generics/issues/issue-80062.rs
new file mode 100644
index 00000000000..56dc53298fb
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-80062.rs
@@ -0,0 +1,10 @@
+// Regression test for issue #80062 (fixed by `min_const_generics`)
+
+fn sof<T>() -> T { unimplemented!() }
+
+fn test<T>() {
+    let _: [u8; sof::<T>()];
+    //~^ ERROR generic parameters may not be used in const operations
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-80062.stderr b/src/test/ui/const-generics/issues/issue-80062.stderr
new file mode 100644
index 00000000000..aad8907bda2
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-80062.stderr
@@ -0,0 +1,11 @@
+error: generic parameters may not be used in const operations
+  --> $DIR/issue-80062.rs:6:23
+   |
+LL |     let _: [u8; sof::<T>()];
+   |                       ^ cannot perform const operation using `T`
+   |
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-80375.rs b/src/test/ui/const-generics/issues/issue-80375.rs
new file mode 100644
index 00000000000..c906bb2c4d9
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-80375.rs
@@ -0,0 +1,4 @@
+struct MyArray<const COUNT: usize>([u8; COUNT + 1]);
+//~^ ERROR generic parameters may not be used in const operations
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-80375.stderr b/src/test/ui/const-generics/issues/issue-80375.stderr
new file mode 100644
index 00000000000..9765a639a48
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-80375.stderr
@@ -0,0 +1,11 @@
+error: generic parameters may not be used in const operations
+  --> $DIR/issue-80375.rs:1:41
+   |
+LL | struct MyArray<const COUNT: usize>([u8; COUNT + 1]);
+   |                                         ^^^^^ cannot perform const operation using `COUNT`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `COUNT`
+   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs b/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
index 28f80702dcf..189a32570f7 100644
--- a/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
+++ b/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait T<const A: usize> {
     fn f();
diff --git a/src/test/ui/const-generics/macro_rules-braces.full.stderr b/src/test/ui/const-generics/macro_rules-braces.full.stderr
index 3c9d4c9b470..1883f454e60 100644
--- a/src/test/ui/const-generics/macro_rules-braces.full.stderr
+++ b/src/test/ui/const-generics/macro_rules-braces.full.stderr
@@ -1,5 +1,5 @@
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/macro_rules-braces.rs:49:17
+  --> $DIR/macro_rules-braces.rs:48:17
    |
 LL |     let _: baz!(m::P);
    |                 ^^^^
@@ -10,7 +10,7 @@ LL |     let _: baz!({ m::P });
    |                 ^      ^
 
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/macro_rules-braces.rs:69:17
+  --> $DIR/macro_rules-braces.rs:68:17
    |
 LL |     let _: baz!(10 + 7);
    |                 ^^^^^^
@@ -21,7 +21,7 @@ LL |     let _: baz!({ 10 + 7 });
    |                 ^        ^
 
 error: constant expression depends on a generic parameter
-  --> $DIR/macro_rules-braces.rs:16:13
+  --> $DIR/macro_rules-braces.rs:15:13
    |
 LL |             [u8; $x]
    |             ^^^^^^^^
@@ -33,7 +33,7 @@ LL |     let _: foo!({{ N }});
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: constant expression depends on a generic parameter
-  --> $DIR/macro_rules-braces.rs:21:13
+  --> $DIR/macro_rules-braces.rs:20:13
    |
 LL |             [u8; { $x }]
    |             ^^^^^^^^^^^^
@@ -45,7 +45,7 @@ LL |     let _: bar!({ N });
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: constant expression depends on a generic parameter
-  --> $DIR/macro_rules-braces.rs:26:13
+  --> $DIR/macro_rules-braces.rs:25:13
    |
 LL |             Foo<$x>
    |             ^^^^^^^
@@ -57,7 +57,7 @@ LL |     let _: baz!({{ N }});
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: constant expression depends on a generic parameter
-  --> $DIR/macro_rules-braces.rs:31:13
+  --> $DIR/macro_rules-braces.rs:30:13
    |
 LL |             Foo<{ $x }>
    |             ^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/macro_rules-braces.min.stderr b/src/test/ui/const-generics/macro_rules-braces.min.stderr
index c400e2c814d..60583d43c01 100644
--- a/src/test/ui/const-generics/macro_rules-braces.min.stderr
+++ b/src/test/ui/const-generics/macro_rules-braces.min.stderr
@@ -1,5 +1,5 @@
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/macro_rules-braces.rs:49:17
+  --> $DIR/macro_rules-braces.rs:48:17
    |
 LL |     let _: baz!(m::P);
    |                 ^^^^
@@ -10,7 +10,7 @@ LL |     let _: baz!({ m::P });
    |                 ^      ^
 
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/macro_rules-braces.rs:69:17
+  --> $DIR/macro_rules-braces.rs:68:17
    |
 LL |     let _: baz!(10 + 7);
    |                 ^^^^^^
@@ -21,7 +21,7 @@ LL |     let _: baz!({ 10 + 7 });
    |                 ^        ^
 
 error: generic parameters may not be used in const operations
-  --> $DIR/macro_rules-braces.rs:37:20
+  --> $DIR/macro_rules-braces.rs:36:20
    |
 LL |     let _: foo!({{ N }});
    |                    ^ cannot perform const operation using `N`
@@ -30,7 +30,7 @@ LL |     let _: foo!({{ N }});
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/macro_rules-braces.rs:41:19
+  --> $DIR/macro_rules-braces.rs:40:19
    |
 LL |     let _: bar!({ N });
    |                   ^ cannot perform const operation using `N`
@@ -39,7 +39,7 @@ LL |     let _: bar!({ N });
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/macro_rules-braces.rs:46:20
+  --> $DIR/macro_rules-braces.rs:45:20
    |
 LL |     let _: baz!({{ N }});
    |                    ^ cannot perform const operation using `N`
@@ -48,7 +48,7 @@ LL |     let _: baz!({{ N }});
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/macro_rules-braces.rs:51:19
+  --> $DIR/macro_rules-braces.rs:50:19
    |
 LL |     let _: biz!({ N });
    |                   ^ cannot perform const operation using `N`
diff --git a/src/test/ui/const-generics/macro_rules-braces.rs b/src/test/ui/const-generics/macro_rules-braces.rs
index c6b43bec243..605a10880bb 100644
--- a/src/test/ui/const-generics/macro_rules-braces.rs
+++ b/src/test/ui/const-generics/macro_rules-braces.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, allow(incomplete_features))]
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 mod m {
     pub const P: usize = 0;
diff --git a/src/test/ui/const-generics/min-and-full-same-time.rs b/src/test/ui/const-generics/min-and-full-same-time.rs
deleted file mode 100644
index 2365adc3a86..00000000000
--- a/src/test/ui/const-generics/min-and-full-same-time.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#![feature(const_generics)]
-//~^ ERROR features `const_generics` and `min_const_generics` are incompatible
-#![allow(incomplete_features)]
-#![feature(min_const_generics)]
-
-
-fn main() {}
diff --git a/src/test/ui/const-generics/min-and-full-same-time.stderr b/src/test/ui/const-generics/min-and-full-same-time.stderr
deleted file mode 100644
index 907fec9bbe1..00000000000
--- a/src/test/ui/const-generics/min-and-full-same-time.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error: features `const_generics` and `min_const_generics` are incompatible, using them at the same time is not allowed
-  --> $DIR/min-and-full-same-time.rs:1:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-...
-LL | #![feature(min_const_generics)]
-   |            ^^^^^^^^^^^^^^^^^^
-   |
-   = help: remove one of these features
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/const-generics/min_const_generics/assoc_const.rs b/src/test/ui/const-generics/min_const_generics/assoc_const.rs
index fa75613d9dd..27e971b5b6f 100644
--- a/src/test/ui/const-generics/min_const_generics/assoc_const.rs
+++ b/src/test/ui/const-generics/min_const_generics/assoc_const.rs
@@ -1,6 +1,4 @@
 // check-pass
-#![feature(min_const_generics)]
-
 struct Foo<const N: usize>;
 
 impl<const N: usize> Foo<N> {
diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.rs b/src/test/ui/const-generics/min_const_generics/complex-expression.rs
index 686ce98fcdf..7840989cb08 100644
--- a/src/test/ui/const-generics/min_const_generics/complex-expression.rs
+++ b/src/test/ui/const-generics/min_const_generics/complex-expression.rs
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 use std::mem::size_of;
 
 fn test<const N: usize>() {}
diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr
index 2ea66279d46..17669244849 100644
--- a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr
+++ b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:11:38
+  --> $DIR/complex-expression.rs:9:38
    |
 LL | struct Break0<const N: usize>([u8; { N + 1 }]);
    |                                      ^ cannot perform const operation using `N`
@@ -8,7 +8,7 @@ LL | struct Break0<const N: usize>([u8; { N + 1 }]);
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:14:40
+  --> $DIR/complex-expression.rs:12:40
    |
 LL | struct Break1<const N: usize>([u8; { { N } }]);
    |                                        ^ cannot perform const operation using `N`
@@ -17,7 +17,7 @@ LL | struct Break1<const N: usize>([u8; { { N } }]);
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:18:17
+  --> $DIR/complex-expression.rs:16:17
    |
 LL |     let _: [u8; N + 1];
    |                 ^ cannot perform const operation using `N`
@@ -26,7 +26,7 @@ LL |     let _: [u8; N + 1];
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:23:17
+  --> $DIR/complex-expression.rs:21:17
    |
 LL |     let _ = [0; N + 1];
    |                 ^ cannot perform const operation using `N`
@@ -35,7 +35,7 @@ LL |     let _ = [0; N + 1];
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:27:45
+  --> $DIR/complex-expression.rs:25:45
    |
 LL | struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]);
    |                                             ^ cannot perform const operation using `T`
@@ -44,7 +44,7 @@ LL | struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]);
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:30:47
+  --> $DIR/complex-expression.rs:28:47
    |
 LL | struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]);
    |                                               ^ cannot perform const operation using `T`
@@ -53,7 +53,7 @@ LL | struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]);
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:34:32
+  --> $DIR/complex-expression.rs:32:32
    |
 LL |     let _: [u8; size_of::<*mut T>() + 1];
    |                                ^ cannot perform const operation using `T`
@@ -62,7 +62,7 @@ LL |     let _: [u8; size_of::<*mut T>() + 1];
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/complex-expression.rs:39:17
+  --> $DIR/complex-expression.rs:37:17
    |
 LL |     let _ = [0; size_of::<*mut T>() + 1];
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/min_const_generics/complex-types.rs b/src/test/ui/const-generics/min_const_generics/complex-types.rs
index 2aaf2c39875..057bd5af89e 100644
--- a/src/test/ui/const-generics/min_const_generics/complex-types.rs
+++ b/src/test/ui/const-generics/min_const_generics/complex-types.rs
@@ -1,4 +1,3 @@
-#![feature(min_const_generics)]
 #![feature(never_type)]
 
 struct Foo<const N: [u8; 0]>;
diff --git a/src/test/ui/const-generics/min_const_generics/complex-types.stderr b/src/test/ui/const-generics/min_const_generics/complex-types.stderr
index 5d473f1f876..20d498f9c93 100644
--- a/src/test/ui/const-generics/min_const_generics/complex-types.stderr
+++ b/src/test/ui/const-generics/min_const_generics/complex-types.stderr
@@ -1,5 +1,5 @@
 error: `[u8; 0]` is forbidden as the type of a const generic parameter
-  --> $DIR/complex-types.rs:4:21
+  --> $DIR/complex-types.rs:3:21
    |
 LL | struct Foo<const N: [u8; 0]>;
    |                     ^^^^^^^
@@ -8,7 +8,7 @@ LL | struct Foo<const N: [u8; 0]>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `()` is forbidden as the type of a const generic parameter
-  --> $DIR/complex-types.rs:7:21
+  --> $DIR/complex-types.rs:6:21
    |
 LL | struct Bar<const N: ()>;
    |                     ^^
@@ -17,7 +17,7 @@ LL | struct Bar<const N: ()>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `No` is forbidden as the type of a const generic parameter
-  --> $DIR/complex-types.rs:12:21
+  --> $DIR/complex-types.rs:11:21
    |
 LL | struct Fez<const N: No>;
    |                     ^^
@@ -26,7 +26,7 @@ LL | struct Fez<const N: No>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `&'static u8` is forbidden as the type of a const generic parameter
-  --> $DIR/complex-types.rs:15:21
+  --> $DIR/complex-types.rs:14:21
    |
 LL | struct Faz<const N: &'static u8>;
    |                     ^^^^^^^^^^^
@@ -35,7 +35,7 @@ LL | struct Faz<const N: &'static u8>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `!` is forbidden as the type of a const generic parameter
-  --> $DIR/complex-types.rs:18:21
+  --> $DIR/complex-types.rs:17:21
    |
 LL | struct Fiz<const N: !>;
    |                     ^
@@ -44,7 +44,7 @@ LL | struct Fiz<const N: !>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `()` is forbidden as the type of a const generic parameter
-  --> $DIR/complex-types.rs:21:19
+  --> $DIR/complex-types.rs:20:19
    |
 LL | enum Goo<const N: ()> { A, B }
    |                   ^^
@@ -53,7 +53,7 @@ LL | enum Goo<const N: ()> { A, B }
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `()` is forbidden as the type of a const generic parameter
-  --> $DIR/complex-types.rs:24:20
+  --> $DIR/complex-types.rs:23:20
    |
 LL | union Boo<const N: ()> { a: () }
    |                    ^^
diff --git a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs
index dd82be33a8e..71d13ca61c9 100644
--- a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs
+++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs
@@ -1,5 +1,4 @@
 // check-pass
-#![feature(min_const_generics)]
 #![allow(dead_code)]
 
 fn foo<T>() {
diff --git a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr
index 4d0cab012f9..f9f6660f6b8 100644
--- a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr
+++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr
@@ -1,5 +1,5 @@
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/const-evaluatable-unchecked.rs:6:9
+  --> $DIR/const-evaluatable-unchecked.rs:5:9
    |
 LL |     [0; std::mem::size_of::<*mut T>()];
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     [0; std::mem::size_of::<*mut T>()];
    = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>
 
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/const-evaluatable-unchecked.rs:17:21
+  --> $DIR/const-evaluatable-unchecked.rs:16:21
    |
 LL |         let _ = [0; Self::ASSOC];
    |                     ^^^^^^^^^^^
@@ -18,7 +18,7 @@ LL |         let _ = [0; Self::ASSOC];
    = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>
 
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/const-evaluatable-unchecked.rs:29:21
+  --> $DIR/const-evaluatable-unchecked.rs:28:21
    |
 LL |         let _ = [0; Self::ASSOC];
    |                     ^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs
index b9afd226430..fac3777cf21 100644
--- a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs
+++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 fn foo<const C: usize>() {}
 
 const BAR: usize = 42;
diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr
index 13742238a20..beea0acac60 100644
--- a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr
+++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.stderr
@@ -1,5 +1,5 @@
 error: comparison operators cannot be chained
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:8:8
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:6:8
    |
 LL |     foo<BAR + 3>();
    |        ^       ^
@@ -10,7 +10,7 @@ LL |     foo::<BAR + 3>();
    |        ^^
 
 error: comparison operators cannot be chained
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:11:8
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:9:8
    |
 LL |     foo<BAR + BAR>();
    |        ^         ^
@@ -21,7 +21,7 @@ LL |     foo::<BAR + BAR>();
    |        ^^
 
 error: comparison operators cannot be chained
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:14:8
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:12:8
    |
 LL |     foo<3 + 3>();
    |        ^     ^
@@ -32,7 +32,7 @@ LL |     foo::<3 + 3>();
    |        ^^
 
 error: comparison operators cannot be chained
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:17:8
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:15:8
    |
 LL |     foo<BAR - 3>();
    |        ^       ^
@@ -43,7 +43,7 @@ LL |     foo::<BAR - 3>();
    |        ^^
 
 error: comparison operators cannot be chained
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:20:8
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:18:8
    |
 LL |     foo<BAR - BAR>();
    |        ^         ^
@@ -54,7 +54,7 @@ LL |     foo::<BAR - BAR>();
    |        ^^
 
 error: comparison operators cannot be chained
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:23:8
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:21:8
    |
 LL |     foo<100 - BAR>();
    |        ^         ^
@@ -65,7 +65,7 @@ LL |     foo::<100 - BAR>();
    |        ^^
 
 error: comparison operators cannot be chained
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:26:8
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:24:8
    |
 LL |     foo<bar<i32>()>();
    |        ^   ^
@@ -76,13 +76,13 @@ LL |     foo::<bar<i32>()>();
    |        ^^
 
 error: expected one of `;` or `}`, found `>`
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:26:19
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:24:19
    |
 LL |     foo<bar<i32>()>();
    |                   ^ expected one of `;` or `}`
 
 error: comparison operators cannot be chained
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:30:8
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:28:8
    |
 LL |     foo<bar::<i32>()>();
    |        ^            ^
@@ -93,7 +93,7 @@ LL |     foo::<bar::<i32>()>();
    |        ^^
 
 error: comparison operators cannot be chained
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:33:8
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:31:8
    |
 LL |     foo<bar::<i32>() + BAR>();
    |        ^                  ^
@@ -104,7 +104,7 @@ LL |     foo::<bar::<i32>() + BAR>();
    |        ^^
 
 error: comparison operators cannot be chained
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:36:8
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:34:8
    |
 LL |     foo<bar::<i32>() - BAR>();
    |        ^                  ^
@@ -115,7 +115,7 @@ LL |     foo::<bar::<i32>() - BAR>();
    |        ^^
 
 error: comparison operators cannot be chained
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:39:8
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:37:8
    |
 LL |     foo<BAR - bar::<i32>()>();
    |        ^                  ^
@@ -126,7 +126,7 @@ LL |     foo::<BAR - bar::<i32>()>();
    |        ^^
 
 error: comparison operators cannot be chained
-  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:42:8
+  --> $DIR/const-expression-suggest-missing-braces-without-turbofish.rs:40:8
    |
 LL |     foo<BAR - bar::<i32>()>();
    |        ^                  ^
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 b96d5c561ff..f8b9d7adbfe 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
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 fn foo<const C: usize>() {}
 
 const BAR: usize = 42;
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 6adcf6a3e36..ad451fcf65d 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
@@ -1,5 +1,5 @@
 error: expected one of `,` or `>`, found `3`
-  --> $DIR/const-expression-suggest-missing-braces.rs:8:17
+  --> $DIR/const-expression-suggest-missing-braces.rs:6:17
    |
 LL |     foo::<BAR + 3>();
    |                 ^ expected one of `,` or `>`
@@ -10,7 +10,7 @@ LL |     foo::<{ BAR + 3 }>();
    |           ^         ^
 
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/const-expression-suggest-missing-braces.rs:20:11
+  --> $DIR/const-expression-suggest-missing-braces.rs:18:11
    |
 LL |     foo::<3 + 3>();
    |           ^^^^^
@@ -21,7 +21,7 @@ LL |     foo::<{ 3 + 3 }>();
    |           ^       ^
 
 error: expected one of `,` or `>`, found `-`
-  --> $DIR/const-expression-suggest-missing-braces.rs:23:15
+  --> $DIR/const-expression-suggest-missing-braces.rs:21:15
    |
 LL |     foo::<BAR - 3>();
    |               ^ expected one of `,` or `>`
@@ -32,7 +32,7 @@ LL |     foo::<{ BAR - 3 }>();
    |           ^         ^
 
 error: expected one of `,` or `>`, found `-`
-  --> $DIR/const-expression-suggest-missing-braces.rs:26:15
+  --> $DIR/const-expression-suggest-missing-braces.rs:24:15
    |
 LL |     foo::<BAR - BAR>();
    |               ^ expected one of `,` or `>`
@@ -43,7 +43,7 @@ LL |     foo::<{ BAR - BAR }>();
    |           ^           ^
 
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/const-expression-suggest-missing-braces.rs:29:11
+  --> $DIR/const-expression-suggest-missing-braces.rs:27:11
    |
 LL |     foo::<100 - BAR>();
    |           ^^^^^^^^^
@@ -54,7 +54,7 @@ LL |     foo::<{ 100 - BAR }>();
    |           ^           ^
 
 error: expected one of `,` or `>`, found `(`
-  --> $DIR/const-expression-suggest-missing-braces.rs:32:19
+  --> $DIR/const-expression-suggest-missing-braces.rs:30:19
    |
 LL |     foo::<bar<i32>()>();
    |                   ^ expected one of `,` or `>`
@@ -65,7 +65,7 @@ LL |     foo::<{ bar<i32>() }>();
    |           ^            ^
 
 error: expected one of `,` or `>`, found `(`
-  --> $DIR/const-expression-suggest-missing-braces.rs:35:21
+  --> $DIR/const-expression-suggest-missing-braces.rs:33:21
    |
 LL |     foo::<bar::<i32>()>();
    |                     ^ expected one of `,` or `>`
@@ -76,7 +76,7 @@ LL |     foo::<{ bar::<i32>() }>();
    |           ^              ^
 
 error: expected one of `,` or `>`, found `(`
-  --> $DIR/const-expression-suggest-missing-braces.rs:38:21
+  --> $DIR/const-expression-suggest-missing-braces.rs:36:21
    |
 LL |     foo::<bar::<i32>() + BAR>();
    |                     ^ expected one of `,` or `>`
@@ -87,7 +87,7 @@ LL |     foo::<{ bar::<i32>() + BAR }>();
    |           ^                    ^
 
 error: expected one of `,` or `>`, found `(`
-  --> $DIR/const-expression-suggest-missing-braces.rs:41:21
+  --> $DIR/const-expression-suggest-missing-braces.rs:39:21
    |
 LL |     foo::<bar::<i32>() - BAR>();
    |                     ^ expected one of `,` or `>`
@@ -98,7 +98,7 @@ LL |     foo::<{ bar::<i32>() - BAR }>();
    |           ^                    ^
 
 error: expected one of `,` or `>`, found `-`
-  --> $DIR/const-expression-suggest-missing-braces.rs:44:15
+  --> $DIR/const-expression-suggest-missing-braces.rs:42:15
    |
 LL |     foo::<BAR - bar::<i32>()>();
    |               ^ expected one of `,` or `>`
@@ -109,7 +109,7 @@ LL |     foo::<{ BAR - bar::<i32>() }>();
    |           ^                    ^
 
 error: expected one of `,` or `>`, found `-`
-  --> $DIR/const-expression-suggest-missing-braces.rs:47:15
+  --> $DIR/const-expression-suggest-missing-braces.rs:45:15
    |
 LL |     foo::<BAR - bar::<i32>()>();
    |               ^ expected one of `,` or `>`
@@ -120,19 +120,19 @@ LL |     foo::<{ BAR - bar::<i32>() }>();
    |           ^                    ^
 
 error[E0404]: expected trait, found constant `BAR`
-  --> $DIR/const-expression-suggest-missing-braces.rs:13:11
+  --> $DIR/const-expression-suggest-missing-braces.rs:11:11
    |
 LL |     foo::<BAR + BAR>();
    |           ^^^ not a trait
 
 error[E0404]: expected trait, found constant `BAR`
-  --> $DIR/const-expression-suggest-missing-braces.rs:13:17
+  --> $DIR/const-expression-suggest-missing-braces.rs:11:17
    |
 LL |     foo::<BAR + BAR>();
    |                 ^^^ not a trait
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/const-expression-suggest-missing-braces.rs:13:11
+  --> $DIR/const-expression-suggest-missing-braces.rs:11:11
    |
 LL |     foo::<BAR + BAR>();
    |           ^^^^^^^^^ help: use `dyn`: `dyn BAR + BAR`
@@ -140,7 +140,7 @@ LL |     foo::<BAR + BAR>();
    = note: `#[warn(bare_trait_objects)]` on by default
 
 error[E0747]: type provided when a constant was expected
-  --> $DIR/const-expression-suggest-missing-braces.rs:13:11
+  --> $DIR/const-expression-suggest-missing-braces.rs:11:11
    |
 LL |     foo::<BAR + BAR>();
    |           ^^^^^^^^^
diff --git a/src/test/ui/const-generics/min_const_generics/const_fn_in_generics.rs b/src/test/ui/const-generics/min_const_generics/const_fn_in_generics.rs
index 3370666cc5c..0c10af6c43f 100644
--- a/src/test/ui/const-generics/min_const_generics/const_fn_in_generics.rs
+++ b/src/test/ui/const-generics/min_const_generics/const_fn_in_generics.rs
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(min_const_generics)]
-
 const fn identity<const T: u32>() -> u32 { T }
 
 #[derive(Eq, PartialEq, Debug)]
diff --git a/src/test/ui/const-generics/min_const_generics/default_function_param.rs b/src/test/ui/const-generics/min_const_generics/default_function_param.rs
index 7e0c1c2ed9f..d7918a73ab8 100644
--- a/src/test/ui/const-generics/min_const_generics/default_function_param.rs
+++ b/src/test/ui/const-generics/min_const_generics/default_function_param.rs
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 fn foo<const SIZE: usize = 5>() {}
                       //~^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `=`
 
diff --git a/src/test/ui/const-generics/min_const_generics/default_function_param.stderr b/src/test/ui/const-generics/min_const_generics/default_function_param.stderr
index ed1a83b6a4d..8eb796d9bb7 100644
--- a/src/test/ui/const-generics/min_const_generics/default_function_param.stderr
+++ b/src/test/ui/const-generics/min_const_generics/default_function_param.stderr
@@ -1,5 +1,5 @@
 error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `=`
-  --> $DIR/default_function_param.rs:3:26
+  --> $DIR/default_function_param.rs:1:26
    |
 LL | fn foo<const SIZE: usize = 5>() {}
    |                          ^ expected one of 7 possible tokens
diff --git a/src/test/ui/const-generics/min_const_generics/default_trait_param.rs b/src/test/ui/const-generics/min_const_generics/default_trait_param.rs
index 322ddccbf18..c8003ad5d44 100644
--- a/src/test/ui/const-generics/min_const_generics/default_trait_param.rs
+++ b/src/test/ui/const-generics/min_const_generics/default_trait_param.rs
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 trait Foo<const KIND: bool = true> {}
                         //~^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `=`
 
diff --git a/src/test/ui/const-generics/min_const_generics/default_trait_param.stderr b/src/test/ui/const-generics/min_const_generics/default_trait_param.stderr
index 49c3ac86744..6d112ef1de0 100644
--- a/src/test/ui/const-generics/min_const_generics/default_trait_param.stderr
+++ b/src/test/ui/const-generics/min_const_generics/default_trait_param.stderr
@@ -1,5 +1,5 @@
 error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `=`
-  --> $DIR/default_trait_param.rs:3:28
+  --> $DIR/default_trait_param.rs:1:28
    |
 LL | trait Foo<const KIND: bool = true> {}
    |                            ^ expected one of 7 possible tokens
diff --git a/src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.rs b/src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.rs
deleted file mode 100644
index 423deae4600..00000000000
--- a/src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-fn test<const N: usize>() {}
-//~^ ERROR const generics are unstable
-
-fn main() {}
diff --git a/src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.stderr b/src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.stderr
deleted file mode 100644
index 7f82a960da2..00000000000
--- a/src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: const generics are unstable
-  --> $DIR/feature-gate-min_const_generics.rs:1:15
-   |
-LL | fn test<const N: usize>() {}
-   |               ^
-   |
-   = note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
-   = help: add `#![feature(min_const_generics)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs b/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs
index 02944e2bff2..881f8b98aad 100644
--- a/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs
+++ b/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 // This test checks that non-static lifetimes are prohibited under `min_const_generics`. It
 // currently emits an error with `min_const_generics`. This will ICE under `const_generics`.
 
diff --git a/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr b/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr
index cdfd491e395..5def54ca26d 100644
--- a/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr
+++ b/src/test/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr
@@ -1,5 +1,5 @@
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/forbid-non-static-lifetimes.rs:9:22
+  --> $DIR/forbid-non-static-lifetimes.rs:7:22
    |
 LL |     test::<{ let _: &'a (); 3 },>();
    |                      ^^
@@ -8,7 +8,7 @@ LL |     test::<{ let _: &'a (); 3 },>();
    = help: add `#![feature(const_generics)]` to the crate attributes to enable
 
 error[E0658]: a non-static lifetime is not allowed in a `const`
-  --> $DIR/forbid-non-static-lifetimes.rs:23:16
+  --> $DIR/forbid-non-static-lifetimes.rs:21:16
    |
 LL |     [(); (|_: &'a u8| (), 0).1];
    |                ^^
diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs b/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs
index e59b97922be..a120eee67ee 100644
--- a/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs
+++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.rs
@@ -1,4 +1,3 @@
-#![feature(min_const_generics)]
 use std::mem::transmute;
 
 fn get_flag<const FlagSet: bool, const ShortName: char>() -> Option<char> {
diff --git a/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr b/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr
index a3157c6b564..04f716fa733 100644
--- a/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr
+++ b/src/test/ui/const-generics/min_const_generics/invalid-patterns.stderr
@@ -1,29 +1,29 @@
 error[E0308]: mismatched types
-  --> $DIR/invalid-patterns.rs:29:21
+  --> $DIR/invalid-patterns.rs:28:21
    |
 LL |   get_flag::<false, 0xFF>();
    |                     ^^^^ expected `char`, found `u8`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-patterns.rs:31:14
+  --> $DIR/invalid-patterns.rs:30:14
    |
 LL |   get_flag::<7, 'c'>();
    |              ^ expected `bool`, found integer
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-patterns.rs:33:14
+  --> $DIR/invalid-patterns.rs:32:14
    |
 LL |   get_flag::<42, 0x5ad>();
    |              ^^ expected `bool`, found integer
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-patterns.rs:33:18
+  --> $DIR/invalid-patterns.rs:32:18
    |
 LL |   get_flag::<42, 0x5ad>();
    |                  ^^^^^ expected `char`, found `u8`
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/invalid-patterns.rs:38:21
+  --> $DIR/invalid-patterns.rs:37:21
    |
 LL |   get_flag::<false, { unsafe { char_raw.character } }>();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
@@ -31,7 +31,7 @@ LL |   get_flag::<false, { unsafe { char_raw.character } }>();
    = 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.
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/invalid-patterns.rs:40:14
+  --> $DIR/invalid-patterns.rs:39:14
    |
 LL |   get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x42, but expected a boolean
@@ -39,7 +39,7 @@ LL |   get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
    = 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.
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/invalid-patterns.rs:42:14
+  --> $DIR/invalid-patterns.rs:41:14
    |
 LL |   get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x42, but expected a boolean
@@ -47,7 +47,7 @@ LL |   get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character
    = 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.
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/invalid-patterns.rs:42:47
+  --> $DIR/invalid-patterns.rs:41:47
    |
 LL |   get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
    |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
diff --git a/src/test/ui/const-generics/min_const_generics/macro-fail.rs b/src/test/ui/const-generics/min_const_generics/macro-fail.rs
index 1bd0c46f55e..f83518fc9d4 100644
--- a/src/test/ui/const-generics/min_const_generics/macro-fail.rs
+++ b/src/test/ui/const-generics/min_const_generics/macro-fail.rs
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 struct Example<const N: usize>;
 
 macro_rules! external_macro {
diff --git a/src/test/ui/const-generics/min_const_generics/macro-fail.stderr b/src/test/ui/const-generics/min_const_generics/macro-fail.stderr
index a5dedf6fe20..22930a352a8 100644
--- a/src/test/ui/const-generics/min_const_generics/macro-fail.stderr
+++ b/src/test/ui/const-generics/min_const_generics/macro-fail.stderr
@@ -1,5 +1,5 @@
 error: expected type, found `{`
-  --> $DIR/macro-fail.rs:31:27
+  --> $DIR/macro-fail.rs:29:27
    |
 LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
    |                                 ----------------------
@@ -13,7 +13,7 @@ LL |       ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected type, found `{`
-  --> $DIR/macro-fail.rs:31:27
+  --> $DIR/macro-fail.rs:29:27
    |
 LL |   Example::<gimme_a_const!(marker)>
    |             ----------------------
@@ -27,7 +27,7 @@ LL |       ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: expected type, found `{`
-  --> $DIR/macro-fail.rs:6:10
+  --> $DIR/macro-fail.rs:4:10
    |
 LL |     () => {{
    |  __________^
@@ -46,7 +46,7 @@ LL |     let _fail = Example::<external_macro!()>;
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unexpected end of macro invocation
-  --> $DIR/macro-fail.rs:41:25
+  --> $DIR/macro-fail.rs:39:25
    |
 LL |     macro_rules! gimme_a_const {
    |     -------------------------- when calling this macro
@@ -55,25 +55,25 @@ LL |   let _fail = Example::<gimme_a_const!()>;
    |                         ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
 
 error[E0747]: type provided when a constant was expected
-  --> $DIR/macro-fail.rs:16:33
+  --> $DIR/macro-fail.rs:14:33
    |
 LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
    |                                 ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0747]: type provided when a constant was expected
-  --> $DIR/macro-fail.rs:18:13
+  --> $DIR/macro-fail.rs:16:13
    |
 LL |   Example::<gimme_a_const!(marker)>
    |             ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0747]: type provided when a constant was expected
-  --> $DIR/macro-fail.rs:38:25
+  --> $DIR/macro-fail.rs:36:25
    |
 LL |   let _fail = Example::<external_macro!()>;
    |                         ^^^^^^^^^^^^^^^^^
 
 error[E0747]: type provided when a constant was expected
-  --> $DIR/macro-fail.rs:41:25
+  --> $DIR/macro-fail.rs:39:25
    |
 LL |   let _fail = Example::<gimme_a_const!()>;
    |                         ^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/min_const_generics/macro.rs b/src/test/ui/const-generics/min_const_generics/macro.rs
index 575fbd33572..9b63f76987a 100644
--- a/src/test/ui/const-generics/min_const_generics/macro.rs
+++ b/src/test/ui/const-generics/min_const_generics/macro.rs
@@ -1,6 +1,4 @@
 // run-pass
-#![feature(min_const_generics)]
-
 struct Example<const N: usize>;
 
 macro_rules! external_macro {
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs
index 0973b373c12..9ef619365a0 100644
--- a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.rs
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 trait Foo {
     fn t1() -> [u8; std::mem::size_of::<Self>()]; //~ERROR generic parameters
 }
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
index 40c73f0b951..4fdfb5fbcb1 100644
--- a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/self-ty-in-const-1.rs:4:41
+  --> $DIR/self-ty-in-const-1.rs:2:41
    |
 LL |     fn t1() -> [u8; std::mem::size_of::<Self>()];
    |                                         ^^^^ cannot perform const operation using `Self`
@@ -8,13 +8,13 @@ LL |     fn t1() -> [u8; std::mem::size_of::<Self>()];
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic `Self` types are currently not permitted in anonymous constants
-  --> $DIR/self-ty-in-const-1.rs:14:41
+  --> $DIR/self-ty-in-const-1.rs:12:41
    |
 LL |     fn t3() -> [u8; std::mem::size_of::<Self>()] {}
    |                                         ^^^^
    |
 note: not a concrete type
-  --> $DIR/self-ty-in-const-1.rs:13:9
+  --> $DIR/self-ty-in-const-1.rs:11:9
    |
 LL | impl<T> Bar<T> {
    |         ^^^^^^
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs
index e7f80d50082..286ec2d2450 100644
--- a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.rs
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 struct Bar<T>(T);
 
 trait Baz {
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr
index 9ac6410a290..41546292c47 100644
--- a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-2.stderr
@@ -1,11 +1,11 @@
 error: generic `Self` types are currently not permitted in anonymous constants
-  --> $DIR/self-ty-in-const-2.rs:17:41
+  --> $DIR/self-ty-in-const-2.rs:15:41
    |
 LL |         let _: [u8; std::mem::size_of::<Self>()];
    |                                         ^^^^
    |
 note: not a concrete type
-  --> $DIR/self-ty-in-const-2.rs:15:17
+  --> $DIR/self-ty-in-const-2.rs:13:17
    |
 LL | impl<T> Baz for Bar<T> {
    |                 ^^^^^^
diff --git a/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs b/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs
index 0ef17109bed..7518dc59e59 100644
--- a/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs
+++ b/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 fn a<const X: &'static [u32]>() {}
 //~^ ERROR `&'static [u32]` is forbidden as the type of a const generic parameter
 
diff --git a/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.stderr b/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.stderr
index 6c39f6b4c1d..05939b05bba 100644
--- a/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.stderr
+++ b/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.stderr
@@ -1,5 +1,5 @@
 error: `&'static [u32]` is forbidden as the type of a const generic parameter
-  --> $DIR/static-reference-array-const-param.rs:3:15
+  --> $DIR/static-reference-array-const-param.rs:1:15
    |
 LL | fn a<const X: &'static [u32]>() {}
    |               ^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs b/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs
index dfa1ece2f36..560795a51f5 100644
--- a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs
+++ b/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs
@@ -1,5 +1,3 @@
-#![feature(min_const_generics)]
-
 struct Const<const P: &'static ()>;
 //~^ ERROR `&'static ()` is forbidden as the type of a const generic parameter
 
diff --git a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr b/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr
index 6b90329b72c..8724c7e33b1 100644
--- a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr
+++ b/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr
@@ -1,5 +1,5 @@
 error: `&'static ()` is forbidden as the type of a const generic parameter
-  --> $DIR/transmute-const-param-static-reference.rs:3:23
+  --> $DIR/transmute-const-param-static-reference.rs:1:23
    |
 LL | struct Const<const P: &'static ()>;
    |                       ^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/mut-ref-const-param-array.rs b/src/test/ui/const-generics/mut-ref-const-param-array.rs
index cf24cbe7e82..6a5739db3ae 100644
--- a/src/test/ui/const-generics/mut-ref-const-param-array.rs
+++ b/src/test/ui/const-generics/mut-ref-const-param-array.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 
 use std::ops::AddAssign;
diff --git a/src/test/ui/const-generics/nested-type.full.stderr b/src/test/ui/const-generics/nested-type.full.stderr
index 06ab9a6ff29..9d7ca36545c 100644
--- a/src/test/ui/const-generics/nested-type.full.stderr
+++ b/src/test/ui/const-generics/nested-type.full.stderr
@@ -1,5 +1,5 @@
 error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/nested-type.rs:16:5
+  --> $DIR/nested-type.rs:15:5
    |
 LL |     Foo::<17>::value()
    |     ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/nested-type.min.stderr b/src/test/ui/const-generics/nested-type.min.stderr
index 369e387508e..dabb3f245f5 100644
--- a/src/test/ui/const-generics/nested-type.min.stderr
+++ b/src/test/ui/const-generics/nested-type.min.stderr
@@ -1,5 +1,5 @@
 error: `[u8; _]` is forbidden as the type of a const generic parameter
-  --> $DIR/nested-type.rs:7:21
+  --> $DIR/nested-type.rs:6:21
    |
 LL |   struct Foo<const N: [u8; {
    |  _____________________^
@@ -15,7 +15,7 @@ LL | | }]>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/nested-type.rs:16:5
+  --> $DIR/nested-type.rs:15:5
    |
 LL |     Foo::<17>::value()
    |     ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/nested-type.rs b/src/test/ui/const-generics/nested-type.rs
index c5660983985..be8ebb7f401 100644
--- a/src/test/ui/const-generics/nested-type.rs
+++ b/src/test/ui/const-generics/nested-type.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo<const N: [u8; { //[min]~ ERROR `[u8; _]` is forbidden
     struct Foo<const N: usize>;
diff --git a/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr b/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr
index 8a1462c59e8..671f1103dcc 100644
--- a/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr
+++ b/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr
@@ -6,7 +6,6 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error: constant expression depends on a generic parameter
   --> $DIR/unify-fixpoint.rs:9:32
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-5.rs b/src/test/ui/const-generics/occurs-check/unused-substs-5.rs
new file mode 100644
index 00000000000..e5d487d89b9
--- /dev/null
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-5.rs
@@ -0,0 +1,20 @@
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+// `N + 1` also depends on `T` here even if it doesn't use it.
+fn q<T, const N: usize>(_: T) -> [u8; N + 1] {
+    todo!()
+}
+
+fn supplier<T>() -> T {
+    todo!()
+}
+
+fn catch_me<const N: usize>() where [u8; N + 1]: Default {
+    let mut x = supplier();
+    x = q::<_, N>(x); //~ ERROR mismatched types
+}
+
+fn main() {
+    catch_me::<3>();
+}
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr
new file mode 100644
index 00000000000..239569dab09
--- /dev/null
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/unused-substs-5.rs:15:9
+   |
+LL |     x = q::<_, N>(x);
+   |         ^^^^^^^^^^^^
+   |         |
+   |         cyclic type of infinite size
+   |         help: try using a conversion method: `q::<_, N>(x).to_vec()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr
index 3dccfd73dcc..debb272da36 100644
--- a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr
+++ b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.full.stderr
@@ -1,5 +1,5 @@
 error: type parameters with a default must be trailing
-  --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:12:12
+  --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:11:12
    |
 LL | struct Bar<T = [u8; N], const N: usize>(T);
    |            ^
@@ -7,13 +7,13 @@ LL | struct Bar<T = [u8; N], const N: usize>(T);
    = note: using type defaults and const parameters in the same parameter list is currently not permitted
 
 error: constant values inside of type parameter defaults must not depend on generic parameters
-  --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:7:44
+  --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:6:44
    |
 LL | struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
    |                                            ^ the anonymous constant must not depend on the parameter `T`
 
 error: constant values inside of type parameter defaults must not depend on generic parameters
-  --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:12:21
+  --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:11:21
    |
 LL | struct Bar<T = [u8; N], const N: usize>(T);
    |                     ^ the anonymous constant must not depend on the parameter `N`
diff --git a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr
index 9e0837a0a62..171efca1938 100644
--- a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr
+++ b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr
@@ -1,5 +1,5 @@
 error: type parameters with a default must be trailing
-  --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:12:12
+  --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:11:12
    |
 LL | struct Bar<T = [u8; N], const N: usize>(T);
    |            ^
@@ -7,7 +7,7 @@ LL | struct Bar<T = [u8; N], const N: usize>(T);
    = note: using type defaults and const parameters in the same parameter list is currently not permitted
 
 error: generic parameters may not be used in const operations
-  --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:7:44
+  --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:6:44
    |
 LL | struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
    |                                            ^ cannot perform const operation using `T`
@@ -16,7 +16,7 @@ LL | struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: constant values inside of type parameter defaults must not depend on generic parameters
-  --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:12:21
+  --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:11:21
    |
 LL | struct Bar<T = [u8; N], const N: usize>(T);
    |                     ^ the anonymous constant must not depend on the parameter `N`
diff --git a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs
index 51f0cff3f21..845c6111b59 100644
--- a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs
+++ b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
 //[full]~^ ERROR constant values inside of type parameter defaults
diff --git a/src/test/ui/const-generics/promotion.rs b/src/test/ui/const-generics/promotion.rs
index ac568bb75f0..ce9a1a0feb4 100644
--- a/src/test/ui/const-generics/promotion.rs
+++ b/src/test/ui/const-generics/promotion.rs
@@ -1,7 +1,5 @@
 // run-pass
 // tests that promoting expressions containing const parameters is allowed.
-#![feature(min_const_generics)]
-
 fn promotion_test<const N: usize>() -> &'static usize {
     &(3 + N)
 }
diff --git a/src/test/ui/const-generics/raw-ptr-const-param-deref.full.stderr b/src/test/ui/const-generics/raw-ptr-const-param-deref.full.stderr
index ffaab51f766..04bc46cb4ab 100644
--- a/src/test/ui/const-generics/raw-ptr-const-param-deref.full.stderr
+++ b/src/test/ui/const-generics/raw-ptr-const-param-deref.full.stderr
@@ -1,11 +1,11 @@
 error: using raw pointers as const generic parameters is forbidden
-  --> $DIR/raw-ptr-const-param-deref.rs:10:23
+  --> $DIR/raw-ptr-const-param-deref.rs:9:23
    |
 LL | struct Const<const P: *const u32>;
    |                       ^^^^^^^^^^
 
 error: using raw pointers as const generic parameters is forbidden
-  --> $DIR/raw-ptr-const-param-deref.rs:12:15
+  --> $DIR/raw-ptr-const-param-deref.rs:11:15
    |
 LL | impl<const P: *const u32> Const<P> {
    |               ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/raw-ptr-const-param-deref.min.stderr b/src/test/ui/const-generics/raw-ptr-const-param-deref.min.stderr
index ffaab51f766..04bc46cb4ab 100644
--- a/src/test/ui/const-generics/raw-ptr-const-param-deref.min.stderr
+++ b/src/test/ui/const-generics/raw-ptr-const-param-deref.min.stderr
@@ -1,11 +1,11 @@
 error: using raw pointers as const generic parameters is forbidden
-  --> $DIR/raw-ptr-const-param-deref.rs:10:23
+  --> $DIR/raw-ptr-const-param-deref.rs:9:23
    |
 LL | struct Const<const P: *const u32>;
    |                       ^^^^^^^^^^
 
 error: using raw pointers as const generic parameters is forbidden
-  --> $DIR/raw-ptr-const-param-deref.rs:12:15
+  --> $DIR/raw-ptr-const-param-deref.rs:11:15
    |
 LL | impl<const P: *const u32> Const<P> {
    |               ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/raw-ptr-const-param-deref.rs b/src/test/ui/const-generics/raw-ptr-const-param-deref.rs
index 20cc62ebc17..ca7d33c0eb9 100644
--- a/src/test/ui/const-generics/raw-ptr-const-param-deref.rs
+++ b/src/test/ui/const-generics/raw-ptr-const-param-deref.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 const A: u32 = 3;
 
diff --git a/src/test/ui/const-generics/raw-ptr-const-param.full.stderr b/src/test/ui/const-generics/raw-ptr-const-param.full.stderr
index d317aa0f585..310422aafcd 100644
--- a/src/test/ui/const-generics/raw-ptr-const-param.full.stderr
+++ b/src/test/ui/const-generics/raw-ptr-const-param.full.stderr
@@ -1,5 +1,5 @@
 error: using raw pointers as const generic parameters is forbidden
-  --> $DIR/raw-ptr-const-param.rs:7:23
+  --> $DIR/raw-ptr-const-param.rs:6:23
    |
 LL | struct Const<const P: *const u32>;
    |                       ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/raw-ptr-const-param.min.stderr b/src/test/ui/const-generics/raw-ptr-const-param.min.stderr
index d317aa0f585..310422aafcd 100644
--- a/src/test/ui/const-generics/raw-ptr-const-param.min.stderr
+++ b/src/test/ui/const-generics/raw-ptr-const-param.min.stderr
@@ -1,5 +1,5 @@
 error: using raw pointers as const generic parameters is forbidden
-  --> $DIR/raw-ptr-const-param.rs:7:23
+  --> $DIR/raw-ptr-const-param.rs:6:23
    |
 LL | struct Const<const P: *const u32>;
    |                       ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/raw-ptr-const-param.rs b/src/test/ui/const-generics/raw-ptr-const-param.rs
index 36e593aa210..a04c6d5e64e 100644
--- a/src/test/ui/const-generics/raw-ptr-const-param.rs
+++ b/src/test/ui/const-generics/raw-ptr-const-param.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Const<const P: *const u32>; //~ ERROR: using raw pointers as const generic parameters
 
diff --git a/src/test/ui/const-generics/slice-const-param-mismatch.full.stderr b/src/test/ui/const-generics/slice-const-param-mismatch.full.stderr
index d06da2ef063..80dd1be33c2 100644
--- a/src/test/ui/const-generics/slice-const-param-mismatch.full.stderr
+++ b/src/test/ui/const-generics/slice-const-param-mismatch.full.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/slice-const-param-mismatch.rs:15:35
+  --> $DIR/slice-const-param-mismatch.rs:14:35
    |
 LL |     let _: ConstString<"Hello"> = ConstString::<"World">;
    |            --------------------   ^^^^^^^^^^^^^^^^^^^^^^ expected `"Hello"`, found `"World"`
@@ -10,7 +10,7 @@ LL |     let _: ConstString<"Hello"> = ConstString::<"World">;
               found struct `ConstString<"World">`
 
 error[E0308]: mismatched types
-  --> $DIR/slice-const-param-mismatch.rs:17:33
+  --> $DIR/slice-const-param-mismatch.rs:16:33
    |
 LL |     let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">;
    |            -------------------   ^^^^^^^^^^^^^^^^^^^^^ expected `"ℇ㇈↦"`, found `"ℇ㇈↥"`
@@ -21,7 +21,7 @@ LL |     let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">;
               found struct `ConstString<"ℇ㇈↥">`
 
 error[E0308]: mismatched types
-  --> $DIR/slice-const-param-mismatch.rs:19:33
+  --> $DIR/slice-const-param-mismatch.rs:18:33
    |
 LL |     let _: ConstBytes<b"AAA"> = ConstBytes::<b"BBB">;
    |            ------------------   ^^^^^^^^^^^^^^^^^^^^ expected `b"AAA"`, found `b"BBB"`
diff --git a/src/test/ui/const-generics/slice-const-param-mismatch.min.stderr b/src/test/ui/const-generics/slice-const-param-mismatch.min.stderr
index 46997fed770..13d0b217ed2 100644
--- a/src/test/ui/const-generics/slice-const-param-mismatch.min.stderr
+++ b/src/test/ui/const-generics/slice-const-param-mismatch.min.stderr
@@ -1,5 +1,5 @@
 error: `&'static str` is forbidden as the type of a const generic parameter
-  --> $DIR/slice-const-param-mismatch.rs:8:29
+  --> $DIR/slice-const-param-mismatch.rs:7:29
    |
 LL | struct ConstString<const T: &'static str>;
    |                             ^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | struct ConstString<const T: &'static str>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `&'static [u8]` is forbidden as the type of a const generic parameter
-  --> $DIR/slice-const-param-mismatch.rs:10:28
+  --> $DIR/slice-const-param-mismatch.rs:9:28
    |
 LL | struct ConstBytes<const T: &'static [u8]>;
    |                            ^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/slice-const-param-mismatch.rs b/src/test/ui/const-generics/slice-const-param-mismatch.rs
index 0f8ae9bac4a..f020e2bf66f 100644
--- a/src/test/ui/const-generics/slice-const-param-mismatch.rs
+++ b/src/test/ui/const-generics/slice-const-param-mismatch.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 
 struct ConstString<const T: &'static str>;
diff --git a/src/test/ui/const-generics/slice-const-param.min.stderr b/src/test/ui/const-generics/slice-const-param.min.stderr
index 7a9f65233e7..821c6e3995a 100644
--- a/src/test/ui/const-generics/slice-const-param.min.stderr
+++ b/src/test/ui/const-generics/slice-const-param.min.stderr
@@ -1,5 +1,5 @@
 error: `&'static str` is forbidden as the type of a const generic parameter
-  --> $DIR/slice-const-param.rs:8:40
+  --> $DIR/slice-const-param.rs:7:40
    |
 LL | pub fn function_with_str<const STRING: &'static str>() -> &'static str {
    |                                        ^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | pub fn function_with_str<const STRING: &'static str>() -> &'static str {
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `&'static [u8]` is forbidden as the type of a const generic parameter
-  --> $DIR/slice-const-param.rs:13:41
+  --> $DIR/slice-const-param.rs:12:41
    |
 LL | pub fn function_with_bytes<const BYTES: &'static [u8]>() -> &'static [u8] {
    |                                         ^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/slice-const-param.rs b/src/test/ui/const-generics/slice-const-param.rs
index f76e948c4af..bf1bf8af922 100644
--- a/src/test/ui/const-generics/slice-const-param.rs
+++ b/src/test/ui/const-generics/slice-const-param.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub fn function_with_str<const STRING: &'static str>() -> &'static str {
     //[min]~^ ERROR `&'static str` is forbidden
diff --git a/src/test/ui/const-generics/std/const-generics-range.min.stderr b/src/test/ui/const-generics/std/const-generics-range.min.stderr
index 9274ccd2b92..d7d2a8447e9 100644
--- a/src/test/ui/const-generics/std/const-generics-range.min.stderr
+++ b/src/test/ui/const-generics/std/const-generics-range.min.stderr
@@ -1,5 +1,5 @@
 error: `std::ops::Range<usize>` is forbidden as the type of a const generic parameter
-  --> $DIR/const-generics-range.rs:8:24
+  --> $DIR/const-generics-range.rs:7:24
    |
 LL | struct _Range<const R: std::ops::Range<usize>>;
    |                        ^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | struct _Range<const R: std::ops::Range<usize>>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `RangeFrom<usize>` is forbidden as the type of a const generic parameter
-  --> $DIR/const-generics-range.rs:13:28
+  --> $DIR/const-generics-range.rs:12:28
    |
 LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `RangeFull` is forbidden as the type of a const generic parameter
-  --> $DIR/const-generics-range.rs:18:28
+  --> $DIR/const-generics-range.rs:17:28
    |
 LL | struct _RangeFull<const R: std::ops::RangeFull>;
    |                            ^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | struct _RangeFull<const R: std::ops::RangeFull>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `RangeInclusive<usize>` is forbidden as the type of a const generic parameter
-  --> $DIR/const-generics-range.rs:24:33
+  --> $DIR/const-generics-range.rs:23:33
    |
 LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -35,7 +35,7 @@ LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `RangeTo<usize>` is forbidden as the type of a const generic parameter
-  --> $DIR/const-generics-range.rs:29:26
+  --> $DIR/const-generics-range.rs:28:26
    |
 LL | struct _RangeTo<const R: std::ops::RangeTo<usize>>;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -44,7 +44,7 @@ LL | struct _RangeTo<const R: std::ops::RangeTo<usize>>;
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `RangeToInclusive<usize>` is forbidden as the type of a const generic parameter
-  --> $DIR/const-generics-range.rs:34:35
+  --> $DIR/const-generics-range.rs:33:35
    |
 LL | struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>;
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/std/const-generics-range.rs b/src/test/ui/const-generics/std/const-generics-range.rs
index 136ac352890..deaab830e91 100644
--- a/src/test/ui/const-generics/std/const-generics-range.rs
+++ b/src/test/ui/const-generics/std/const-generics-range.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 // `Range` should be usable within const generics:
 struct _Range<const R: std::ops::Range<usize>>;
diff --git a/src/test/ui/const-generics/struct-with-invalid-const-param.full.stderr b/src/test/ui/const-generics/struct-with-invalid-const-param.full.stderr
index e73a297c878..db998033c0a 100644
--- a/src/test/ui/const-generics/struct-with-invalid-const-param.full.stderr
+++ b/src/test/ui/const-generics/struct-with-invalid-const-param.full.stderr
@@ -1,5 +1,5 @@
 error[E0573]: expected type, found const parameter `C`
-  --> $DIR/struct-with-invalid-const-param.rs:8:23
+  --> $DIR/struct-with-invalid-const-param.rs:7:23
    |
 LL | struct S<const C: u8>(C);
    |                       ^ not a type
diff --git a/src/test/ui/const-generics/struct-with-invalid-const-param.min.stderr b/src/test/ui/const-generics/struct-with-invalid-const-param.min.stderr
index e73a297c878..db998033c0a 100644
--- a/src/test/ui/const-generics/struct-with-invalid-const-param.min.stderr
+++ b/src/test/ui/const-generics/struct-with-invalid-const-param.min.stderr
@@ -1,5 +1,5 @@
 error[E0573]: expected type, found const parameter `C`
-  --> $DIR/struct-with-invalid-const-param.rs:8:23
+  --> $DIR/struct-with-invalid-const-param.rs:7:23
    |
 LL | struct S<const C: u8>(C);
    |                       ^ not a type
diff --git a/src/test/ui/const-generics/struct-with-invalid-const-param.rs b/src/test/ui/const-generics/struct-with-invalid-const-param.rs
index f0122ace3ae..32970ccaa5d 100644
--- a/src/test/ui/const-generics/struct-with-invalid-const-param.rs
+++ b/src/test/ui/const-generics/struct-with-invalid-const-param.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct S<const C: u8>(C); //~ ERROR expected type, found const parameter
 
diff --git a/src/test/ui/const-generics/trait-const-args.rs b/src/test/ui/const-generics/trait-const-args.rs
index b66d79845f9..30d05c708e1 100644
--- a/src/test/ui/const-generics/trait-const-args.rs
+++ b/src/test/ui/const-generics/trait-const-args.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Const<const N: usize>;
 trait Foo<const N: usize> {}
diff --git a/src/test/ui/const-generics/transparent-maybeunit-array-wrapper.rs b/src/test/ui/const-generics/transparent-maybeunit-array-wrapper.rs
index e041e9709d0..bf855d4dcaa 100644
--- a/src/test/ui/const-generics/transparent-maybeunit-array-wrapper.rs
+++ b/src/test/ui/const-generics/transparent-maybeunit-array-wrapper.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 use std::mem::MaybeUninit;
 
diff --git a/src/test/ui/const-generics/type-after-const-ok.min.stderr b/src/test/ui/const-generics/type-after-const-ok.min.stderr
index 67a44d2c5b4..ad38754c741 100644
--- a/src/test/ui/const-generics/type-after-const-ok.min.stderr
+++ b/src/test/ui/const-generics/type-after-const-ok.min.stderr
@@ -1,5 +1,5 @@
 error: type parameters must be declared prior to const parameters
-  --> $DIR/type-after-const-ok.rs:9:26
+  --> $DIR/type-after-const-ok.rs:8:26
    |
 LL | struct A<const N: usize, T>(T);
    |         -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
diff --git a/src/test/ui/const-generics/type-after-const-ok.rs b/src/test/ui/const-generics/type-after-const-ok.rs
index 69227cdf19c..920c067dc1a 100644
--- a/src/test/ui/const-generics/type-after-const-ok.rs
+++ b/src/test/ui/const-generics/type-after-const-ok.rs
@@ -3,7 +3,6 @@
 // Verifies that having generic parameters after constants is permitted
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 #[allow(dead_code)]
 struct A<const N: usize, T>(T);
diff --git a/src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs b/src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs
index aa85376bf0d..cd9c3ae7bbc 100644
--- a/src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs
+++ b/src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs
@@ -1,6 +1,5 @@
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub struct Struct<const N: usize>(());
 
diff --git a/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs b/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs
index 3ccdd472613..4997d493bbb 100644
--- a/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs
+++ b/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs
@@ -1,7 +1,6 @@
 // run-pass
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
-#![cfg_attr(min, feature(min_const_generics))]
 #![allow(incomplete_features)]
 
 struct Foo;
diff --git a/src/test/ui/const-generics/type-dependent/issue-61936.rs b/src/test/ui/const-generics/type-dependent/issue-61936.rs
index f3b19109a7c..417fe2501ae 100644
--- a/src/test/ui/const-generics/type-dependent/issue-61936.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-61936.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait SliceExt<T: Clone> {
     fn array_windows_example<'a, const N: usize>(&'a self) -> ArrayWindowsExample<'a, T, N>;
diff --git a/src/test/ui/const-generics/type-dependent/issue-63695.rs b/src/test/ui/const-generics/type-dependent/issue-63695.rs
index 465b66b09ce..2ece25bb41b 100644
--- a/src/test/ui/const-generics/type-dependent/issue-63695.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-63695.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait T {
     fn test<const A: i32>(&self) -> i32 { A }
diff --git a/src/test/ui/const-generics/type-dependent/issue-67144-1.rs b/src/test/ui/const-generics/type-dependent/issue-67144-1.rs
index 3d4910e9e4b..4a2c303095e 100644
--- a/src/test/ui/const-generics/type-dependent/issue-67144-1.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-67144-1.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct X;
 
diff --git a/src/test/ui/const-generics/type-dependent/issue-67144-2.rs b/src/test/ui/const-generics/type-dependent/issue-67144-2.rs
index 0868d309b33..a1163fca8d4 100644
--- a/src/test/ui/const-generics/type-dependent/issue-67144-2.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-67144-2.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct A<const N: usize>;
 
diff --git a/src/test/ui/const-generics/type-dependent/issue-69816.rs b/src/test/ui/const-generics/type-dependent/issue-69816.rs
index 4a374dc1db6..75ddd839f66 100644
--- a/src/test/ui/const-generics/type-dependent/issue-69816.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-69816.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait IterExt: Sized + Iterator {
     fn default_for_size<const N: usize>(self) -> [Self::Item; N]
diff --git a/src/test/ui/const-generics/type-dependent/issue-70217.rs b/src/test/ui/const-generics/type-dependent/issue-70217.rs
index ba5a42e47e9..b3585d5fc10 100644
--- a/src/test/ui/const-generics/type-dependent/issue-70217.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-70217.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Struct<const N: usize>;
 
diff --git a/src/test/ui/const-generics/type-dependent/issue-70507.rs b/src/test/ui/const-generics/type-dependent/issue-70507.rs
index 234c09e04ae..df7c277f605 100644
--- a/src/test/ui/const-generics/type-dependent/issue-70507.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-70507.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait ConstChunksExactTrait<T> {
     fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, {N}>;
diff --git a/src/test/ui/const-generics/type-dependent/issue-70586.rs b/src/test/ui/const-generics/type-dependent/issue-70586.rs
index fd52373cee2..5fb571f2394 100644
--- a/src/test/ui/const-generics/type-dependent/issue-70586.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-70586.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 use std::marker::PhantomData;
 
diff --git a/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr b/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr
index 8f240f0d930..92f5d815a0f 100644
--- a/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr
+++ b/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr
@@ -1,5 +1,5 @@
 error: `&'static str` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-71348.rs:11:24
+  --> $DIR/issue-71348.rs:10:24
    |
 LL | trait Get<'a, const N: &'static str> {
    |                        ^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | trait Get<'a, const N: &'static str> {
    = help: more complex types are supported with `#[feature(const_generics)]`
 
 error: `&'static str` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-71348.rs:19:25
+  --> $DIR/issue-71348.rs:18:25
    |
 LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target
    |                         ^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/type-dependent/issue-71348.rs b/src/test/ui/const-generics/type-dependent/issue-71348.rs
index 772e179746d..33735ef87c5 100644
--- a/src/test/ui/const-generics/type-dependent/issue-71348.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-71348.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Foo {
     i: i32,
diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.full.stderr b/src/test/ui/const-generics/type-dependent/issue-71382.full.stderr
index da1d3270b7c..8ac9bab6320 100644
--- a/src/test/ui/const-generics/type-dependent/issue-71382.full.stderr
+++ b/src/test/ui/const-generics/type-dependent/issue-71382.full.stderr
@@ -1,5 +1,5 @@
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71382.rs:17:23
+  --> $DIR/issue-71382.rs:16:23
    |
 LL |     fn test<const FN: fn() -> u8>(&self) -> u8 {
    |                       ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.min.stderr b/src/test/ui/const-generics/type-dependent/issue-71382.min.stderr
index da1d3270b7c..8ac9bab6320 100644
--- a/src/test/ui/const-generics/type-dependent/issue-71382.min.stderr
+++ b/src/test/ui/const-generics/type-dependent/issue-71382.min.stderr
@@ -1,5 +1,5 @@
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71382.rs:17:23
+  --> $DIR/issue-71382.rs:16:23
    |
 LL |     fn test<const FN: fn() -> u8>(&self) -> u8 {
    |                       ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.rs b/src/test/ui/const-generics/type-dependent/issue-71382.rs
index 497fd1381de..b3677613dbc 100644
--- a/src/test/ui/const-generics/type-dependent/issue-71382.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-71382.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct Test;
 
diff --git a/src/test/ui/const-generics/type-dependent/issue-71805.rs b/src/test/ui/const-generics/type-dependent/issue-71805.rs
index 2aaf12cea4f..3701e14eadc 100644
--- a/src/test/ui/const-generics/type-dependent/issue-71805.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-71805.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 use std::mem::MaybeUninit;
 
diff --git a/src/test/ui/const-generics/type-dependent/issue-73730.rs b/src/test/ui/const-generics/type-dependent/issue-73730.rs
index 3e53190ee48..5d7dcb9c458 100644
--- a/src/test/ui/const-generics/type-dependent/issue-73730.rs
+++ b/src/test/ui/const-generics/type-dependent/issue-73730.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait Foo<'a, A>: Iterator<Item=A> {
     fn bar<const N: usize>(&mut self) -> *const [A; N];
diff --git a/src/test/ui/const-generics/type-dependent/non-local.rs b/src/test/ui/const-generics/type-dependent/non-local.rs
index 747664a0962..9e4afba3114 100644
--- a/src/test/ui/const-generics/type-dependent/non-local.rs
+++ b/src/test/ui/const-generics/type-dependent/non-local.rs
@@ -3,7 +3,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 extern crate type_dependent_lib;
 
diff --git a/src/test/ui/const-generics/type-dependent/qpath.rs b/src/test/ui/const-generics/type-dependent/qpath.rs
index ec23ff1d221..b61e970cfb3 100644
--- a/src/test/ui/const-generics/type-dependent/qpath.rs
+++ b/src/test/ui/const-generics/type-dependent/qpath.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct A;
 impl A {
diff --git a/src/test/ui/const-generics/type-dependent/simple.rs b/src/test/ui/const-generics/type-dependent/simple.rs
index 70af6550923..a4776a43b21 100644
--- a/src/test/ui/const-generics/type-dependent/simple.rs
+++ b/src/test/ui/const-generics/type-dependent/simple.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct R;
 
diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr b/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr
index a530e63449d..b942c397a8d 100644
--- a/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr
+++ b/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/type-mismatch.rs:12:27
+  --> $DIR/type-mismatch.rs:11:27
    |
 LL |     assert_eq!(R.method::<1u16>(), 1);
    |                           ^^^^ expected `u8`, found `u16`
diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr b/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr
index a530e63449d..b942c397a8d 100644
--- a/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr
+++ b/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/type-mismatch.rs:12:27
+  --> $DIR/type-mismatch.rs:11:27
    |
 LL |     assert_eq!(R.method::<1u16>(), 1);
    |                           ^^^^ expected `u8`, found `u16`
diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.rs b/src/test/ui/const-generics/type-dependent/type-mismatch.rs
index 67d80973f03..7fba1afe918 100644
--- a/src/test/ui/const-generics/type-dependent/type-mismatch.rs
+++ b/src/test/ui/const-generics/type-dependent/type-mismatch.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct R;
 
diff --git a/src/test/ui/const-generics/type_of_anon_const.rs b/src/test/ui/const-generics/type_of_anon_const.rs
index f424fd03341..9a2e9f09319 100644
--- a/src/test/ui/const-generics/type_of_anon_const.rs
+++ b/src/test/ui/const-generics/type_of_anon_const.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait T<const A: usize> {
     fn l<const N: bool>() -> usize;
diff --git a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr
index 265e9ee618b..480ecdb3873 100644
--- a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr
+++ b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/types-mismatch-const-args.rs:15:41
+  --> $DIR/types-mismatch-const-args.rs:14:41
    |
 LL |     let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data: PhantomData };
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2_u32`, found `4_u32`
@@ -8,7 +8,7 @@ LL |     let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data
               found type `4_u32`
 
 error[E0308]: mismatched types
-  --> $DIR/types-mismatch-const-args.rs:17:41
+  --> $DIR/types-mismatch-const-args.rs:16:41
    |
 LL |     let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData };
    |            --------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u16`, found `u32`
diff --git a/src/test/ui/const-generics/types-mismatch-const-args.min.stderr b/src/test/ui/const-generics/types-mismatch-const-args.min.stderr
index 27277f0c0be..c19c8db737a 100644
--- a/src/test/ui/const-generics/types-mismatch-const-args.min.stderr
+++ b/src/test/ui/const-generics/types-mismatch-const-args.min.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/types-mismatch-const-args.rs:15:41
+  --> $DIR/types-mismatch-const-args.rs:14:41
    |
 LL |     let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data: PhantomData };
    |            --------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2_u32`, found `4_u32`
@@ -10,7 +10,7 @@ LL |     let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data
               found struct `A<'_, _, 4_u32, _>`
 
 error[E0308]: mismatched types
-  --> $DIR/types-mismatch-const-args.rs:17:41
+  --> $DIR/types-mismatch-const-args.rs:16:41
    |
 LL |     let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData };
    |            --------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u16`, found `u32`
diff --git a/src/test/ui/const-generics/types-mismatch-const-args.rs b/src/test/ui/const-generics/types-mismatch-const-args.rs
index 34b85304cc4..14cef083d83 100644
--- a/src/test/ui/const-generics/types-mismatch-const-args.rs
+++ b/src/test/ui/const-generics/types-mismatch-const-args.rs
@@ -1,7 +1,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 // tests the diagnostic output of type mismatches for types that have const generics arguments.
 
diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs
index 45afbdc9ab1..9592f266230 100644
--- a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs
+++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 use std::fmt;
 
diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs
index 65ae05e1198..4bab2bb5a77 100644
--- a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs
+++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 use std::fmt;
 
diff --git a/src/test/ui/const-generics/unknown_adt.full.stderr b/src/test/ui/const-generics/unknown_adt.full.stderr
index 94f3165eaec..b8b2e90aa66 100644
--- a/src/test/ui/const-generics/unknown_adt.full.stderr
+++ b/src/test/ui/const-generics/unknown_adt.full.stderr
@@ -1,5 +1,5 @@
 error[E0412]: cannot find type `UnknownStruct` in this scope
-  --> $DIR/unknown_adt.rs:8:12
+  --> $DIR/unknown_adt.rs:7:12
    |
 LL |     let _: UnknownStruct<7>;
    |            ^^^^^^^^^^^^^ not found in this scope
diff --git a/src/test/ui/const-generics/unknown_adt.min.stderr b/src/test/ui/const-generics/unknown_adt.min.stderr
index 94f3165eaec..b8b2e90aa66 100644
--- a/src/test/ui/const-generics/unknown_adt.min.stderr
+++ b/src/test/ui/const-generics/unknown_adt.min.stderr
@@ -1,5 +1,5 @@
 error[E0412]: cannot find type `UnknownStruct` in this scope
-  --> $DIR/unknown_adt.rs:8:12
+  --> $DIR/unknown_adt.rs:7:12
    |
 LL |     let _: UnknownStruct<7>;
    |            ^^^^^^^^^^^^^ not found in this scope
diff --git a/src/test/ui/const-generics/unknown_adt.rs b/src/test/ui/const-generics/unknown_adt.rs
index c6131402aeb..977f90aad11 100644
--- a/src/test/ui/const-generics/unknown_adt.rs
+++ b/src/test/ui/const-generics/unknown_adt.rs
@@ -2,7 +2,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 fn main() {
     let _: UnknownStruct<7>;
diff --git a/src/test/ui/const-generics/unused-const-param.rs b/src/test/ui/const-generics/unused-const-param.rs
index 3c305167b4b..2918e399dc8 100644
--- a/src/test/ui/const-generics/unused-const-param.rs
+++ b/src/test/ui/const-generics/unused-const-param.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 struct A<const N: usize>; // ok
 
diff --git a/src/test/ui/const-generics/unused_braces.full.fixed b/src/test/ui/const-generics/unused_braces.full.fixed
index 1b075ade16a..46d57e0dcfc 100644
--- a/src/test/ui/const-generics/unused_braces.full.fixed
+++ b/src/test/ui/const-generics/unused_braces.full.fixed
@@ -4,7 +4,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 #![warn(unused_braces)]
 
 
diff --git a/src/test/ui/const-generics/unused_braces.full.stderr b/src/test/ui/const-generics/unused_braces.full.stderr
index 1752779a60a..8899139aa6b 100644
--- a/src/test/ui/const-generics/unused_braces.full.stderr
+++ b/src/test/ui/const-generics/unused_braces.full.stderr
@@ -1,11 +1,11 @@
 warning: unnecessary braces around const expression
-  --> $DIR/unused_braces.rs:15:14
+  --> $DIR/unused_braces.rs:14:14
    |
 LL |     let _: A<{ 7 }>;
    |              ^^^^^ help: remove these braces
    |
 note: the lint level is defined here
-  --> $DIR/unused_braces.rs:8:9
+  --> $DIR/unused_braces.rs:7:9
    |
 LL | #![warn(unused_braces)]
    |         ^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/unused_braces.min.fixed b/src/test/ui/const-generics/unused_braces.min.fixed
index 1b075ade16a..46d57e0dcfc 100644
--- a/src/test/ui/const-generics/unused_braces.min.fixed
+++ b/src/test/ui/const-generics/unused_braces.min.fixed
@@ -4,7 +4,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 #![warn(unused_braces)]
 
 
diff --git a/src/test/ui/const-generics/unused_braces.min.stderr b/src/test/ui/const-generics/unused_braces.min.stderr
index 1752779a60a..8899139aa6b 100644
--- a/src/test/ui/const-generics/unused_braces.min.stderr
+++ b/src/test/ui/const-generics/unused_braces.min.stderr
@@ -1,11 +1,11 @@
 warning: unnecessary braces around const expression
-  --> $DIR/unused_braces.rs:15:14
+  --> $DIR/unused_braces.rs:14:14
    |
 LL |     let _: A<{ 7 }>;
    |              ^^^^^ help: remove these braces
    |
 note: the lint level is defined here
-  --> $DIR/unused_braces.rs:8:9
+  --> $DIR/unused_braces.rs:7:9
    |
 LL | #![warn(unused_braces)]
    |         ^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/unused_braces.rs b/src/test/ui/const-generics/unused_braces.rs
index 31c4caf7ab8..0348bbacaab 100644
--- a/src/test/ui/const-generics/unused_braces.rs
+++ b/src/test/ui/const-generics/unused_braces.rs
@@ -4,7 +4,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 #![warn(unused_braces)]
 
 
diff --git a/src/test/ui/const-generics/wf-misc.full.stderr b/src/test/ui/const-generics/wf-misc.full.stderr
index 4af48fa1590..dfb593a9507 100644
--- a/src/test/ui/const-generics/wf-misc.full.stderr
+++ b/src/test/ui/const-generics/wf-misc.full.stderr
@@ -1,5 +1,5 @@
 error: constant expression depends on a generic parameter
-  --> $DIR/wf-misc.rs:9:12
+  --> $DIR/wf-misc.rs:8:12
    |
 LL |     let _: [u8; N + 1];
    |            ^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL |     let _: [u8; N + 1];
    = note: this may fail depending on what value the parameter takes
 
 error: constant expression depends on a generic parameter
-  --> $DIR/wf-misc.rs:17:12
+  --> $DIR/wf-misc.rs:16:12
    |
 LL |     let _: Const::<{N + 1}>;
    |            ^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/wf-misc.min.stderr b/src/test/ui/const-generics/wf-misc.min.stderr
index 99142cb6ce7..9967a2218f6 100644
--- a/src/test/ui/const-generics/wf-misc.min.stderr
+++ b/src/test/ui/const-generics/wf-misc.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/wf-misc.rs:9:17
+  --> $DIR/wf-misc.rs:8:17
    |
 LL |     let _: [u8; N + 1];
    |                 ^ cannot perform const operation using `N`
@@ -8,7 +8,7 @@ LL |     let _: [u8; N + 1];
    = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/wf-misc.rs:17:21
+  --> $DIR/wf-misc.rs:16:21
    |
 LL |     let _: Const::<{N + 1}>;
    |                     ^ cannot perform const operation using `N`
diff --git a/src/test/ui/const-generics/wf-misc.rs b/src/test/ui/const-generics/wf-misc.rs
index 103c580f28f..8a5b6ddfe26 100644
--- a/src/test/ui/const-generics/wf-misc.rs
+++ b/src/test/ui/const-generics/wf-misc.rs
@@ -3,7 +3,6 @@
 
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 pub fn arr_len<const N: usize>() {
     let _: [u8; N + 1];
diff --git a/src/test/ui/const-generics/where-clauses.rs b/src/test/ui/const-generics/where-clauses.rs
index cdcaf250942..dc09cad3180 100644
--- a/src/test/ui/const-generics/where-clauses.rs
+++ b/src/test/ui/const-generics/where-clauses.rs
@@ -2,7 +2,6 @@
 // revisions: full min
 #![cfg_attr(full, feature(const_generics))]
 #![cfg_attr(full, allow(incomplete_features))]
-#![cfg_attr(min, feature(min_const_generics))]
 
 trait Bar<const N: usize> { fn bar() {} }
 trait Foo<const N: usize>: Bar<N> {}
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..183aa9e5122
--- /dev/null
+++ b/src/test/ui/const-ptr/out_of_bounds_read.rs
@@ -0,0 +1,16 @@
+// error-pattern: any use of this value will cause an error
+
+#![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..ca65a079947
--- /dev/null
+++ b/src/test/ui/const-ptr/out_of_bounds_read.stderr
@@ -0,0 +1,54 @@
+error: any use of this value will cause an error
+  --> $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
+   |              inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |              inside `_READ` at $DIR/out_of_bounds_read.rs:13:33
+   | 
+  ::: $DIR/out_of_bounds_read.rs:13:5
+   |
+LL |     const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
+   |     ------------------------------------------------------
+   |
+   = note: `#[deny(const_err)]` on by default
+
+error: any use of this value will cause an error
+  --> $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
+   |              inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |              inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+   |              inside `_CONST_READ` at $DIR/out_of_bounds_read.rs:14:39
+   | 
+  ::: $DIR/out_of_bounds_read.rs:14:5
+   |
+LL |     const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
+   |     --------------------------------------------------------
+
+error: any use of this value will cause an error
+  --> $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
+   |              inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+   |              inside `ptr::mut_ptr::<impl *mut u32>::read` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+   |              inside `_MUT_READ` at $DIR/out_of_bounds_read.rs:15:37
+   | 
+  ::: $DIR/out_of_bounds_read.rs:15:5
+   |
+LL |     const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
+   |     --------------------------------------------------------------------
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/consts/assume-type-intrinsics.rs b/src/test/ui/consts/assume-type-intrinsics.rs
new file mode 100644
index 00000000000..77370e1ccc5
--- /dev/null
+++ b/src/test/ui/consts/assume-type-intrinsics.rs
@@ -0,0 +1,13 @@
+// error-pattern: any use of this value will cause an error
+
+#![feature(never_type)]
+#![feature(const_maybe_uninit_assume_init)]
+
+#[allow(invalid_value)]
+fn main() {
+    use std::mem::MaybeUninit;
+
+    const _BAD: () = unsafe {
+        MaybeUninit::<!>::uninit().assume_init();
+    };
+}
diff --git a/src/test/ui/consts/assume-type-intrinsics.stderr b/src/test/ui/consts/assume-type-intrinsics.stderr
new file mode 100644
index 00000000000..ed09f74e9b1
--- /dev/null
+++ b/src/test/ui/consts/assume-type-intrinsics.stderr
@@ -0,0 +1,21 @@
+error: any use of this value will cause an error
+  --> $SRC_DIR/core/src/mem/maybe_uninit.rs:LL:COL
+   |
+LL |               intrinsics::assert_inhabited::<T>();
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |               |
+   |               aborted execution: attempted to instantiate uninhabited type `!`
+   |               inside `MaybeUninit::<!>::assume_init` at $SRC_DIR/core/src/mem/maybe_uninit.rs:LL:COL
+   |               inside `_BAD` at $DIR/assume-type-intrinsics.rs:11:9
+   | 
+  ::: $DIR/assume-type-intrinsics.rs:10:5
+   |
+LL | /     const _BAD: () = unsafe {
+LL | |         MaybeUninit::<!>::uninit().assume_init();
+LL | |     };
+   | |______-
+   |
+   = note: `#[deny(const_err)]` on by default
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/consts/const-fn-error.rs b/src/test/ui/consts/const-fn-error.rs
index 68a4d414ff3..68a4d414ff3 100644
--- a/src/test/compile-fail/consts/const-fn-error.rs
+++ b/src/test/ui/consts/const-fn-error.rs
diff --git a/src/test/ui/consts/const-fn-error.stderr b/src/test/ui/consts/const-fn-error.stderr
new file mode 100644
index 00000000000..86b1eebcb2c
--- /dev/null
+++ b/src/test/ui/consts/const-fn-error.stderr
@@ -0,0 +1,49 @@
+error[E0744]: `for` is not allowed in a `const fn`
+  --> $DIR/const-fn-error.rs:7:5
+   |
+LL | /     for i in 0..x {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |         sum += i;
+LL | |     }
+   | |_____^
+
+error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+  --> $DIR/const-fn-error.rs:7:14
+   |
+LL |     for i in 0..x {
+   |              ^^^^
+
+error[E0658]: mutable references are not allowed in constant functions
+  --> $DIR/const-fn-error.rs:7:14
+   |
+LL |     for i in 0..x {
+   |              ^^^^
+   |
+   = 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/const-fn-error.rs:7:14
+   |
+LL |     for i in 0..x {
+   |              ^^^^
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/const-fn-error.rs:7:14
+   |
+LL |     for i in 0..x {
+   |              ^^^^
+   |              |
+   |              calling non-const function `<std::ops::Range<usize> as IntoIterator>::into_iter`
+   |              inside `f` at $DIR/const-fn-error.rs:7:14
+...
+LL |     let a : [i32; f(X)];
+   |                   ---- inside `main::{constant#0}` at $DIR/const-fn-error.rs:20:19
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0015, E0080, E0658, E0744.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/src/test/ui/consts/const-size_of_val-align_of_val.rs b/src/test/ui/consts/const-size_of_val-align_of_val.rs
index e8e6f1d3900..5c0d7d94d64 100644
--- a/src/test/ui/consts/const-size_of_val-align_of_val.rs
+++ b/src/test/ui/consts/const-size_of_val-align_of_val.rs
@@ -1,6 +1,7 @@
 // run-pass
 
 #![feature(const_size_of_val, const_align_of_val)]
+#![feature(const_size_of_val_raw, const_align_of_val_raw, layout_for_ptr)]
 
 use std::mem;
 
@@ -32,6 +33,9 @@ const ALIGN_OF_UGH: usize = mem::align_of_val(&UGH);
 
 const SIZE_OF_SLICE: usize = mem::size_of_val("foobar".as_bytes());
 
+const SIZE_OF_DANGLING: usize = unsafe { mem::size_of_val_raw(0x100 as *const i32) };
+const ALIGN_OF_DANGLING: usize = unsafe { mem::align_of_val_raw(0x100 as *const i16) };
+
 fn main() {
     assert_eq!(SIZE_OF_FOO, mem::size_of::<Foo>());
     assert_eq!(SIZE_OF_BAR, mem::size_of::<Bar>());
@@ -41,5 +45,8 @@ fn main() {
     assert_eq!(ALIGN_OF_BAR, mem::align_of::<Bar>());
     assert_eq!(ALIGN_OF_UGH, mem::align_of::<Ugh>());
 
+    assert_eq!(SIZE_OF_DANGLING, mem::size_of::<i32>());
+    assert_eq!(ALIGN_OF_DANGLING, mem::align_of::<i16>());
+
     assert_eq!(SIZE_OF_SLICE, "foobar".len());
 }
diff --git a/src/test/compile-fail/issue-44415.rs b/src/test/ui/consts/issue-44415.rs
index 71e764620d1..71e764620d1 100644
--- a/src/test/compile-fail/issue-44415.rs
+++ b/src/test/ui/consts/issue-44415.rs
diff --git a/src/test/ui/consts/issue-44415.stderr b/src/test/ui/consts/issue-44415.stderr
new file mode 100644
index 00000000000..38841e99a72
--- /dev/null
+++ b/src/test/ui/consts/issue-44415.stderr
@@ -0,0 +1,28 @@
+error[E0391]: cycle detected when simplifying constant for the type system `Foo::bytes::{constant#0}`
+  --> $DIR/issue-44415.rs:6:17
+   |
+LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
+   |                 ^^^^^^
+   |
+note: ...which requires simplifying constant for the type system `Foo::bytes::{constant#0}`...
+  --> $DIR/issue-44415.rs:6:17
+   |
+LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
+   |                 ^^^^^^
+note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`...
+  --> $DIR/issue-44415.rs:6:17
+   |
+LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
+   |                 ^^^^^^
+   = note: ...which requires computing layout of `Foo`...
+   = note: ...which requires normalizing `[u8; _]`...
+   = note: ...which again requires simplifying constant for the type system `Foo::bytes::{constant#0}`, completing the cycle
+note: cycle used when checking that `Foo` is well-formed
+  --> $DIR/issue-44415.rs:5:1
+   |
+LL | struct Foo {
+   | ^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/compile-fail/consts/issue-55878.rs b/src/test/ui/consts/issue-55878.rs
index fee664caa17..c1c54646db8 100644
--- a/src/test/compile-fail/consts/issue-55878.rs
+++ b/src/test/ui/consts/issue-55878.rs
@@ -1,3 +1,4 @@
+// build-fail
 // normalize-stderr-64bit "18446744073709551615" -> "SIZE"
 // normalize-stderr-32bit "4294967295" -> "SIZE"
 
diff --git a/src/test/ui/consts/issue-55878.stderr b/src/test/ui/consts/issue-55878.stderr
new file mode 100644
index 00000000000..924910e9cb6
--- /dev/null
+++ b/src/test/ui/consts/issue-55878.stderr
@@ -0,0 +1,25 @@
+error[E0080]: values of the type `[u8; SIZE]` are too big for the current architecture
+  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+   |
+LL |     intrinsics::size_of::<T>()
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     inside `std::mem::size_of::<[u8; SIZE]>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+   |     inside `main` at $DIR/issue-55878.rs:7:26
+   | 
+  ::: $DIR/issue-55878.rs:7:26
+   |
+LL |     println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
+   |                          ----------------------------------------------
+
+error: erroneous constant used
+  --> $DIR/issue-55878.rs:7:26
+   |
+LL |     println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+   |
+   = note: `#[deny(const_err)]` on by default
+
+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/const_refers_to_static_cross_crate.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr
index 52662ef9eaf..b65e50eb9f4 100644
--- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr
+++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr
@@ -146,6 +146,11 @@ help: skipping check that does not even have a feature gate
    |
 LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: skipping check that does not even have a feature gate
+  --> $DIR/const_refers_to_static_cross_crate.rs:32:20
+   |
+LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check for `const_panic` feature
   --> $DIR/const_refers_to_static_cross_crate.rs:32:77
    |
diff --git a/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-repeat.rs b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-repeat.rs
new file mode 100644
index 00000000000..65d02317d34
--- /dev/null
+++ b/src/test/ui/consts/rfc-2203-const-array-repeat-exprs/const-repeat.rs
@@ -0,0 +1,27 @@
+// run-pass
+
+// Repeating a *constant* of non-Copy type (not just a constant expression) is already stable.
+
+const EMPTY: Vec<i32> = Vec::new();
+
+pub fn bar() -> [Vec<i32>; 2] {
+    [EMPTY; 2]
+}
+
+struct Bomb;
+
+impl Drop for Bomb {
+    fn drop(&mut self) {
+        panic!("BOOM!");
+    }
+}
+
+const BOOM: Bomb = Bomb;
+
+fn main() {
+    let _x = bar();
+
+    // Make sure the destructor does not get called for empty arrays. `[CONST; N]` should
+    // instantiate (and then later drop) the const exactly `N` times.
+    let _x = [BOOM; 0];
+}
diff --git a/src/test/compile-fail/auxiliary/crateresolve1-1.rs b/src/test/ui/crate-loading/auxiliary/crateresolve1-1.rs
index a00a19e46d5..a00a19e46d5 100644
--- a/src/test/compile-fail/auxiliary/crateresolve1-1.rs
+++ b/src/test/ui/crate-loading/auxiliary/crateresolve1-1.rs
diff --git a/src/test/compile-fail/auxiliary/crateresolve1-2.rs b/src/test/ui/crate-loading/auxiliary/crateresolve1-2.rs
index 71cc0a12ea3..71cc0a12ea3 100644
--- a/src/test/compile-fail/auxiliary/crateresolve1-2.rs
+++ b/src/test/ui/crate-loading/auxiliary/crateresolve1-2.rs
diff --git a/src/test/compile-fail/auxiliary/crateresolve1-3.rs b/src/test/ui/crate-loading/auxiliary/crateresolve1-3.rs
index 921687d4c3b..921687d4c3b 100644
--- a/src/test/compile-fail/auxiliary/crateresolve1-3.rs
+++ b/src/test/ui/crate-loading/auxiliary/crateresolve1-3.rs
diff --git a/src/test/compile-fail/crateresolve1.rs b/src/test/ui/crate-loading/crateresolve1.rs
index 453c8d97622..49e47dacc3d 100644
--- a/src/test/compile-fail/crateresolve1.rs
+++ b/src/test/ui/crate-loading/crateresolve1.rs
@@ -1,3 +1,4 @@
+// dont-check-compiler-stderr
 // aux-build:crateresolve1-1.rs
 // aux-build:crateresolve1-2.rs
 // aux-build:crateresolve1-3.rs
diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.rs b/src/test/ui/deprecation/rustc_deprecation-in-future.rs
index 6a619bcc49c..11f7960b757 100644
--- a/src/test/ui/deprecation/rustc_deprecation-in-future.rs
+++ b/src/test/ui/deprecation/rustc_deprecation-in-future.rs
@@ -8,8 +8,13 @@
 
 #[rustc_deprecated(since = "99.99.99", reason = "effectively never")]
 #[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")]
-pub struct S;
+pub struct S1;
+
+#[rustc_deprecated(since = "TBD", reason = "literally never")]
+#[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")]
+pub struct S2;
 
 fn main() {
-    let _ = S; //~ ERROR use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never
+    let _ = S1; //~ ERROR use of unit struct `S1` that will be deprecated in future version 99.99.99: effectively never
+    let _ = S2; //~ ERROR use of unit struct `S2` that will be deprecated in a future Rust version: literally never
 }
diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr
index e4f50d10dad..b5a7dd3c28d 100644
--- a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr
+++ b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr
@@ -1,8 +1,8 @@
-error: use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never
-  --> $DIR/rustc_deprecation-in-future.rs:14:13
+error: use of unit struct `S1` that will be deprecated in future version 99.99.99: effectively never
+  --> $DIR/rustc_deprecation-in-future.rs:18:13
    |
-LL |     let _ = S;
-   |             ^
+LL |     let _ = S1;
+   |             ^^
    |
 note: the lint level is defined here
   --> $DIR/rustc_deprecation-in-future.rs:3:9
@@ -10,5 +10,11 @@ note: the lint level is defined here
 LL | #![deny(deprecated_in_future)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: use of unit struct `S2` that will be deprecated in a future Rust version: literally never
+  --> $DIR/rustc_deprecation-in-future.rs:19:13
+   |
+LL |     let _ = S2;
+   |             ^^
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/dropck/dropck_trait_cycle_checked.rs b/src/test/ui/dropck/dropck_trait_cycle_checked.rs
index bea77dc9f5c..be6ec3e4ed1 100644
--- a/src/test/ui/dropck/dropck_trait_cycle_checked.rs
+++ b/src/test/ui/dropck/dropck_trait_cycle_checked.rs
@@ -1,7 +1,7 @@
 // Reject mixing cyclic structure and Drop when using trait
 // objects to hide the cross-references.
 //
-// (Compare against compile-fail/dropck_vec_cycle_checked.rs)
+// (Compare against ui/span/dropck_vec_cycle_checked.rs)
 
 use std::cell::Cell;
 use id::Id;
diff --git a/src/test/ui/dropck/reject-specialized-drops-8142.rs b/src/test/ui/dropck/reject-specialized-drops-8142.rs
index 02e8665cd2e..c9599f6e805 100644
--- a/src/test/ui/dropck/reject-specialized-drops-8142.rs
+++ b/src/test/ui/dropck/reject-specialized-drops-8142.rs
@@ -1,7 +1,5 @@
 // Issue 8142: Test that Drop impls cannot be specialized beyond the
 // predicates attached to the type definition itself.
-#![feature(min_const_generics)]
-
 trait Bound { fn foo(&self) { } }
 struct K<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 }
 struct L<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 }
diff --git a/src/test/ui/dropck/reject-specialized-drops-8142.stderr b/src/test/ui/dropck/reject-specialized-drops-8142.stderr
index 284cf59c822..cb4d97a8b20 100644
--- a/src/test/ui/dropck/reject-specialized-drops-8142.stderr
+++ b/src/test/ui/dropck/reject-specialized-drops-8142.stderr
@@ -1,108 +1,108 @@
 error[E0367]: `Drop` impl requires `'adds_bnd: 'al` but the struct it is implemented for does not
-  --> $DIR/reject-specialized-drops-8142.rs:26:20
+  --> $DIR/reject-specialized-drops-8142.rs:24:20
    |
 LL | impl<'al,'adds_bnd:'al> Drop for K<'al,'adds_bnd> {                        // REJECT
    |                    ^^^
    |
 note: the implementor must specify the same requirement
-  --> $DIR/reject-specialized-drops-8142.rs:6:1
+  --> $DIR/reject-specialized-drops-8142.rs:4:1
    |
 LL | struct K<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0367]: `Drop` impl requires `'adds_bnd: 'al` but the struct it is implemented for does not
-  --> $DIR/reject-specialized-drops-8142.rs:30:67
+  --> $DIR/reject-specialized-drops-8142.rs:28:67
    |
 LL | impl<'al,'adds_bnd>     Drop for L<'al,'adds_bnd> where 'adds_bnd:'al {    // REJECT
    |                                                                   ^^^
    |
 note: the implementor must specify the same requirement
-  --> $DIR/reject-specialized-drops-8142.rs:7:1
+  --> $DIR/reject-specialized-drops-8142.rs:5:1
    |
 LL | struct L<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/reject-specialized-drops-8142.rs:36:1
+  --> $DIR/reject-specialized-drops-8142.rs:34:1
    |
 LL | impl                    Drop for N<'static>     { fn drop(&mut self) { } } // REJECT
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
    = note: expected struct `N<'n>`
               found struct `N<'static>`
-note: the lifetime `'n` as defined on the struct at 9:10...
-  --> $DIR/reject-specialized-drops-8142.rs:9:10
+note: the lifetime `'n` as defined on the struct at 7:10...
+  --> $DIR/reject-specialized-drops-8142.rs:7:10
    |
 LL | struct N<'n> { x: &'n i8 }
    |          ^^
    = note: ...does not necessarily outlive the static lifetime
 
 error[E0366]: `Drop` impls cannot be specialized
-  --> $DIR/reject-specialized-drops-8142.rs:43:1
+  --> $DIR/reject-specialized-drops-8142.rs:41:1
    |
 LL | impl              Drop for P<i8>          { fn drop(&mut self) { } } // REJECT
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: use the same sequence of generic type, lifetime and const parameters as the struct definition
-  --> $DIR/reject-specialized-drops-8142.rs:11:1
+  --> $DIR/reject-specialized-drops-8142.rs:9:1
    |
 LL | struct P<Tp> { x: *const Tp }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the struct it is implemented for does not
-  --> $DIR/reject-specialized-drops-8142.rs:46:14
+  --> $DIR/reject-specialized-drops-8142.rs:44:14
    |
 LL | impl<AddsBnd:Bound> Drop for Q<AddsBnd> { fn drop(&mut self) { } } // REJECT
    |              ^^^^^
    |
 note: the implementor must specify the same requirement
-  --> $DIR/reject-specialized-drops-8142.rs:12:1
+  --> $DIR/reject-specialized-drops-8142.rs:10:1
    |
 LL | struct Q<Tq> { x: *const Tq }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0367]: `Drop` impl requires `AddsRBnd: 'rbnd` but the struct it is implemented for does not
-  --> $DIR/reject-specialized-drops-8142.rs:49:21
+  --> $DIR/reject-specialized-drops-8142.rs:47:21
    |
 LL | impl<'rbnd,AddsRBnd:'rbnd> Drop for R<AddsRBnd> { fn drop(&mut self) { } } // REJECT
    |                     ^^^^^
    |
 note: the implementor must specify the same requirement
-  --> $DIR/reject-specialized-drops-8142.rs:13:1
+  --> $DIR/reject-specialized-drops-8142.rs:11:1
    |
 LL | struct R<Tr> { x: *const Tr }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0366]: `Drop` impls cannot be specialized
-  --> $DIR/reject-specialized-drops-8142.rs:58:1
+  --> $DIR/reject-specialized-drops-8142.rs:56:1
    |
 LL | impl<One>         Drop for V<One,One>     { fn drop(&mut self) { } } // REJECT
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: use the same sequence of generic type, lifetime and const parameters as the struct definition
-  --> $DIR/reject-specialized-drops-8142.rs:17:1
+  --> $DIR/reject-specialized-drops-8142.rs:15:1
    |
 LL | struct V<Tva, Tvb> { x: *const Tva, y: *const Tvb }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'lw` due to conflicting requirements
-  --> $DIR/reject-specialized-drops-8142.rs:61:1
+  --> $DIR/reject-specialized-drops-8142.rs:59:1
    |
 LL | impl<'lw>         Drop for W<'lw,'lw>     { fn drop(&mut self) { } } // REJECT
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: first, the lifetime cannot outlive the lifetime `'l1` as defined on the struct at 18:10...
-  --> $DIR/reject-specialized-drops-8142.rs:18:10
+note: first, the lifetime cannot outlive the lifetime `'l1` as defined on the struct at 16:10...
+  --> $DIR/reject-specialized-drops-8142.rs:16:10
    |
 LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 }
    |          ^^^
-note: ...but the lifetime must also be valid for the lifetime `'l2` as defined on the struct at 18:15...
-  --> $DIR/reject-specialized-drops-8142.rs:18:15
+note: ...but the lifetime must also be valid for the lifetime `'l2` as defined on the struct at 16:15...
+  --> $DIR/reject-specialized-drops-8142.rs:16:15
    |
 LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 }
    |               ^^^
 note: ...so that the types are compatible
-  --> $DIR/reject-specialized-drops-8142.rs:61:1
+  --> $DIR/reject-specialized-drops-8142.rs:59:1
    |
 LL | impl<'lw>         Drop for W<'lw,'lw>     { fn drop(&mut self) { } } // REJECT
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -110,61 +110,61 @@ LL | impl<'lw>         Drop for W<'lw,'lw>     { fn drop(&mut self) { } } // REJ
               found `W<'_, '_>`
 
 error[E0366]: `Drop` impls cannot be specialized
-  --> $DIR/reject-specialized-drops-8142.rs:64:1
+  --> $DIR/reject-specialized-drops-8142.rs:62:1
    |
 LL | impl              Drop for X<3>           { fn drop(&mut self) { } } // REJECT
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: use the same sequence of generic type, lifetime and const parameters as the struct definition
-  --> $DIR/reject-specialized-drops-8142.rs:19:1
+  --> $DIR/reject-specialized-drops-8142.rs:17:1
    |
 LL | struct X<const Ca: usize>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0366]: `Drop` impls cannot be specialized
-  --> $DIR/reject-specialized-drops-8142.rs:67:1
+  --> $DIR/reject-specialized-drops-8142.rs:65:1
    |
 LL | impl<const Ca: usize> Drop for Y<Ca, Ca>     { fn drop(&mut self) { } } // REJECT
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: use the same sequence of generic type, lifetime and const parameters as the struct definition
-  --> $DIR/reject-specialized-drops-8142.rs:20:1
+  --> $DIR/reject-specialized-drops-8142.rs:18:1
    |
 LL | struct Y<const Ca: usize, const Cb: usize>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the enum it is implemented for does not
-  --> $DIR/reject-specialized-drops-8142.rs:70:14
+  --> $DIR/reject-specialized-drops-8142.rs:68:14
    |
 LL | impl<AddsBnd:Bound> Drop for Enum<AddsBnd> { fn drop(&mut self) { } } // REJECT
    |              ^^^^^
    |
 note: the implementor must specify the same requirement
-  --> $DIR/reject-specialized-drops-8142.rs:22:1
+  --> $DIR/reject-specialized-drops-8142.rs:20:1
    |
 LL | enum Enum<T> { Variant(T) }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the struct it is implemented for does not
-  --> $DIR/reject-specialized-drops-8142.rs:73:14
+  --> $DIR/reject-specialized-drops-8142.rs:71:14
    |
 LL | impl<AddsBnd:Bound> Drop for TupleStruct<AddsBnd> { fn drop(&mut self) { } } // REJECT
    |              ^^^^^
    |
 note: the implementor must specify the same requirement
-  --> $DIR/reject-specialized-drops-8142.rs:23:1
+  --> $DIR/reject-specialized-drops-8142.rs:21:1
    |
 LL | struct TupleStruct<T>(T);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the union it is implemented for does not
-  --> $DIR/reject-specialized-drops-8142.rs:76:21
+  --> $DIR/reject-specialized-drops-8142.rs:74:21
    |
 LL | impl<AddsBnd:Copy + Bound> Drop for Union<AddsBnd> { fn drop(&mut self) { } } // REJECT
    |                     ^^^^^
    |
 note: the implementor must specify the same requirement
-  --> $DIR/reject-specialized-drops-8142.rs:24:1
+  --> $DIR/reject-specialized-drops-8142.rs:22:1
    |
 LL | union Union<T: Copy> { f: T }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs
index 0cfb93d4668..f927dd18903 100644
--- a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs
+++ b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs
@@ -7,7 +7,7 @@ use core::intrinsics::discriminant_value;
 enum MyWeirdOption<T> {
     None = 0,
     Some(T) = std::mem::size_of::<T>(),
-    //~^ ERROR constant expression depends on a generic parameter
+    //~^ ERROR generic parameters may not be used in const operations
 }
 
 fn main() {
diff --git a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr
index 91d488a07cc..4d57765e13f 100644
--- a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr
+++ b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr
@@ -1,10 +1,11 @@
-error: constant expression depends on a generic parameter
-  --> $DIR/issue-70453-generics-in-discr-ice-2.rs:9:15
+error: generic parameters may not be used in const operations
+  --> $DIR/issue-70453-generics-in-discr-ice-2.rs:9:35
    |
 LL |     Some(T) = std::mem::size_of::<T>(),
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                   ^ cannot perform const operation using `T`
    |
-   = note: this may fail depending on what value the parameter takes
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs
index 676f1115dde..a0fb788a510 100644
--- a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs
+++ b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs
@@ -8,7 +8,7 @@ enum MyWeirdOption<T> {
 //~^ ERROR parameter `T` is never used
     None = 0,
     Some = std::mem::size_of::<T>(),
-    //~^ ERROR constant expression depends on a generic parameter
+    //~^ ERROR generic parameters may not be used in const operations
 }
 
 fn main() {
diff --git a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr
index 0dc5432d28c..1d43903928b 100644
--- a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr
+++ b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr
@@ -1,10 +1,11 @@
-error: constant expression depends on a generic parameter
-  --> $DIR/issue-70453-generics-in-discr-ice.rs:10:12
+error: generic parameters may not be used in const operations
+  --> $DIR/issue-70453-generics-in-discr-ice.rs:10:32
    |
 LL |     Some = std::mem::size_of::<T>(),
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                ^ cannot perform const operation using `T`
    |
-   = note: this may fail depending on what value the parameter takes
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error[E0392]: parameter `T` is never used
   --> $DIR/issue-70453-generics-in-discr-ice.rs:7:20
diff --git a/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs
index cdc1db4c0b4..e62582fb516 100644
--- a/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs
+++ b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs
@@ -1,4 +1,3 @@
-// run-pass
 #![feature(arbitrary_enum_discriminant, core_intrinsics)]
 
 extern crate core;
@@ -8,8 +7,7 @@ use core::intrinsics::discriminant_value;
 enum MyWeirdOption<T> {
     None = 0,
     Some(T) = core::mem::size_of::<*mut T>(),
-    //~^ WARN cannot use constants which depend on generic parameters in types
-    //~| WARN this was previously accepted by the compiler but is being phased out
+    //~^ ERROR generic parameters may not be used
 }
 
 fn main() {
diff --git a/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr
index 906927e705e..8c97af263b2 100644
--- a/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr
+++ b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr
@@ -1,12 +1,11 @@
-warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/issue-70453-polymorphic-ctfe.rs:10:15
+error: generic parameters may not be used in const operations
+  --> $DIR/issue-70453-polymorphic-ctfe.rs:9:41
    |
 LL |     Some(T) = core::mem::size_of::<*mut T>(),
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                         ^ cannot perform const operation using `T`
    |
-   = note: `#[warn(const_evaluatable_unchecked)]` 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 #76200 <https://github.com/rust-lang/rust/issues/76200>
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
-warning: 1 warning emitted
+error: aborting due to previous error
 
diff --git a/src/test/ui/enum/issue-67945-1.rs b/src/test/ui/enum/issue-67945-1.rs
index 7977bddae7b..f4697344cc7 100644
--- a/src/test/ui/enum/issue-67945-1.rs
+++ b/src/test/ui/enum/issue-67945-1.rs
@@ -1,6 +1,6 @@
-enum Bug<S> {
+enum Bug<S> { //~ ERROR parameter `S` is never used
     Var = {
-        let x: S = 0; //~ ERROR: mismatched types
+        let x: S = 0; //~ ERROR generic parameters may not be used
         0
     },
 }
diff --git a/src/test/ui/enum/issue-67945-1.stderr b/src/test/ui/enum/issue-67945-1.stderr
index 6583fe13d0c..32ca94203e6 100644
--- a/src/test/ui/enum/issue-67945-1.stderr
+++ b/src/test/ui/enum/issue-67945-1.stderr
@@ -1,17 +1,20 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-67945-1.rs:3:20
+error: generic parameters may not be used in const operations
+  --> $DIR/issue-67945-1.rs:3:16
    |
-LL | enum Bug<S> {
-   |          - this type parameter
-LL |     Var = {
 LL |         let x: S = 0;
-   |                -   ^ expected type parameter `S`, found integer
-   |                |
-   |                expected due to this
+   |                ^ cannot perform const operation using `S`
+   |
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
+
+error[E0392]: parameter `S` is never used
+  --> $DIR/issue-67945-1.rs:1:10
+   |
+LL | enum Bug<S> {
+   |          ^ unused parameter
    |
-   = note: expected type parameter `S`
-                        found type `{integer}`
+   = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0392`.
diff --git a/src/test/ui/enum/issue-67945-2.rs b/src/test/ui/enum/issue-67945-2.rs
index 16bd8530ab3..e5044468da1 100644
--- a/src/test/ui/enum/issue-67945-2.rs
+++ b/src/test/ui/enum/issue-67945-2.rs
@@ -1,9 +1,8 @@
 #![feature(type_ascription)]
 
-enum Bug<S> {
+enum Bug<S> { //~ ERROR parameter `S` is never used
     Var = 0: S,
-    //~^ ERROR: mismatched types
-    //~| ERROR: mismatched types
+    //~^ ERROR generic parameters may not be used
 }
 
 fn main() {}
diff --git a/src/test/ui/enum/issue-67945-2.stderr b/src/test/ui/enum/issue-67945-2.stderr
index c40506d59ed..a738d3b15a5 100644
--- a/src/test/ui/enum/issue-67945-2.stderr
+++ b/src/test/ui/enum/issue-67945-2.stderr
@@ -1,25 +1,20 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-67945-2.rs:4:11
+error: generic parameters may not be used in const operations
+  --> $DIR/issue-67945-2.rs:4:14
    |
-LL | enum Bug<S> {
-   |          - this type parameter
 LL |     Var = 0: S,
-   |           ^ expected type parameter `S`, found integer
+   |              ^ cannot perform const operation using `S`
    |
-   = note: expected type parameter `S`
-                        found type `{integer}`
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
-error[E0308]: mismatched types
-  --> $DIR/issue-67945-2.rs:4:11
+error[E0392]: parameter `S` is never used
+  --> $DIR/issue-67945-2.rs:3:10
    |
 LL | enum Bug<S> {
-   |          - this type parameter
-LL |     Var = 0: S,
-   |           ^^^^ expected `isize`, found type parameter `S`
+   |          ^ unused parameter
    |
-   = note:        expected type `isize`
-           found type parameter `S`
+   = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0392`.
diff --git a/src/test/ui/error-codes/E0396.rs b/src/test/ui/error-codes/E0396.rs
index b32853e483d..58ed3c2c722 100644
--- a/src/test/ui/error-codes/E0396.rs
+++ b/src/test/ui/error-codes/E0396.rs
@@ -5,5 +5,16 @@ const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
 const VALUE: u8 = unsafe { *REG_ADDR };
 //~^ ERROR dereferencing raw pointers in constants is unstable
 
+const unsafe fn unreachable() -> ! {
+    use std::convert::Infallible;
+
+    const INFALLIBLE: *const Infallible = [].as_ptr();
+    match *INFALLIBLE {}
+    //~^ ERROR dereferencing raw pointers in constant functions is unstable
+
+    const BAD: () = unsafe { match *INFALLIBLE {} };
+    //~^ ERROR dereferencing raw pointers in constants is unstable
+}
+
 fn main() {
 }
diff --git a/src/test/ui/error-codes/E0396.stderr b/src/test/ui/error-codes/E0396.stderr
index 7d2544f939f..20dad1b983c 100644
--- a/src/test/ui/error-codes/E0396.stderr
+++ b/src/test/ui/error-codes/E0396.stderr
@@ -7,6 +7,24 @@ LL | const VALUE: u8 = unsafe { *REG_ADDR };
    = note: see issue #51911 <https://github.com/rust-lang/rust/issues/51911> for more information
    = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
 
-error: aborting due to previous error
+error[E0658]: dereferencing raw pointers in constant functions is unstable
+  --> $DIR/E0396.rs:12:11
+   |
+LL |     match *INFALLIBLE {}
+   |           ^^^^^^^^^^^
+   |
+   = note: see issue #51911 <https://github.com/rust-lang/rust/issues/51911> for more information
+   = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
+
+error[E0658]: dereferencing raw pointers in constants is unstable
+  --> $DIR/E0396.rs:15:36
+   |
+LL |     const BAD: () = unsafe { match *INFALLIBLE {} };
+   |                                    ^^^^^^^^^^^
+   |
+   = note: see issue #51911 <https://github.com/rust-lang/rust/issues/51911> for more information
+   = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/error-codes/E0730.stderr b/src/test/ui/error-codes/E0730.stderr
index 356e4f36042..f915f6edef5 100644
--- a/src/test/ui/error-codes/E0730.stderr
+++ b/src/test/ui/error-codes/E0730.stderr
@@ -6,7 +6,6 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error[E0730]: cannot pattern-match on an array without a fixed length
   --> $DIR/E0730.rs:6:9
diff --git a/src/test/ui/error-codes/E0771.stderr b/src/test/ui/error-codes/E0771.stderr
index b184b599817..60220be6b57 100644
--- a/src/test/ui/error-codes/E0771.stderr
+++ b/src/test/ui/error-codes/E0771.stderr
@@ -6,7 +6,6 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error[E0771]: use of non-static lifetime `'a` in const generic
   --> $DIR/E0771.rs:4:41
diff --git a/src/test/compile-fail/empty-extern-arg.rs b/src/test/ui/extern-flag/empty-extern-arg.rs
index d3cb5aaaeba..d3cb5aaaeba 100644
--- a/src/test/compile-fail/empty-extern-arg.rs
+++ b/src/test/ui/extern-flag/empty-extern-arg.rs
diff --git a/src/test/ui/extern-flag/empty-extern-arg.stderr b/src/test/ui/extern-flag/empty-extern-arg.stderr
new file mode 100644
index 00000000000..199c4fb616b
--- /dev/null
+++ b/src/test/ui/extern-flag/empty-extern-arg.stderr
@@ -0,0 +1,4 @@
+error: extern location for std does not exist: 
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/feature-gate-edition_macro_pats.rs b/src/test/ui/feature-gate-edition_macro_pats.rs
new file mode 100644
index 00000000000..bd8a21ea36a
--- /dev/null
+++ b/src/test/ui/feature-gate-edition_macro_pats.rs
@@ -0,0 +1,8 @@
+// Feature gate test for `edition_macro_pats` feature.
+
+macro_rules! foo {
+    ($x:pat2018) => {}; //~ERROR `pat2018` and `pat2021` are unstable
+    ($x:pat2021) => {}; //~ERROR `pat2018` and `pat2021` are unstable
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gate-edition_macro_pats.stderr b/src/test/ui/feature-gate-edition_macro_pats.stderr
new file mode 100644
index 00000000000..89bfb239d9e
--- /dev/null
+++ b/src/test/ui/feature-gate-edition_macro_pats.stderr
@@ -0,0 +1,21 @@
+error[E0658]: `pat2018` and `pat2021` are unstable.
+  --> $DIR/feature-gate-edition_macro_pats.rs:4:9
+   |
+LL |     ($x:pat2018) => {};
+   |         ^^^^^^^
+   |
+   = note: see issue #54883 <https://github.com/rust-lang/rust/issues/54883> for more information
+   = help: add `#![feature(edition_macro_pats)]` to the crate attributes to enable
+
+error[E0658]: `pat2018` and `pat2021` are unstable.
+  --> $DIR/feature-gate-edition_macro_pats.rs:5:9
+   |
+LL |     ($x:pat2021) => {};
+   |         ^^^^^^^
+   |
+   = note: see issue #54883 <https://github.com/rust-lang/rust/issues/54883> for more information
+   = help: add `#![feature(edition_macro_pats)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-const_generics-ptr.rs b/src/test/ui/feature-gates/feature-gate-const_generics-ptr.rs
deleted file mode 100644
index dc602ba7e6f..00000000000
--- a/src/test/ui/feature-gates/feature-gate-const_generics-ptr.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-struct ConstFn<const F: fn()>;
-//~^ ERROR const generics are unstable
-//~^^ ERROR using function pointers as const generic parameters is forbidden
-
-struct ConstPtr<const P: *const u32>;
-//~^ ERROR const generics are unstable
-//~^^ ERROR using raw pointers as const generic parameters is forbidden
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-const_generics-ptr.stderr b/src/test/ui/feature-gates/feature-gate-const_generics-ptr.stderr
deleted file mode 100644
index eef465318a3..00000000000
--- a/src/test/ui/feature-gates/feature-gate-const_generics-ptr.stderr
+++ /dev/null
@@ -1,33 +0,0 @@
-error[E0658]: const generics are unstable
-  --> $DIR/feature-gate-const_generics-ptr.rs:1:22
-   |
-LL | struct ConstFn<const F: fn()>;
-   |                      ^
-   |
-   = note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
-   = help: add `#![feature(min_const_generics)]` to the crate attributes to enable
-
-error[E0658]: const generics are unstable
-  --> $DIR/feature-gate-const_generics-ptr.rs:5:23
-   |
-LL | struct ConstPtr<const P: *const u32>;
-   |                       ^
-   |
-   = note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
-   = help: add `#![feature(min_const_generics)]` to the crate attributes to enable
-
-error: using function pointers as const generic parameters is forbidden
-  --> $DIR/feature-gate-const_generics-ptr.rs:1:25
-   |
-LL | struct ConstFn<const F: fn()>;
-   |                         ^^^^
-
-error: using raw pointers as const generic parameters is forbidden
-  --> $DIR/feature-gate-const_generics-ptr.rs:5:26
-   |
-LL | struct ConstPtr<const P: *const u32>;
-   |                          ^^^^^^^^^^
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-const_generics.rs b/src/test/ui/feature-gates/feature-gate-const_generics.rs
index fe1ded1c4bb..06364eebef9 100644
--- a/src/test/ui/feature-gates/feature-gate-const_generics.rs
+++ b/src/test/ui/feature-gates/feature-gate-const_generics.rs
@@ -1,5 +1,5 @@
-fn foo<const X: ()>() {} //~ ERROR const generics are unstable
+fn foo<const X: ()>() {} //~ ERROR `()` is forbidden as the type of a const generic parameter
 
-struct Foo<const X: usize>([(); X]); //~ ERROR const generics are unstable
+struct Foo<const X: usize>([(); X]);
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-const_generics.stderr b/src/test/ui/feature-gates/feature-gate-const_generics.stderr
index f80362252f9..b2b7e4576bf 100644
--- a/src/test/ui/feature-gates/feature-gate-const_generics.stderr
+++ b/src/test/ui/feature-gates/feature-gate-const_generics.stderr
@@ -1,21 +1,11 @@
-error[E0658]: const generics are unstable
-  --> $DIR/feature-gate-const_generics.rs:1:14
+error: `()` is forbidden as the type of a const generic parameter
+  --> $DIR/feature-gate-const_generics.rs:1:17
    |
 LL | fn foo<const X: ()>() {}
-   |              ^
+   |                 ^^
    |
-   = note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
-   = help: add `#![feature(min_const_generics)]` to the crate attributes to enable
+   = note: the only supported types are integers, `bool` and `char`
+   = help: more complex types are supported with `#[feature(const_generics)]`
 
-error[E0658]: const generics are unstable
-  --> $DIR/feature-gate-const_generics.rs:3:18
-   |
-LL | struct Foo<const X: usize>([(); X]);
-   |                  ^
-   |
-   = note: see issue #74878 <https://github.com/rust-lang/rust/issues/74878> for more information
-   = help: add `#![feature(min_const_generics)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/fn/fn-recover-return-sign.fixed b/src/test/ui/fn/fn-recover-return-sign.fixed
new file mode 100644
index 00000000000..076be6a35a4
--- /dev/null
+++ b/src/test/ui/fn/fn-recover-return-sign.fixed
@@ -0,0 +1,28 @@
+// run-rustfix
+#![allow(unused)]
+fn a() -> usize { 0 }
+//~^ ERROR return types are denoted using `->`
+
+fn b()-> usize { 0 }
+//~^ ERROR return types are denoted using `->`
+
+fn bar(_: u32) {}
+
+fn baz() -> *const dyn Fn(u32) { unimplemented!() }
+
+fn foo() {
+    match () {
+        _ if baz() == &bar as &dyn Fn(u32) => (),
+        () => (),
+    }
+}
+
+fn main() {
+    let foo = |a: bool| -> bool { a };
+    //~^ ERROR return types are denoted using `->`
+    dbg!(foo(false));
+
+    let bar = |a: bool|-> bool { a };
+    //~^ ERROR return types are denoted using `->`
+    dbg!(bar(false));
+}
diff --git a/src/test/ui/fn/fn-recover-return-sign.rs b/src/test/ui/fn/fn-recover-return-sign.rs
new file mode 100644
index 00000000000..0656023c0f8
--- /dev/null
+++ b/src/test/ui/fn/fn-recover-return-sign.rs
@@ -0,0 +1,28 @@
+// run-rustfix
+#![allow(unused)]
+fn a() => usize { 0 }
+//~^ ERROR return types are denoted using `->`
+
+fn b(): usize { 0 }
+//~^ ERROR return types are denoted using `->`
+
+fn bar(_: u32) {}
+
+fn baz() -> *const dyn Fn(u32) { unimplemented!() }
+
+fn foo() {
+    match () {
+        _ if baz() == &bar as &dyn Fn(u32) => (),
+        () => (),
+    }
+}
+
+fn main() {
+    let foo = |a: bool| => bool { a };
+    //~^ ERROR return types are denoted using `->`
+    dbg!(foo(false));
+
+    let bar = |a: bool|: bool { a };
+    //~^ ERROR return types are denoted using `->`
+    dbg!(bar(false));
+}
diff --git a/src/test/ui/fn/fn-recover-return-sign.stderr b/src/test/ui/fn/fn-recover-return-sign.stderr
new file mode 100644
index 00000000000..983109730ff
--- /dev/null
+++ b/src/test/ui/fn/fn-recover-return-sign.stderr
@@ -0,0 +1,26 @@
+error: return types are denoted using `->`
+  --> $DIR/fn-recover-return-sign.rs:3:8
+   |
+LL | fn a() => usize { 0 }
+   |        ^^ help: use `->` instead
+
+error: return types are denoted using `->`
+  --> $DIR/fn-recover-return-sign.rs:6:7
+   |
+LL | fn b(): usize { 0 }
+   |       ^ help: use `->` instead
+
+error: return types are denoted using `->`
+  --> $DIR/fn-recover-return-sign.rs:21:25
+   |
+LL |     let foo = |a: bool| => bool { a };
+   |                         ^^ help: use `->` instead
+
+error: return types are denoted using `->`
+  --> $DIR/fn-recover-return-sign.rs:25:24
+   |
+LL |     let bar = |a: bool|: bool { a };
+   |                        ^ help: use `->` instead
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/fn/fn-recover-return-sign2.rs b/src/test/ui/fn/fn-recover-return-sign2.rs
new file mode 100644
index 00000000000..b6a6a1ec2a6
--- /dev/null
+++ b/src/test/ui/fn/fn-recover-return-sign2.rs
@@ -0,0 +1,8 @@
+// Separate test file because `Fn() => bool` isn't getting fixed and rustfix complained that
+// even though a fix was applied the code was still incorrect
+
+fn foo() => impl Fn() => bool {
+    //~^ ERROR return types are denoted using `->`
+    //~| ERROR expected one of `+`, `->`, `::`, `;`, `where`, or `{`, found `=>`
+    unimplemented!()
+}
diff --git a/src/test/ui/fn/fn-recover-return-sign2.stderr b/src/test/ui/fn/fn-recover-return-sign2.stderr
new file mode 100644
index 00000000000..d62cacd4bf5
--- /dev/null
+++ b/src/test/ui/fn/fn-recover-return-sign2.stderr
@@ -0,0 +1,14 @@
+error: return types are denoted using `->`
+  --> $DIR/fn-recover-return-sign2.rs:4:10
+   |
+LL | fn foo() => impl Fn() => bool {
+   |          ^^ help: use `->` instead
+
+error: expected one of `+`, `->`, `::`, `;`, `where`, or `{`, found `=>`
+  --> $DIR/fn-recover-return-sign2.rs:4:23
+   |
+LL | fn foo() => impl Fn() => bool {
+   |                       ^^ expected one of `+`, `->`, `::`, `;`, `where`, or `{`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/fn/issue-80179.rs b/src/test/ui/fn/issue-80179.rs
new file mode 100644
index 00000000000..7609b1525cc
--- /dev/null
+++ b/src/test/ui/fn/issue-80179.rs
@@ -0,0 +1,27 @@
+// Functions with a type placeholder `_` as the return type should
+// show a function pointer suggestion when given a function item
+// and suggest how to return closures correctly from a function.
+// This is a regression test of #80179
+
+fn returns_i32() -> i32 {
+    0
+}
+
+fn returns_fn_ptr() -> _ {
+//~^ ERROR the type placeholder `_` is not allowed within types on item signatures [E0121]
+//~| NOTE not allowed in type signatures
+//~| HELP replace with the correct return type
+//~| SUGGESTION fn() -> i32
+    returns_i32
+}
+
+fn returns_closure() -> _ {
+//~^ ERROR the type placeholder `_` is not allowed within types on item signatures [E0121]
+//~| NOTE not allowed in type signatures
+//~| HELP consider using an `Fn`, `FnMut`, or `FnOnce` trait bound
+//~| NOTE for more information on `Fn` traits and closure types, see
+//        https://doc.rust-lang.org/book/ch13-01-closures.html
+    || 0
+}
+
+fn main() {}
diff --git a/src/test/ui/fn/issue-80179.stderr b/src/test/ui/fn/issue-80179.stderr
new file mode 100644
index 00000000000..63571e71b34
--- /dev/null
+++ b/src/test/ui/fn/issue-80179.stderr
@@ -0,0 +1,21 @@
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/issue-80179.rs:10:24
+   |
+LL | fn returns_fn_ptr() -> _ {
+   |                        ^
+   |                        |
+   |                        not allowed in type signatures
+   |                        help: replace with the correct return type: `fn() -> i32`
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/issue-80179.rs:18:25
+   |
+LL | fn returns_closure() -> _ {
+   |                         ^ not allowed in type signatures
+   |
+   = help: consider using an `Fn`, `FnMut`, or `FnOnce` trait bound
+   = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/fsu-moves-and-copies.rs b/src/test/ui/fsu-moves-and-copies.rs
index c41bcc73fa5..6a0b4ed17b9 100644
--- a/src/test/ui/fsu-moves-and-copies.rs
+++ b/src/test/ui/fsu-moves-and-copies.rs
@@ -36,7 +36,7 @@ impl Drop for DropMoveFoo { fn drop(&mut self) { } }
 fn test0() {
     // just copy implicitly copyable fields from `f`, no moves
     // (and thus it is okay that these are Drop; compare against
-    // compile-fail test: borrowck-struct-update-with-dtor.rs).
+    // test ui/borrowck/borrowck-struct-update-with-dtor.rs).
 
     // Case 1: Nocopyable
     let f = DropNoFoo::new(1, 2);
diff --git a/src/test/ui/functions-closures/closure-expected-type/README.md b/src/test/ui/functions-closures/closure-expected-type/README.md
index fd493e1ff37..11d2c9b7fb7 100644
--- a/src/test/ui/functions-closures/closure-expected-type/README.md
+++ b/src/test/ui/functions-closures/closure-expected-type/README.md
@@ -5,4 +5,4 @@ inputs. This investigation was kicked off by #38714, which revealed
 some pretty deep flaws in the ad-hoc way that we were doing things
 before.
 
-See also `src/test/compile-fail/closure-expected-type`.
+See also `src/test/ui/closure-expected-type`.
diff --git a/src/test/ui/generator/yielding-in-match-guards.rs b/src/test/ui/generator/yielding-in-match-guards.rs
index c76726414df..5c10a7c7811 100644
--- a/src/test/ui/generator/yielding-in-match-guards.rs
+++ b/src/test/ui/generator/yielding-in-match-guards.rs
@@ -10,6 +10,9 @@
 // Thus, `&'_ u8` should be included in type signature
 // of the underlying generator.
 
+#![feature(if_let_guard)]
+#![allow(incomplete_features)]
+
 async fn f() -> u8 { 1 }
 async fn foo() -> [bool; 10] { [false; 10] }
 
@@ -36,8 +39,16 @@ async fn i(x: u8) {
     }
 }
 
+async fn j(x: u8) {
+    match x {
+        y if let (1, 42) = (f().await, y) => (),
+        _ => (),
+    }
+}
+
 fn main() {
     let _ = g(10);
     let _ = h(9);
     let _ = i(8);
+    let _ = j(7);
 }
diff --git a/src/test/ui/generic-associated-types/issue-74824.rs b/src/test/ui/generic-associated-types/issue-74824.rs
new file mode 100644
index 00000000000..00761a97d00
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-74824.rs
@@ -0,0 +1,27 @@
+#![feature(generic_associated_types)]
+#![feature(associated_type_defaults)]
+#![allow(incomplete_features)]
+
+use std::ops::Deref;
+
+trait UnsafeCopy {
+    type Copy<T>: Copy = Box<T>;
+    //~^ ERROR the trait bound `Box<T>: Copy` is not satisfied
+    //~^^ ERROR the trait bound `T: Clone` is not satisfied
+    fn copy<T>(x: &Self::Copy<T>) -> Self::Copy<T> {
+        *x
+    }
+}
+
+impl<T> UnsafeCopy for T {}
+
+fn main() {
+    let b = Box::new(42usize);
+    let copy = <()>::copy(&b);
+
+    let raw_b = Box::deref(&b) as *const _;
+    let raw_copy = Box::deref(&copy) as *const _;
+
+    // assert the addresses.
+    assert_eq!(raw_b, raw_copy);
+}
diff --git a/src/test/ui/generic-associated-types/issue-74824.stderr b/src/test/ui/generic-associated-types/issue-74824.stderr
new file mode 100644
index 00000000000..34a2c1932eb
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-74824.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the trait bound `Box<T>: Copy` is not satisfied
+  --> $DIR/issue-74824.rs:8:5
+   |
+LL |     type Copy<T>: Copy = Box<T>;
+   |     ^^^^^^^^^^^^^^----^^^^^^^^^^
+   |     |             |
+   |     |             required by this bound in `UnsafeCopy::Copy`
+   |     the trait `Copy` is not implemented for `Box<T>`
+
+error[E0277]: the trait bound `T: Clone` is not satisfied
+  --> $DIR/issue-74824.rs:8:5
+   |
+LL |     type Copy<T>: Copy = Box<T>;
+   |     ^^^^^^^^^^^^^^----^^^^^^^^^^
+   |     |             |
+   |     |             required by this bound in `UnsafeCopy::Copy`
+   |     the trait `Clone` is not implemented for `T`
+   |
+   = note: required because of the requirements on the impl of `Clone` for `Box<T>`
+help: consider restricting type parameter `T`
+   |
+LL |     type Copy<T: Clone>: Copy = Box<T>;
+   |                ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generics/param-in-ct-in-ty-param-default.rs b/src/test/ui/generics/param-in-ct-in-ty-param-default.rs
index dd89bc0f7a0..3c62e47381c 100644
--- a/src/test/ui/generics/param-in-ct-in-ty-param-default.rs
+++ b/src/test/ui/generics/param-in-ct-in-ty-param-default.rs
@@ -1,4 +1,4 @@
 struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
-//~^ ERROR constant values inside of type parameter defaults
+//~^ ERROR generic parameters may not be used in const operations
 
 fn main() {}
diff --git a/src/test/ui/generics/param-in-ct-in-ty-param-default.stderr b/src/test/ui/generics/param-in-ct-in-ty-param-default.stderr
index ea867240269..41a0a03ff66 100644
--- a/src/test/ui/generics/param-in-ct-in-ty-param-default.stderr
+++ b/src/test/ui/generics/param-in-ct-in-ty-param-default.stderr
@@ -1,8 +1,11 @@
-error: constant values inside of type parameter defaults must not depend on generic parameters
+error: generic parameters may not be used in const operations
   --> $DIR/param-in-ct-in-ty-param-default.rs:1:44
    |
 LL | struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
-   |                                            ^ the anonymous constant must not depend on the parameter `T`
+   |                                            ^ cannot perform const operation using `T`
+   |
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hygiene/generic_params.stderr b/src/test/ui/hygiene/generic_params.stderr
index 6de36deb597..4ca6d199835 100644
--- a/src/test/ui/hygiene/generic_params.stderr
+++ b/src/test/ui/hygiene/generic_params.stderr
@@ -6,7 +6,6 @@ LL | #![feature(decl_macro, rustc_attrs, const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/hygiene/issue-61574-const-parameters.stderr b/src/test/ui/hygiene/issue-61574-const-parameters.stderr
index 3f85383eb33..b351b8b73a0 100644
--- a/src/test/ui/hygiene/issue-61574-const-parameters.stderr
+++ b/src/test/ui/hygiene/issue-61574-const-parameters.stderr
@@ -6,7 +6,6 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/inherent-impls-overlap-check/auxiliary/repeat.rs b/src/test/ui/inherent-impls-overlap-check/auxiliary/repeat.rs
new file mode 100644
index 00000000000..42ed5d19deb
--- /dev/null
+++ b/src/test/ui/inherent-impls-overlap-check/auxiliary/repeat.rs
@@ -0,0 +1,54 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::{Ident, Group, TokenStream, TokenTree as Tt};
+
+// This constant has to be above the ALLOCATING_ALGO_THRESHOLD
+// constant in inherent_impls_overlap.rs
+const REPEAT_COUNT: u32 = 501;
+
+#[proc_macro]
+/// Repeats the input many times, while replacing idents
+/// named "IDENT" with "id_$v", where v is a counter.
+pub fn repeat_with_idents(input: TokenStream) -> TokenStream {
+    let mut res = Vec::new();
+    fn visit_stream(res: &mut Vec<Tt>, stream :TokenStream, v: u32) {
+        let mut stream_iter = stream.into_iter();
+        while let Some(tt) = stream_iter.next() {
+            match tt {
+                Tt::Group(group) => {
+                    let tt = Tt::Group(visit_group(group, v));
+                    res.push(tt);
+                },
+                Tt::Ident(id) => {
+                    let id = if &id.to_string() == "IDENT" {
+                        Ident::new(&format!("id_{}", v), id.span())
+                    } else {
+                        id
+                    };
+                    res.push(Tt::Ident(id));
+                },
+                Tt::Punct(p) => {
+                    res.push(Tt::Punct(p));
+                },
+                Tt::Literal(lit) => {
+                    res.push(Tt::Literal(lit));
+                },
+            }
+        }
+    }
+    fn visit_group(group :Group, v: u32) -> Group {
+        let mut res = Vec::new();
+        visit_stream(&mut res, group.stream(), v);
+        let stream = res.into_iter().collect();
+        let delim = group.delimiter();
+        Group::new(delim, stream)
+    }
+    for v in 0 .. REPEAT_COUNT {
+        visit_stream(&mut res, input.clone(), v)
+    }
+    res.into_iter().collect()
+}
diff --git a/src/test/ui/inherent-impls-overlap-check/no-overlap.rs b/src/test/ui/inherent-impls-overlap-check/no-overlap.rs
new file mode 100644
index 00000000000..341bfc7b605
--- /dev/null
+++ b/src/test/ui/inherent-impls-overlap-check/no-overlap.rs
@@ -0,0 +1,34 @@
+// run-pass
+// aux-build:repeat.rs
+
+// This tests the allocating algo branch of the
+// inherent impls overlap checker.
+// This branch was added by PR:
+// https://github.com/rust-lang/rust/pull/78317
+// In this test, we repeat many impl blocks
+// to trigger the allocating branch.
+
+#![allow(unused)]
+
+extern crate repeat;
+
+// Simple case where each impl block is distinct
+
+struct Foo {}
+
+repeat::repeat_with_idents!(impl Foo { fn IDENT() {} });
+
+// There are overlapping impl blocks but due to generics,
+// they may overlap.
+
+struct Bar<T>(T);
+
+struct A;
+struct B;
+
+repeat::repeat_with_idents!(impl Bar<A> { fn IDENT() {} });
+
+impl Bar<A> { fn foo() {} }
+impl Bar<B> { fn foo() {} }
+
+fn main() {}
diff --git a/src/test/ui/inherent-impls-overlap-check/overlap.rs b/src/test/ui/inherent-impls-overlap-check/overlap.rs
new file mode 100644
index 00000000000..6f2801197e9
--- /dev/null
+++ b/src/test/ui/inherent-impls-overlap-check/overlap.rs
@@ -0,0 +1,71 @@
+// aux-build:repeat.rs
+
+#![allow(unused)]
+
+// This tests the allocating algo branch of the
+// inherent impls overlap checker.
+// This branch was added by PR:
+// https://github.com/rust-lang/rust/pull/78317
+// In this test, we repeat many impl blocks
+// to trigger the allocating branch.
+
+// Simple overlap
+
+extern crate repeat;
+
+struct Foo {}
+
+repeat::repeat_with_idents!(impl Foo { fn IDENT() {} });
+
+impl Foo { fn hello() {} } //~ERROR duplicate definitions with name `hello`
+impl Foo { fn hello() {} }
+
+// Transitive overlap
+
+struct Foo2 {}
+
+repeat::repeat_with_idents!(impl Foo2 { fn IDENT() {} });
+
+impl Foo2 {
+    fn bar() {}
+    fn hello2() {} //~ERROR duplicate definitions with name `hello2`
+}
+
+impl Foo2 {
+    fn baz() {}
+    fn hello2() {}
+}
+
+// Slightly stronger transitive overlap
+
+struct Foo3 {}
+
+repeat::repeat_with_idents!(impl Foo3 { fn IDENT() {} });
+
+impl Foo3 {
+    fn bar() {} //~ERROR duplicate definitions with name `bar`
+    fn hello3() {} //~ERROR duplicate definitions with name `hello3`
+}
+
+impl Foo3 {
+    fn bar() {}
+    fn hello3() {}
+}
+
+// Generic overlap
+
+struct Bar<T>(T);
+
+struct A;
+struct B;
+
+repeat::repeat_with_idents!(impl Bar<A> { fn IDENT() {} });
+
+impl Bar<A> { fn foo() {} fn bar2() {} }
+impl Bar<B> {
+    fn foo() {}
+    fn bar2() {} //~ERROR duplicate definitions with name `bar2`
+}
+impl Bar<B> { fn bar2() {} }
+
+fn main() {}
diff --git a/src/test/ui/inherent-impls-overlap-check/overlap.stderr b/src/test/ui/inherent-impls-overlap-check/overlap.stderr
new file mode 100644
index 00000000000..3dd2793712f
--- /dev/null
+++ b/src/test/ui/inherent-impls-overlap-check/overlap.stderr
@@ -0,0 +1,47 @@
+error[E0592]: duplicate definitions with name `hello`
+  --> $DIR/overlap.rs:20:12
+   |
+LL | impl Foo { fn hello() {} }
+   |            ^^^^^^^^^^ duplicate definitions for `hello`
+LL | impl Foo { fn hello() {} }
+   |            ---------- other definition for `hello`
+
+error[E0592]: duplicate definitions with name `hello2`
+  --> $DIR/overlap.rs:31:5
+   |
+LL |     fn hello2() {}
+   |     ^^^^^^^^^^^ duplicate definitions for `hello2`
+...
+LL |     fn hello2() {}
+   |     ----------- other definition for `hello2`
+
+error[E0592]: duplicate definitions with name `bar`
+  --> $DIR/overlap.rs:46:5
+   |
+LL |     fn bar() {}
+   |     ^^^^^^^^ duplicate definitions for `bar`
+...
+LL |     fn bar() {}
+   |     -------- other definition for `bar`
+
+error[E0592]: duplicate definitions with name `hello3`
+  --> $DIR/overlap.rs:47:5
+   |
+LL |     fn hello3() {}
+   |     ^^^^^^^^^^^ duplicate definitions for `hello3`
+...
+LL |     fn hello3() {}
+   |     ----------- other definition for `hello3`
+
+error[E0592]: duplicate definitions with name `bar2`
+  --> $DIR/overlap.rs:67:5
+   |
+LL |     fn bar2() {}
+   |     ^^^^^^^^^ duplicate definitions for `bar2`
+LL | }
+LL | impl Bar<B> { fn bar2() {} }
+   |               --------- other definition for `bar2`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0592`.
diff --git a/src/test/ui/inline-const/macro-with-const.rs b/src/test/ui/inline-const/macro-with-const.rs
new file mode 100644
index 00000000000..e7393166d8d
--- /dev/null
+++ b/src/test/ui/inline-const/macro-with-const.rs
@@ -0,0 +1,20 @@
+// check-pass
+
+macro_rules! exp {
+    (const $n:expr) => {
+        $n
+    };
+}
+
+macro_rules! stmt {
+    (exp $e:expr) => {
+        $e
+    };
+    (exp $($t:tt)+) => {
+        exp!($($t)+)
+    };
+}
+
+fn main() {
+    stmt!(exp const 1);
+}
diff --git a/src/test/ui/issues/issue-20433.stderr b/src/test/ui/issues/issue-20433.stderr
index 3f7226c79bf..5fed02164b5 100644
--- a/src/test/ui/issues/issue-20433.stderr
+++ b/src/test/ui/issues/issue-20433.stderr
@@ -4,7 +4,7 @@ error[E0277]: the size for values of type `[i32]` cannot be known at compilation
 LL |     fn iceman(c: Vec<[i32]>) {}
    |                  ^^^^^^^^^^ doesn't have a size known at compile-time
    | 
-  ::: $SRC_DIR/alloc/src/vec.rs:LL:COL
+  ::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
    |
 LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
    |                - required by this bound in `Vec`
diff --git a/src/test/ui/issues/issue-21475.rs b/src/test/ui/issues/issue-21475.rs
index ab0a1886963..b028fcae077 100644
--- a/src/test/ui/issues/issue-21475.rs
+++ b/src/test/ui/issues/issue-21475.rs
@@ -1,5 +1,5 @@
 // run-pass
-#![allow(unused_imports, overlapping_patterns)]
+#![allow(unused_imports, overlapping_range_endpoints)]
 // pretty-expanded FIXME #23616
 
 use m::{START, END};
diff --git a/src/test/ui/issues/issue-23122-2.stderr b/src/test/ui/issues/issue-23122-2.stderr
index ce3bffe602c..ff7e884ea6f 100644
--- a/src/test/ui/issues/issue-23122-2.stderr
+++ b/src/test/ui/issues/issue-23122-2.stderr
@@ -1,11 +1,10 @@
-error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized`
+error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next`
   --> $DIR/issue-23122-2.rs:9:5
    |
 LL |     type Next = <GetNext<T::Next> as Next>::Next;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`issue_23122_2`)
-   = note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-26251.rs b/src/test/ui/issues/issue-26251.rs
index edb06fea8ad..a3e26a41232 100644
--- a/src/test/ui/issues/issue-26251.rs
+++ b/src/test/ui/issues/issue-26251.rs
@@ -1,5 +1,5 @@
 // run-pass
-#![allow(overlapping_patterns)]
+#![allow(overlapping_range_endpoints)]
 
 fn main() {
     let x = 'a';
diff --git a/src/test/ui/issues/issue-26996.rs b/src/test/ui/issues/issue-26996.rs
index 04382be27d7..84037b72a27 100644
--- a/src/test/ui/issues/issue-26996.rs
+++ b/src/test/ui/issues/issue-26996.rs
@@ -1,6 +1,6 @@
 // run-pass
 
-// This test is bogus (i.e., should be compile-fail) during the period
+// This test is bogus (i.e., should be check-fail) during the period
 // where #54986 is implemented and #54987 is *not* implemented. For
 // now: just ignore it
 //
diff --git a/src/test/ui/issues/issue-27021.rs b/src/test/ui/issues/issue-27021.rs
index 30551375450..ef3b114a5fa 100644
--- a/src/test/ui/issues/issue-27021.rs
+++ b/src/test/ui/issues/issue-27021.rs
@@ -1,6 +1,6 @@
 // run-pass
 
-// This test is bogus (i.e., should be compile-fail) during the period
+// This test is bogus (i.e., should be check-fail) during the period
 // where #54986 is implemented and #54987 is *not* implemented. For
 // now: just ignore it
 //
diff --git a/src/test/ui/issues/issue-28498-ugeh-with-lifetime-param.rs b/src/test/ui/issues/issue-28498-ugeh-with-lifetime-param.rs
index aea9fde5309..43c0bfb26cd 100644
--- a/src/test/ui/issues/issue-28498-ugeh-with-lifetime-param.rs
+++ b/src/test/ui/issues/issue-28498-ugeh-with-lifetime-param.rs
@@ -3,7 +3,7 @@
 // Demonstrate the use of the unguarded escape hatch with a lifetime param
 // to assert that destructor will not access any dead data.
 //
-// Compare with compile-fail/issue28498-reject-lifetime-param.rs
+// Compare with ui/span/issue28498-reject-lifetime-param.rs
 
 #![feature(dropck_eyepatch)]
 
diff --git a/src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs b/src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs
index 91ef5a7c98d..23fd86a093b 100644
--- a/src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs
+++ b/src/test/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs
@@ -3,7 +3,7 @@
 // Demonstrate the use of the unguarded escape hatch with a type param in negative position
 // to assert that destructor will not access any dead data.
 //
-// Compare with compile-fail/issue28498-reject-lifetime-param.rs
+// Compare with ui/span/issue28498-reject-lifetime-param.rs
 
 // Demonstrate that a type param in negative position causes dropck to reject code
 // that might indirectly access previously dropped value.
diff --git a/src/test/ui/issues/issue-28498-ugeh-with-trait-bound.rs b/src/test/ui/issues/issue-28498-ugeh-with-trait-bound.rs
index 808f3b6e81e..61d11cf3834 100644
--- a/src/test/ui/issues/issue-28498-ugeh-with-trait-bound.rs
+++ b/src/test/ui/issues/issue-28498-ugeh-with-trait-bound.rs
@@ -3,7 +3,7 @@
 // Demonstrate the use of the unguarded escape hatch with a trait bound
 // to assert that destructor will not access any dead data.
 //
-// Compare with compile-fail/issue28498-reject-trait-bound.rs
+// Compare with ui/span/issue28498-reject-trait-bound.rs
 
 #![feature(dropck_eyepatch)]
 
diff --git a/src/test/ui/issues/issue-39559.rs b/src/test/ui/issues/issue-39559.rs
index 3a75956af52..58d25940733 100644
--- a/src/test/ui/issues/issue-39559.rs
+++ b/src/test/ui/issues/issue-39559.rs
@@ -12,7 +12,7 @@ impl Dim for Dim3 {
 
 pub struct Vector<T, D: Dim> {
     entries: [T; D::dim()],
-    //~^ ERROR no function or associated item named `dim` found
+    //~^ ERROR generic parameters may not be used
     _dummy: D,
 }
 
diff --git a/src/test/ui/issues/issue-39559.stderr b/src/test/ui/issues/issue-39559.stderr
index 5e8d487f416..91e31ca0bd8 100644
--- a/src/test/ui/issues/issue-39559.stderr
+++ b/src/test/ui/issues/issue-39559.stderr
@@ -1,11 +1,11 @@
-error[E0599]: no function or associated item named `dim` found for type parameter `D` in the current scope
-  --> $DIR/issue-39559.rs:14:21
+error: generic parameters may not be used in const operations
+  --> $DIR/issue-39559.rs:14:18
    |
 LL |     entries: [T; D::dim()],
-   |                     ^^^ function or associated item not found in `D`
+   |                  ^^^^^^ cannot perform const operation using `D`
    |
-   = help: items from traits can only be used if the type parameter is bounded by the trait
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-40000.nll.stderr b/src/test/ui/issues/issue-40000.nll.stderr
index f673fbae8b7..4e2bde06a52 100644
--- a/src/test/ui/issues/issue-40000.nll.stderr
+++ b/src/test/ui/issues/issue-40000.nll.stderr
@@ -4,5 +4,11 @@ error: higher-ranked subtype error
 LL |     foo(bar);
    |         ^^^
 
-error: aborting due to previous error
+error: higher-ranked subtype error
+  --> $DIR/issue-40000.rs:6:9
+   |
+LL |     foo(bar);
+   |         ^^^
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-49298.rs b/src/test/ui/issues/issue-49298.rs
index 697a160b4ec..e3ffa8e7c6e 100644
--- a/src/test/ui/issues/issue-49298.rs
+++ b/src/test/ui/issues/issue-49298.rs
@@ -2,7 +2,7 @@
 #![feature(test)]
 #![allow(unused_mut)] // under NLL we get warning about `x` below: rust-lang/rust#54499
 
-// This test is bogus (i.e., should be compile-fail) during the period
+// This test is bogus (i.e., should be check-fail) during the period
 // where #54986 is implemented and #54987 is *not* implemented. For
 // now: just ignore it
 //
diff --git a/src/test/ui/issues/issue-59508-1.stderr b/src/test/ui/issues/issue-59508-1.stderr
index 2a4ccda8929..5e97339f148 100644
--- a/src/test/ui/issues/issue-59508-1.stderr
+++ b/src/test/ui/issues/issue-59508-1.stderr
@@ -12,7 +12,6 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/issues/issue-59508.stderr b/src/test/ui/issues/issue-59508.stderr
index c0fdb2ef34a..33e967cebff 100644
--- a/src/test/ui/issues/issue-59508.stderr
+++ b/src/test/ui/issues/issue-59508.stderr
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
   --> $DIR/issue-59508.rs:10:25
    |
 LL |     pub fn do_things<T, 'a, 'b: 'a>() {
-   |                     ----^^--^^----- help: reorder the parameters: lifetimes, then types: `<'a, 'b: 'a, T>`
+   |                     ----^^--^^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b: 'a, T>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-75763.rs b/src/test/ui/issues/issue-75763.rs
index 2fd9f9a60de..c311de05a1c 100644
--- a/src/test/ui/issues/issue-75763.rs
+++ b/src/test/ui/issues/issue-75763.rs
@@ -1,4 +1,5 @@
-// build-pass
+// ignore-test
+// FIXME(const_generics): This test causes an ICE after reverting #76030.
 
 #![allow(incomplete_features)]
 #![feature(const_generics)]
diff --git a/src/test/ui/issues/issue-78957.rs b/src/test/ui/issues/issue-78957.rs
new file mode 100644
index 00000000000..263c69bbc0b
--- /dev/null
+++ b/src/test/ui/issues/issue-78957.rs
@@ -0,0 +1,30 @@
+#![deny(unused_attributes)]
+#![feature(min_const_generics)]
+
+use std::marker::PhantomData;
+
+pub struct Foo<#[inline] const N: usize>;
+//~^ ERROR attribute should be applied to function or closure
+pub struct Bar<#[cold] const N: usize>;
+//~^ ERROR attribute should be applied to a function
+//~| WARN this was previously accepted
+pub struct Baz<#[repr(C)] const N: usize>;
+//~^ ERROR attribute should be applied to a struct, enum, or union
+//
+pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>);
+//~^ ERROR attribute should be applied to function or closure
+pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>);
+//~^ ERROR attribute should be applied to a function
+//~| WARN this was previously accepted
+pub struct Baz2<#[repr(C)] 'a>(PhantomData<&'a ()>);
+//~^ ERROR attribute should be applied to a struct, enum, or union
+//
+pub struct Foo3<#[inline] T>(PhantomData<T>);
+//~^ ERROR attribute should be applied to function or closure
+pub struct Bar3<#[cold] T>(PhantomData<T>);
+//~^ ERROR attribute should be applied to a function
+//~| WARN this was previously accepted
+pub struct Baz3<#[repr(C)] T>(PhantomData<T>);
+//~^ ERROR attribute should be applied to a struct, enum, or union
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-78957.stderr b/src/test/ui/issues/issue-78957.stderr
new file mode 100644
index 00000000000..26437ee4bef
--- /dev/null
+++ b/src/test/ui/issues/issue-78957.stderr
@@ -0,0 +1,69 @@
+error[E0518]: attribute should be applied to function or closure
+  --> $DIR/issue-78957.rs:6:16
+   |
+LL | pub struct Foo<#[inline] const N: usize>;
+   |                ^^^^^^^^^       - not a function or closure
+
+error: attribute should be applied to a function
+  --> $DIR/issue-78957.rs:8:16
+   |
+LL | pub struct Bar<#[cold] const N: usize>;
+   |                ^^^^^^^       - not a function
+   |
+note: the lint level is defined here
+  --> $DIR/issue-78957.rs:1:9
+   |
+LL | #![deny(unused_attributes)]
+   |         ^^^^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/issue-78957.rs:11:23
+   |
+LL | pub struct Baz<#[repr(C)] const N: usize>;
+   |                       ^         - not a struct, enum, or union
+
+error[E0518]: attribute should be applied to function or closure
+  --> $DIR/issue-78957.rs:14:17
+   |
+LL | pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>);
+   |                 ^^^^^^^^^ -- not a function or closure
+
+error: attribute should be applied to a function
+  --> $DIR/issue-78957.rs:16:17
+   |
+LL | pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>);
+   |                 ^^^^^^^ -- not a function
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/issue-78957.rs:19:24
+   |
+LL | pub struct Baz2<#[repr(C)] 'a>(PhantomData<&'a ()>);
+   |                        ^   -- not a struct, enum, or union
+
+error[E0518]: attribute should be applied to function or closure
+  --> $DIR/issue-78957.rs:22:17
+   |
+LL | pub struct Foo3<#[inline] T>(PhantomData<T>);
+   |                 ^^^^^^^^^ - not a function or closure
+
+error: attribute should be applied to a function
+  --> $DIR/issue-78957.rs:24:17
+   |
+LL | pub struct Bar3<#[cold] T>(PhantomData<T>);
+   |                 ^^^^^^^ - not a function
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/issue-78957.rs:27:24
+   |
+LL | pub struct Baz3<#[repr(C)] T>(PhantomData<T>);
+   |                        ^   - not a struct, enum, or union
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0517, E0518.
+For more information about an error, try `rustc --explain E0517`.
diff --git a/src/test/ui/issues/issue-79593.rs b/src/test/ui/issues/issue-79593.rs
new file mode 100644
index 00000000000..fb54b36940d
--- /dev/null
+++ b/src/test/ui/issues/issue-79593.rs
@@ -0,0 +1,29 @@
+mod foo {
+    pub struct Pub { private: () }
+
+    pub enum Enum {
+        Variant { x: (), y: () },
+        Other
+    }
+
+    fn correct() {
+        Pub {};
+        //~^ ERROR missing field `private` in initializer of `Pub`
+        Enum::Variant { x: () };
+        //~^ ERROR missing field `y` in initializer of `Enum`
+    }
+}
+
+fn correct() {
+    foo::Pub {};
+    //~^ ERROR cannot construct `Pub` with struct literal syntax due to inaccessible fields
+}
+
+fn wrong() {
+    foo::Enum::Variant { x: () };
+    //~^ ERROR missing field `y` in initializer of `Enum`
+    foo::Enum::Variant { };
+    //~^ ERROR missing fields `x`, `y` in initializer of `Enum`
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-79593.stderr b/src/test/ui/issues/issue-79593.stderr
new file mode 100644
index 00000000000..33dbd85032e
--- /dev/null
+++ b/src/test/ui/issues/issue-79593.stderr
@@ -0,0 +1,33 @@
+error[E0063]: missing field `private` in initializer of `Pub`
+  --> $DIR/issue-79593.rs:10:9
+   |
+LL |         Pub {};
+   |         ^^^ missing `private`
+
+error[E0063]: missing field `y` in initializer of `Enum`
+  --> $DIR/issue-79593.rs:12:9
+   |
+LL |         Enum::Variant { x: () };
+   |         ^^^^^^^^^^^^^ missing `y`
+
+error: cannot construct `Pub` with struct literal syntax due to inaccessible fields
+  --> $DIR/issue-79593.rs:18:5
+   |
+LL |     foo::Pub {};
+   |     ^^^^^^^^
+
+error[E0063]: missing field `y` in initializer of `Enum`
+  --> $DIR/issue-79593.rs:23:5
+   |
+LL |     foo::Enum::Variant { x: () };
+   |     ^^^^^^^^^^^^^^^^^^ missing `y`
+
+error[E0063]: missing fields `x`, `y` in initializer of `Enum`
+  --> $DIR/issue-79593.rs:25:5
+   |
+LL |     foo::Enum::Variant { };
+   |     ^^^^^^^^^^^^^^^^^^ missing `x`, `y`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0063`.
diff --git a/src/test/ui/issues/issue-80512-param-reordering-with-defaults.rs b/src/test/ui/issues/issue-80512-param-reordering-with-defaults.rs
new file mode 100644
index 00000000000..fe3e4fbc7e0
--- /dev/null
+++ b/src/test/ui/issues/issue-80512-param-reordering-with-defaults.rs
@@ -0,0 +1,4 @@
+#![crate_type = "lib"]
+
+struct S<T = (), 'a>(&'a T);
+//~^ ERROR lifetime parameters must be declared prior to type parameters
diff --git a/src/test/ui/issues/issue-80512-param-reordering-with-defaults.stderr b/src/test/ui/issues/issue-80512-param-reordering-with-defaults.stderr
new file mode 100644
index 00000000000..a1e9a903f81
--- /dev/null
+++ b/src/test/ui/issues/issue-80512-param-reordering-with-defaults.stderr
@@ -0,0 +1,8 @@
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/issue-80512-param-reordering-with-defaults.rs:3:18
+   |
+LL | struct S<T = (), 'a>(&'a T);
+   |         ---------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = ()>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/label/label_misspelled.rs b/src/test/ui/label/label_misspelled.rs
new file mode 100644
index 00000000000..ebfd5642c9f
--- /dev/null
+++ b/src/test/ui/label/label_misspelled.rs
@@ -0,0 +1,18 @@
+fn main() {
+    'LOOP: loop {
+        LOOP;
+        //~^ ERROR cannot find value `LOOP` in this scope
+    };
+    'while_loop: while true { //~ WARN denote infinite loops with
+        while_loop;
+        //~^ ERROR cannot find value `while_loop` in this scope
+    };
+    'while_let: while let Some(_) = Some(()) {
+        while_let;
+        //~^ ERROR cannot find value `while_let` in this scope
+    }
+    'for_loop: for _ in 0..3 {
+        for_loop;
+        //~^ ERROR cannot find value `for_loop` in this scope
+    };
+}
diff --git a/src/test/ui/label/label_misspelled.stderr b/src/test/ui/label/label_misspelled.stderr
new file mode 100644
index 00000000000..1368ca4126c
--- /dev/null
+++ b/src/test/ui/label/label_misspelled.stderr
@@ -0,0 +1,47 @@
+error[E0425]: cannot find value `LOOP` in this scope
+  --> $DIR/label_misspelled.rs:3:9
+   |
+LL |         LOOP;
+   |         ^^^^
+   |         |
+   |         not found in this scope
+   |         help: a label with a similar name exists: `'LOOP`
+
+error[E0425]: cannot find value `while_loop` in this scope
+  --> $DIR/label_misspelled.rs:7:9
+   |
+LL |         while_loop;
+   |         ^^^^^^^^^^
+   |         |
+   |         not found in this scope
+   |         help: a label with a similar name exists: `'while_loop`
+
+error[E0425]: cannot find value `while_let` in this scope
+  --> $DIR/label_misspelled.rs:11:9
+   |
+LL |         while_let;
+   |         ^^^^^^^^^
+   |         |
+   |         not found in this scope
+   |         help: a label with a similar name exists: `'while_let`
+
+error[E0425]: cannot find value `for_loop` in this scope
+  --> $DIR/label_misspelled.rs:15:9
+   |
+LL |         for_loop;
+   |         ^^^^^^^^
+   |         |
+   |         not found in this scope
+   |         help: a label with a similar name exists: `'for_loop`
+
+warning: denote infinite loops with `loop { ... }`
+  --> $DIR/label_misspelled.rs:6:5
+   |
+LL |     'while_loop: while true {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: use `loop`
+   |
+   = note: `#[warn(while_true)]` on by default
+
+error: aborting due to 4 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs b/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs
index 44cb74815c6..46ae9403c03 100644
--- a/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs
+++ b/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs
@@ -4,7 +4,7 @@ pub const fn sof<T>() -> usize {
 
 fn test<T>() {
     let _: [u8; sof::<T>()];
-    //~^ ERROR the size for values of type `T`
+    //~^ ERROR generic parameters may not be used in const operations
 }
 
 fn main() {}
diff --git a/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.stderr b/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.stderr
index 5a6c86d133b..5c167ea0834 100644
--- a/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.stderr
+++ b/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.stderr
@@ -1,19 +1,11 @@
-error[E0277]: the size for values of type `T` cannot be known at compilation time
+error: generic parameters may not be used in const operations
   --> $DIR/feature-gate-lazy_normalization_consts.rs:6:23
    |
-LL | pub const fn sof<T>() -> usize {
-   |                  - required by this bound in `sof`
-...
-LL | fn test<T>() {
-   |         - this type parameter needs to be `Sized`
 LL |     let _: [u8; sof::<T>()];
-   |                       ^ doesn't have a size known at compile-time
+   |                       ^ cannot perform const operation using `T`
    |
-help: consider relaxing the implicit `Sized` restriction
-   |
-LL | pub const fn sof<T: ?Sized>() -> usize {
-   |                   ^^^^^^^^
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/lifetime-before-type-params.stderr b/src/test/ui/lifetime-before-type-params.stderr
index 76d7d0f024d..047bc7f6d90 100644
--- a/src/test/ui/lifetime-before-type-params.stderr
+++ b/src/test/ui/lifetime-before-type-params.stderr
@@ -2,25 +2,25 @@ error: lifetime parameters must be declared prior to type parameters
   --> $DIR/lifetime-before-type-params.rs:2:13
    |
 LL | fn first<T, 'a, 'b>() {}
-   |         ----^^--^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
+   |         ----^^--^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
 
 error: lifetime parameters must be declared prior to type parameters
   --> $DIR/lifetime-before-type-params.rs:4:18
    |
 LL | fn second<'a, T, 'b>() {}
-   |          --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
+   |          --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
 
 error: lifetime parameters must be declared prior to type parameters
   --> $DIR/lifetime-before-type-params.rs:6:16
    |
 LL | fn third<T, U, 'a>() {}
-   |         -------^^- help: reorder the parameters: lifetimes, then types: `<'a, T, U>`
+   |         -------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>`
 
 error: lifetime parameters must be declared prior to type parameters
   --> $DIR/lifetime-before-type-params.rs:8:18
    |
 LL | fn fourth<'a, T, 'b, U, 'c, V>() {}
-   |          --------^^-----^^---- help: reorder the parameters: lifetimes, then types: `<'a, 'b, 'c, T, U, V>`
+   |          --------^^-----^^---- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, 'c, T, U, V>`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/compile-fail/invalid-link-args.rs b/src/test/ui/linkage-attr/invalid-link-args.rs
index 1e68b4f8b70..5eb1c637f09 100644
--- a/src/test/compile-fail/invalid-link-args.rs
+++ b/src/test/ui/linkage-attr/invalid-link-args.rs
@@ -1,3 +1,5 @@
+// build-fail
+// dont-check-compiler-stderr
 // ignore-msvc due to linker-flavor=ld
 // error-pattern:aFdEfSeVEEE
 // compile-flags: -C linker-flavor=ld
diff --git a/src/test/compile-fail/issue-10755.rs b/src/test/ui/linkage-attr/issue-10755.rs
index 3c6fcddc0d2..5ce69bceed3 100644
--- a/src/test/compile-fail/issue-10755.rs
+++ b/src/test/ui/linkage-attr/issue-10755.rs
@@ -1,3 +1,5 @@
+// build-fail
+// dont-check-compiler-stderr
 // compile-flags: -C linker=llllll -C linker-flavor=ld
 // error-pattern: linker `llllll` not found
 
diff --git a/src/test/ui/lint/expansion-time.rs b/src/test/ui/lint/expansion-time.rs
index a9c7ac363b0..f23c7cb0dca 100644
--- a/src/test/ui/lint/expansion-time.rs
+++ b/src/test/ui/lint/expansion-time.rs
@@ -5,6 +5,10 @@ macro_rules! foo {
     ( $($i:ident)* ) => { $($i)+ }; //~ WARN meta-variable repeats with different Kleene operator
 }
 
+#[warn(missing_fragment_specifier)]
+macro_rules! m { ($i) => {} } //~ WARN missing fragment specifier
+                              //~| WARN this was previously accepted
+
 #[warn(soft_unstable)]
 mod benches {
     #[bench] //~ WARN use of unstable library feature 'test'
diff --git a/src/test/ui/lint/expansion-time.stderr b/src/test/ui/lint/expansion-time.stderr
index 24e2733064e..b0fc1f8e5ee 100644
--- a/src/test/ui/lint/expansion-time.stderr
+++ b/src/test/ui/lint/expansion-time.stderr
@@ -12,14 +12,28 @@ note: the lint level is defined here
 LL | #[warn(meta_variable_misuse)]
    |        ^^^^^^^^^^^^^^^^^^^^
 
+warning: missing fragment specifier
+  --> $DIR/expansion-time.rs:9:19
+   |
+LL | macro_rules! m { ($i) => {} }
+   |                   ^^
+   |
+note: the lint level is defined here
+  --> $DIR/expansion-time.rs:8:8
+   |
+LL | #[warn(missing_fragment_specifier)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = 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 #40107 <https://github.com/rust-lang/rust/issues/40107>
+
 warning: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable
-  --> $DIR/expansion-time.rs:10:7
+  --> $DIR/expansion-time.rs:14:7
    |
 LL |     #[bench]
    |       ^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/expansion-time.rs:8:8
+  --> $DIR/expansion-time.rs:12:8
    |
 LL | #[warn(soft_unstable)]
    |        ^^^^^^^^^^^^^
@@ -33,10 +47,10 @@ LL | 2
    | ^
    |
 note: the lint level is defined here
-  --> $DIR/expansion-time.rs:25:8
+  --> $DIR/expansion-time.rs:29:8
    |
 LL | #[warn(incomplete_include)]
    |        ^^^^^^^^^^^^^^^^^^
 
-warning: 3 warnings emitted
+warning: 4 warnings emitted
 
diff --git a/src/test/ui/lint/function-item-references.rs b/src/test/ui/lint/function-item-references.rs
index 5f7f5e66eaa..05213f4ed4b 100644
--- a/src/test/ui/lint/function-item-references.rs
+++ b/src/test/ui/lint/function-item-references.rs
@@ -1,5 +1,5 @@
 // check-pass
-#![feature(c_variadic, min_const_generics)]
+#![feature(c_variadic)]
 #![warn(function_item_references)]
 use std::fmt::Pointer;
 use std::fmt::Formatter;
diff --git a/src/test/ui/lint/lint-const-item-mutation.rs b/src/test/ui/lint/lint-const-item-mutation.rs
index ef55f31593b..4bf5e0a9e21 100644
--- a/src/test/ui/lint/lint-const-item-mutation.rs
+++ b/src/test/ui/lint/lint-const-item-mutation.rs
@@ -30,6 +30,8 @@ const MUTABLE: Mutable = Mutable { msg: "" };
 const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() };
 const VEC: Vec<i32> = Vec::new();
 const PTR: *mut () = 1 as *mut _;
+const PTR_TO_ARRAY: *mut [u32; 4] = 0x12345678 as _;
+const ARRAY_OF_PTR: [*mut u32; 1] = [1 as *mut _];
 
 fn main() {
     ARRAY[0] = 5; //~ WARN attempting to modify
@@ -55,4 +57,10 @@ fn main() {
     // Test that we don't warn when converting a raw pointer
     // into a mutable reference
     unsafe { &mut *PTR };
+
+    // Test that we don't warn when there's a dereference involved.
+    // If we ever 'leave' the const via a deference, we're going
+    // to end up modifying something other than the temporary
+    unsafe { (*PTR_TO_ARRAY)[0] = 1 };
+    unsafe { *ARRAY_OF_PTR[0] = 25; }
 }
diff --git a/src/test/ui/lint/lint-const-item-mutation.stderr b/src/test/ui/lint/lint-const-item-mutation.stderr
index ae95abc72f3..3973af540c8 100644
--- a/src/test/ui/lint/lint-const-item-mutation.stderr
+++ b/src/test/ui/lint/lint-const-item-mutation.stderr
@@ -1,5 +1,5 @@
 warning: attempting to modify a `const` item
-  --> $DIR/lint-const-item-mutation.rs:35:5
+  --> $DIR/lint-const-item-mutation.rs:37:5
    |
 LL |     ARRAY[0] = 5;
    |     ^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL | const ARRAY: [u8; 1] = [25];
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: attempting to modify a `const` item
-  --> $DIR/lint-const-item-mutation.rs:36:5
+  --> $DIR/lint-const-item-mutation.rs:38:5
    |
 LL |     MY_STRUCT.field = false;
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: attempting to modify a `const` item
-  --> $DIR/lint-const-item-mutation.rs:37:5
+  --> $DIR/lint-const-item-mutation.rs:39:5
    |
 LL |     MY_STRUCT.inner_array[0] = 'b';
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -39,7 +39,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: taking a mutable reference to a `const` item
-  --> $DIR/lint-const-item-mutation.rs:38:5
+  --> $DIR/lint-const-item-mutation.rs:40:5
    |
 LL |     MY_STRUCT.use_mut();
    |     ^^^^^^^^^^^^^^^^^^^
@@ -58,7 +58,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: taking a mutable reference to a `const` item
-  --> $DIR/lint-const-item-mutation.rs:39:5
+  --> $DIR/lint-const-item-mutation.rs:41:5
    |
 LL |     &mut MY_STRUCT;
    |     ^^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: taking a mutable reference to a `const` item
-  --> $DIR/lint-const-item-mutation.rs:40:5
+  --> $DIR/lint-const-item-mutation.rs:42:5
    |
 LL |     (&mut MY_STRUCT).use_mut();
    |     ^^^^^^^^^^^^^^^^
@@ -86,7 +86,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: attempting to modify a `const` item
-  --> $DIR/lint-const-item-mutation.rs:52:5
+  --> $DIR/lint-const-item-mutation.rs:54:5
    |
 LL |     MUTABLE2.msg = "wow";
    |     ^^^^^^^^^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL | const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: taking a mutable reference to a `const` item
-  --> $DIR/lint-const-item-mutation.rs:53:5
+  --> $DIR/lint-const-item-mutation.rs:55:5
    |
 LL |     VEC.push(0);
    |     ^^^^^^^^^^^
@@ -107,7 +107,7 @@ LL |     VEC.push(0);
    = note: each usage of a `const` item creates a new temporary
    = note: the mutable reference will refer to this temporary, not the original `const` item
 note: mutable reference created due to call to this method
-  --> $SRC_DIR/alloc/src/vec.rs:LL:COL
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
    |
 LL | /     pub fn push(&mut self, value: T) {
 LL | |         // This will panic or abort if we would allocate > isize::MAX bytes
diff --git a/src/test/compile-fail/must_use-in-stdlib-traits.rs b/src/test/ui/lint/must_use-in-stdlib-traits.rs
index 70dddf61fb7..70dddf61fb7 100644
--- a/src/test/compile-fail/must_use-in-stdlib-traits.rs
+++ b/src/test/ui/lint/must_use-in-stdlib-traits.rs
diff --git a/src/test/ui/lint/must_use-in-stdlib-traits.stderr b/src/test/ui/lint/must_use-in-stdlib-traits.stderr
new file mode 100644
index 00000000000..76978d29dc8
--- /dev/null
+++ b/src/test/ui/lint/must_use-in-stdlib-traits.stderr
@@ -0,0 +1,47 @@
+error: unused implementer of `Iterator` that must be used
+  --> $DIR/must_use-in-stdlib-traits.rs:42:4
+   |
+LL |    iterator();
+   |    ^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/must_use-in-stdlib-traits.rs:1:9
+   |
+LL | #![deny(unused_must_use)]
+   |         ^^^^^^^^^^^^^^^
+   = note: iterators are lazy and do nothing unless consumed
+
+error: unused implementer of `Future` that must be used
+  --> $DIR/must_use-in-stdlib-traits.rs:43:4
+   |
+LL |    future();
+   |    ^^^^^^^^^
+   |
+   = note: futures do nothing unless you `.await` or poll them
+
+error: unused implementer of `FnOnce` that must be used
+  --> $DIR/must_use-in-stdlib-traits.rs:44:4
+   |
+LL |    square_fn_once();
+   |    ^^^^^^^^^^^^^^^^^
+   |
+   = note: closures are lazy and do nothing unless called
+
+error: unused implementer of `FnMut` that must be used
+  --> $DIR/must_use-in-stdlib-traits.rs:45:4
+   |
+LL |    square_fn_mut();
+   |    ^^^^^^^^^^^^^^^^
+   |
+   = note: closures are lazy and do nothing unless called
+
+error: unused implementer of `Fn` that must be used
+  --> $DIR/must_use-in-stdlib-traits.rs:46:4
+   |
+LL |    square_fn();
+   |    ^^^^^^^^^^^^
+   |
+   = note: closures are lazy and do nothing unless called
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/lint/redundant-semicolon/item-stmt-semi.rs b/src/test/ui/lint/redundant-semicolon/item-stmt-semi.rs
index 4592bc31a39..8c79630b7fd 100644
--- a/src/test/ui/lint/redundant-semicolon/item-stmt-semi.rs
+++ b/src/test/ui/lint/redundant-semicolon/item-stmt-semi.rs
@@ -1,10 +1,6 @@
-// check-pass
-// This test should stop compiling
-// we decide to enable this lint for item statements.
-
 #![deny(redundant_semicolons)]
 
 fn main() {
-    fn inner() {};
-    struct Bar {};
+    fn inner() {}; //~ ERROR unnecessary
+    struct Bar {}; //~ ERROR unnecessary
 }
diff --git a/src/test/ui/lint/redundant-semicolon/item-stmt-semi.stderr b/src/test/ui/lint/redundant-semicolon/item-stmt-semi.stderr
new file mode 100644
index 00000000000..451b152cbe5
--- /dev/null
+++ b/src/test/ui/lint/redundant-semicolon/item-stmt-semi.stderr
@@ -0,0 +1,20 @@
+error: unnecessary trailing semicolon
+  --> $DIR/item-stmt-semi.rs:4:18
+   |
+LL |     fn inner() {};
+   |                  ^ help: remove this semicolon
+   |
+note: the lint level is defined here
+  --> $DIR/item-stmt-semi.rs:1:9
+   |
+LL | #![deny(redundant_semicolons)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unnecessary trailing semicolon
+  --> $DIR/item-stmt-semi.rs:5:18
+   |
+LL |     struct Bar {};
+   |                  ^ help: remove this semicolon
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/compile-fail/asm-src-loc-codegen-units.rs b/src/test/ui/llvm-asm/asm-src-loc-codegen-units.rs
index 5b8690c3b98..387822d00f6 100644
--- a/src/test/compile-fail/asm-src-loc-codegen-units.rs
+++ b/src/test/ui/llvm-asm/asm-src-loc-codegen-units.rs
@@ -1,3 +1,5 @@
+// build-fail
+// dont-check-compiler-stderr
 // compile-flags: -C codegen-units=2
 // ignore-emscripten
 
diff --git a/src/test/compile-fail/asm-src-loc.rs b/src/test/ui/llvm-asm/asm-src-loc.rs
index 7c87f370d4f..063066df11c 100644
--- a/src/test/compile-fail/asm-src-loc.rs
+++ b/src/test/ui/llvm-asm/asm-src-loc.rs
@@ -1,3 +1,5 @@
+// build-fail
+// dont-check-compiler-stderr
 // ignore-emscripten
 
 #![feature(llvm_asm)]
diff --git a/src/test/ui/loops/loop-break-value.rs b/src/test/ui/loops/loop-break-value.rs
index 6c4160c36aa..8a080cfdf49 100644
--- a/src/test/ui/loops/loop-break-value.rs
+++ b/src/test/ui/loops/loop-break-value.rs
@@ -90,4 +90,10 @@ fn main() {
         break; //~ ERROR mismatched types
         break 4;
     };
+
+    'LOOP: for _ in 0 .. 9 {
+        break LOOP;
+        //~^ ERROR cannot find value `LOOP` in this scope
+        //~| ERROR `break` with value from a `for` loop
+    }
 }
diff --git a/src/test/ui/loops/loop-break-value.stderr b/src/test/ui/loops/loop-break-value.stderr
index 0503d3d4c78..0237435c8b4 100644
--- a/src/test/ui/loops/loop-break-value.stderr
+++ b/src/test/ui/loops/loop-break-value.stderr
@@ -1,3 +1,12 @@
+error[E0425]: cannot find value `LOOP` in this scope
+  --> $DIR/loop-break-value.rs:95:15
+   |
+LL |         break LOOP;
+   |               ^^^^
+   |               |
+   |               not found in this scope
+   |               help: a label with a similar name exists: `'LOOP`
+
 warning: denote infinite loops with `loop { ... }`
   --> $DIR/loop-break-value.rs:26:5
    |
@@ -94,6 +103,17 @@ help: instead, use `break` on its own without a value inside this `for` loop
 LL |             break;
    |             ^^^^^
 
+error[E0571]: `break` with value from a `for` loop
+  --> $DIR/loop-break-value.rs:95:9
+   |
+LL |         break LOOP;
+   |         ^^^^^^^^^^ can only break with a value inside `loop` or breakable block
+   |
+help: instead, use `break` on its own without a value inside this `for` loop
+   |
+LL |         break;
+   |         ^^^^^
+
 error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:4:31
    |
@@ -151,7 +171,7 @@ LL |         break;
    |         expected integer, found `()`
    |         help: give it a value of the expected type: `break value`
 
-error: aborting due to 16 previous errors; 1 warning emitted
+error: aborting due to 18 previous errors; 1 warning emitted
 
-Some errors have detailed explanations: E0308, E0571.
+Some errors have detailed explanations: E0308, E0425, E0571.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/macros/edition-macro-pats.rs b/src/test/ui/macros/edition-macro-pats.rs
new file mode 100644
index 00000000000..ea1f9bff6bf
--- /dev/null
+++ b/src/test/ui/macros/edition-macro-pats.rs
@@ -0,0 +1,14 @@
+// run-pass
+
+#![feature(or_patterns)]
+#![feature(edition_macro_pats)]
+
+macro_rules! foo {
+    (a $x:pat2018) => {};
+    (b $x:pat2021) => {};
+}
+
+fn main() {
+    foo!(a None);
+    foo!(b 1 | 2);
+}
diff --git a/src/test/ui/macros/issue-39404.rs b/src/test/ui/macros/issue-39404.rs
index 054958ba00b..2229f2c3900 100644
--- a/src/test/ui/macros/issue-39404.rs
+++ b/src/test/ui/macros/issue-39404.rs
@@ -2,5 +2,6 @@
 
 macro_rules! m { ($i) => {} }
 //~^ ERROR missing fragment specifier
+//~| WARN previously accepted
 
 fn main() {}
diff --git a/src/test/ui/macros/issue-39404.stderr b/src/test/ui/macros/issue-39404.stderr
index 645f06e59d8..d2f2a823c2a 100644
--- a/src/test/ui/macros/issue-39404.stderr
+++ b/src/test/ui/macros/issue-39404.stderr
@@ -3,6 +3,10 @@ error: missing fragment specifier
    |
 LL | macro_rules! m { ($i) => {} }
    |                   ^^
+   |
+   = note: `#[deny(missing_fragment_specifier)]` 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 #40107 <https://github.com/rust-lang/rust/issues/40107>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/macros/macro-comma-behavior-rpass.rs b/src/test/ui/macros/macro-comma-behavior-rpass.rs
index e5e656de6fa..c46274d59b6 100644
--- a/src/test/ui/macros/macro-comma-behavior-rpass.rs
+++ b/src/test/ui/macros/macro-comma-behavior-rpass.rs
@@ -8,7 +8,7 @@
 // to it being e.g., a place where the addition of an argument
 // causes it to go down a code path with subtly different behavior).
 //
-// There is a companion test in compile-fail.
+// There is a companion failing test.
 
 // compile-flags: --test -C debug_assertions=yes
 // revisions: std core
@@ -68,26 +68,26 @@ fn to_format_or_not_to_format() {
 
     assert!(true, "{}",);
 
-    // assert_eq!(1, 1, "{}",); // see compile-fail
-    // assert_ne!(1, 2, "{}",); // see compile-fail
+    // assert_eq!(1, 1, "{}",); // see check-fail
+    // assert_ne!(1, 2, "{}",); // see check-fail
 
     debug_assert!(true, "{}",);
 
-    // debug_assert_eq!(1, 1, "{}",); // see compile-fail
-    // debug_assert_ne!(1, 2, "{}",); // see compile-fail
-    // eprint!("{}",); // see compile-fail
-    // eprintln!("{}",); // see compile-fail
-    // format!("{}",); // see compile-fail
-    // format_args!("{}",); // see compile-fail
+    // debug_assert_eq!(1, 1, "{}",); // see check-fail
+    // debug_assert_ne!(1, 2, "{}",); // see check-fail
+    // eprint!("{}",); // see check-fail
+    // eprintln!("{}",); // see check-fail
+    // format!("{}",); // see check-fail
+    // format_args!("{}",); // see check-fail
 
     if falsum() { panic!("{}",); }
 
-    // print!("{}",); // see compile-fail
-    // println!("{}",); // see compile-fail
-    // unimplemented!("{}",); // see compile-fail
+    // print!("{}",); // see check-fail
+    // println!("{}",); // see check-fail
+    // unimplemented!("{}",); // see check-fail
 
     if falsum() { unreachable!("{}",); }
 
-    // write!(&mut stdout, "{}",); // see compile-fail
-    // writeln!(&mut stdout, "{}",); // see compile-fail
+    // write!(&mut stdout, "{}",); // see check-fail
+    // writeln!(&mut stdout, "{}",); // see check-fail
 }
diff --git a/src/test/ui/macros/macro-comma-behavior.core.stderr b/src/test/ui/macros/macro-comma-behavior.core.stderr
index dd0cac659fd..ac15e9fa8ea 100644
--- a/src/test/ui/macros/macro-comma-behavior.core.stderr
+++ b/src/test/ui/macros/macro-comma-behavior.core.stderr
@@ -23,22 +23,28 @@ LL |     debug_assert_ne!(1, 2, "{}",);
    |                             ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:54:19
+  --> $DIR/macro-comma-behavior.rs:52:19
    |
 LL |     format_args!("{}",);
    |                   ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:72:21
+  --> $DIR/macro-comma-behavior.rs:68:21
    |
 LL |     unimplemented!("{}",);
    |                     ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:81:24
+  --> $DIR/macro-comma-behavior.rs:77:24
    |
 LL |             write!(f, "{}",)?;
    |                        ^^
 
-error: aborting due to 7 previous errors
+error: 1 positional argument in format string, but no arguments were given
+  --> $DIR/macro-comma-behavior.rs:81:26
+   |
+LL |             writeln!(f, "{}",)?;
+   |                          ^^
+
+error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/macros/macro-comma-behavior.rs b/src/test/ui/macros/macro-comma-behavior.rs
index 0bfe0683078..27d50ff3d57 100644
--- a/src/test/ui/macros/macro-comma-behavior.rs
+++ b/src/test/ui/macros/macro-comma-behavior.rs
@@ -40,10 +40,8 @@ fn to_format_or_not_to_format() {
     }
 
     #[cfg(std)] {
-        // FIXME: compile-fail says "expected error not found" even though
-        //        rustc does emit an error
-        // eprintln!("{}",);
-        // <DISABLED> [std]~^ ERROR no arguments
+        eprintln!("{}",);
+        //[std]~^ ERROR no arguments
     }
 
     #[cfg(std)] {
@@ -63,10 +61,8 @@ fn to_format_or_not_to_format() {
     }
 
     #[cfg(std)] {
-        // FIXME: compile-fail says "expected error not found" even though
-        //        rustc does emit an error
-        // println!("{}",);
-        // <DISABLED> [std]~^ ERROR no arguments
+        println!("{}",);
+        //[std]~^ ERROR no arguments
     }
 
     unimplemented!("{}",);
@@ -82,11 +78,9 @@ fn to_format_or_not_to_format() {
             //[core]~^ ERROR no arguments
             //[std]~^^ ERROR no arguments
 
-            // FIXME: compile-fail says "expected error not found" even though
-            //        rustc does emit an error
-            // writeln!(f, "{}",)?;
-            // <DISABLED> [core]~^ ERROR no arguments
-            // <DISABLED> [std]~^^ ERROR no arguments
+            writeln!(f, "{}",)?;
+            //[core]~^ ERROR no arguments
+            //[std]~^^ ERROR no arguments
             Ok(())
         }
     }
diff --git a/src/test/ui/macros/macro-comma-behavior.std.stderr b/src/test/ui/macros/macro-comma-behavior.std.stderr
index 4372d89fbf5..7fd060e2224 100644
--- a/src/test/ui/macros/macro-comma-behavior.std.stderr
+++ b/src/test/ui/macros/macro-comma-behavior.std.stderr
@@ -29,34 +29,52 @@ LL |         eprint!("{}",);
    |                  ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:50:18
+  --> $DIR/macro-comma-behavior.rs:43:20
+   |
+LL |         eprintln!("{}",);
+   |                    ^^
+
+error: 1 positional argument in format string, but no arguments were given
+  --> $DIR/macro-comma-behavior.rs:48:18
    |
 LL |         format!("{}",);
    |                  ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:54:19
+  --> $DIR/macro-comma-behavior.rs:52:19
    |
 LL |     format_args!("{}",);
    |                   ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:61:17
+  --> $DIR/macro-comma-behavior.rs:59:17
    |
 LL |         print!("{}",);
    |                 ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:72:21
+  --> $DIR/macro-comma-behavior.rs:64:19
+   |
+LL |         println!("{}",);
+   |                   ^^
+
+error: 1 positional argument in format string, but no arguments were given
+  --> $DIR/macro-comma-behavior.rs:68:21
    |
 LL |     unimplemented!("{}",);
    |                     ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:81:24
+  --> $DIR/macro-comma-behavior.rs:77:24
    |
 LL |             write!(f, "{}",)?;
    |                        ^^
 
-error: aborting due to 10 previous errors
+error: 1 positional argument in format string, but no arguments were given
+  --> $DIR/macro-comma-behavior.rs:81:26
+   |
+LL |             writeln!(f, "{}",)?;
+   |                          ^^
+
+error: aborting due to 13 previous errors
 
diff --git a/src/test/ui/macros/macro-comma-support-rpass.rs b/src/test/ui/macros/macro-comma-support-rpass.rs
index 50c0ef3451d..f6c4f896d67 100644
--- a/src/test/ui/macros/macro-comma-support-rpass.rs
+++ b/src/test/ui/macros/macro-comma-support-rpass.rs
@@ -68,7 +68,7 @@ fn column() {
     let _ = column!();
 }
 
-// compile_error! is in a companion to this test in compile-fail
+// compile_error! is in a check-fail companion to this test
 
 #[test]
 fn concat() {
diff --git a/src/test/ui/macros/macro-match-nonterminal.rs b/src/test/ui/macros/macro-match-nonterminal.rs
index 6b023e41372..b23e5c71c03 100644
--- a/src/test/ui/macros/macro-match-nonterminal.rs
+++ b/src/test/ui/macros/macro-match-nonterminal.rs
@@ -2,6 +2,7 @@ macro_rules! test {
     ($a, $b) => {
         //~^ ERROR missing fragment
         //~| ERROR missing fragment
+        //~| WARN this was previously accepted
         ()
     };
 }
diff --git a/src/test/ui/macros/macro-match-nonterminal.stderr b/src/test/ui/macros/macro-match-nonterminal.stderr
index 334d62812cd..674ce3434aa 100644
--- a/src/test/ui/macros/macro-match-nonterminal.stderr
+++ b/src/test/ui/macros/macro-match-nonterminal.stderr
@@ -9,6 +9,10 @@ error: missing fragment specifier
    |
 LL |     ($a, $b) => {
    |          ^^
+   |
+   = note: `#[deny(missing_fragment_specifier)]` 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 #40107 <https://github.com/rust-lang/rust/issues/40107>
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/macros/macro-pat-follow-2018.rs b/src/test/ui/macros/macro-pat-follow-2018.rs
new file mode 100644
index 00000000000..ce2911de986
--- /dev/null
+++ b/src/test/ui/macros/macro-pat-follow-2018.rs
@@ -0,0 +1,15 @@
+// run-pass
+// edition:2018
+
+macro_rules! pat_bar {
+    ($p:pat | $p2:pat) => {{
+        match Some(1u8) {
+            $p | $p2 => {}
+            _ => {}
+        }
+    }};
+}
+
+fn main() {
+    pat_bar!(Some(1u8) | None);
+}
diff --git a/src/test/ui/macros/macro-pat-follow.rs b/src/test/ui/macros/macro-pat-follow.rs
index 8673cf79467..8e02789fdd8 100644
--- a/src/test/ui/macros/macro-pat-follow.rs
+++ b/src/test/ui/macros/macro-pat-follow.rs
@@ -3,29 +3,19 @@ macro_rules! pat_in {
     ($p:pat in $e:expr) => {{
         let mut iter = $e.into_iter();
         while let $p = iter.next() {}
-    }}
+    }};
 }
 
 macro_rules! pat_if {
     ($p:pat if $e:expr) => {{
         match Some(1u8) {
-            $p if $e => {},
+            $p if $e => {}
             _ => {}
         }
-    }}
-}
-
-macro_rules! pat_bar {
-    ($p:pat | $p2:pat) => {{
-        match Some(1u8) {
-            $p | $p2 => {},
-            _ => {}
-        }
-    }}
+    }};
 }
 
 fn main() {
     pat_in!(Some(_) in 0..10);
     pat_if!(Some(x) if x > 0);
-    pat_bar!(Some(1u8) | None);
 }
diff --git a/src/test/compile-fail/not-utf8.bin b/src/test/ui/macros/not-utf8.bin
index 4148e5b88fe..4148e5b88fe 100644
--- a/src/test/compile-fail/not-utf8.bin
+++ b/src/test/ui/macros/not-utf8.bin
Binary files differdiff --git a/src/test/compile-fail/not-utf8.rs b/src/test/ui/macros/not-utf8.rs
index 1cb1fdcb8c9..1cb1fdcb8c9 100644
--- a/src/test/compile-fail/not-utf8.rs
+++ b/src/test/ui/macros/not-utf8.rs
diff --git a/src/test/ui/macros/not-utf8.stderr b/src/test/ui/macros/not-utf8.stderr
new file mode 100644
index 00000000000..f47be14fae3
--- /dev/null
+++ b/src/test/ui/macros/not-utf8.stderr
@@ -0,0 +1,10 @@
+error: couldn't read $DIR/not-utf8.bin: stream did not contain valid UTF-8
+  --> $DIR/not-utf8.rs:4:5
+   |
+LL |     include!("not-utf8.bin")
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/meta/meta-expected-error-wrong-rev.a.stderr b/src/test/ui/meta/meta-expected-error-wrong-rev.a.stderr
new file mode 100644
index 00000000000..583b2c4cfe0
--- /dev/null
+++ b/src/test/ui/meta/meta-expected-error-wrong-rev.a.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/meta-expected-error-wrong-rev.rs:13:18
+   |
+LL |     let x: u32 = 22_usize;
+   |            ---   ^^^^^^^^ expected `u32`, found `usize`
+   |            |
+   |            expected due to this
+   |
+help: change the type of the numeric literal from `usize` to `u32`
+   |
+LL |     let x: u32 = 22_u32;
+   |                  ^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/compile-fail/meta-expected-error-wrong-rev.rs b/src/test/ui/meta/meta-expected-error-wrong-rev.rs
index 7e49434142b..7e49434142b 100644
--- a/src/test/compile-fail/meta-expected-error-wrong-rev.rs
+++ b/src/test/ui/meta/meta-expected-error-wrong-rev.rs
diff --git a/src/test/ui/mir/issue-78496.rs b/src/test/ui/mir/issue-78496.rs
new file mode 100644
index 00000000000..1b0687cfac3
--- /dev/null
+++ b/src/test/ui/mir/issue-78496.rs
@@ -0,0 +1,16 @@
+// run-pass
+// compile-flags: -Z mir-opt-level=2 -C opt-level=0
+
+// example from #78496
+pub enum E<'a> {
+    Empty,
+    Some(&'a E<'a>),
+}
+
+fn f(e: &E) -> u32 {
+   if let E::Some(E::Some(_)) = e { 1 } else { 2 }
+}
+
+fn main() {
+   assert_eq!(f(&E::Empty), 2);
+}
diff --git a/src/test/ui/mir/mir-inlining/array-clone-with-generic-size.rs b/src/test/ui/mir/mir-inlining/array-clone-with-generic-size.rs
index 8a96303e6b9..eec0a4599c3 100644
--- a/src/test/ui/mir/mir-inlining/array-clone-with-generic-size.rs
+++ b/src/test/ui/mir/mir-inlining/array-clone-with-generic-size.rs
@@ -3,8 +3,6 @@
 //
 // build-pass
 // compile-flags: -Zmir-opt-level=2 -Zvalidate-mir
-#![feature(min_const_generics)]
-
 #[derive(Clone)]
 struct Array<T, const N: usize>([T; N]);
 
diff --git a/src/test/compile-fail/issue-52443.rs b/src/test/ui/never_type/issue-52443.rs
index 4519833b864..4519833b864 100644
--- a/src/test/compile-fail/issue-52443.rs
+++ b/src/test/ui/never_type/issue-52443.rs
diff --git a/src/test/ui/never_type/issue-52443.stderr b/src/test/ui/never_type/issue-52443.stderr
new file mode 100644
index 00000000000..051896cb89c
--- /dev/null
+++ b/src/test/ui/never_type/issue-52443.stderr
@@ -0,0 +1,57 @@
+warning: denote infinite loops with `loop { ... }`
+  --> $DIR/issue-52443.rs:6:11
+   |
+LL |     [(); {while true {break}; 0}];
+   |           ^^^^^^^^^^ help: use `loop`
+   |
+   = note: `#[warn(while_true)]` on by default
+
+error[E0744]: `for` is not allowed in a `const`
+  --> $DIR/issue-52443.rs:9:12
+   |
+LL |     [(); { for _ in 0usize.. {}; 0}];
+   |            ^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/issue-52443.rs:2:10
+   |
+LL |     [(); & { loop { continue } } ];
+   |          ^^^^^^^^^^^^^^^^^^^^^^^
+   |          |
+   |          expected `usize`, found reference
+   |          help: consider removing the borrow: `{ loop { continue } }`
+   |
+   = note:   expected type `usize`
+           found reference `&_`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-52443.rs:4:17
+   |
+LL |     [(); loop { break }];
+   |                 ^^^^^
+   |                 |
+   |                 expected `usize`, found `()`
+   |                 help: give it a value of the expected type: `break 42`
+
+error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
+  --> $DIR/issue-52443.rs:9:21
+   |
+LL |     [(); { for _ in 0usize.. {}; 0}];
+   |                     ^^^^^^^^
+
+error[E0764]: mutable references are not allowed in constants
+  --> $DIR/issue-52443.rs:9:21
+   |
+LL |     [(); { for _ in 0usize.. {}; 0}];
+   |                     ^^^^^^^^ `&mut` is only allowed in `const fn`
+
+error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
+  --> $DIR/issue-52443.rs:9:21
+   |
+LL |     [(); { for _ in 0usize.. {}; 0}];
+   |                     ^^^^^^^^
+
+error: aborting due to 6 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0015, E0308, E0744, E0764.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
index 799ed89dcce..4e122d930fc 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -6,7 +6,7 @@ LL |         let mut closure = expect_sig(|p, y| *p = y);
    |
    = note: defining type: test::{closure#0} with closure substs [
                i16,
-               for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) mut &ReLateBound(DebruijnIndex(0), BrNamed('s)) i32, &ReLateBound(DebruijnIndex(0), BrNamed('t0)) i32)),
+               for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) i32)),
                (),
            ]
 
diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr
index a094fc45178..44d1d2327fc 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr
@@ -6,7 +6,7 @@ LL |         let mut closure = expect_sig(|p, y| *p = y);
    |
    = note: defining type: test::{closure#0} with closure substs [
                i16,
-               for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) mut &ReLateBound(DebruijnIndex(0), BrNamed('s)) i32, &ReLateBound(DebruijnIndex(0), BrNamed('s)) i32)),
+               for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32)),
                (),
            ]
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
index c4f4facae1f..fa9f994c4fa 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
@@ -10,7 +10,7 @@ LL | |         },
    |
    = note: defining type: supply::{closure#0} with closure substs [
                i16,
-               for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>)),
+               for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)),
                (),
            ]
    = note: late-bound region is '_#4r
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
index c1450564c45..0555f79bcb0 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
@@ -11,7 +11,7 @@ LL | |     });
    |
    = note: defining type: supply::{closure#0} with closure substs [
                i16,
-               for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t1)) u32>)),
+               for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>)),
                (),
            ]
    = note: late-bound region is '_#3r
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index e7b8dff4e7e..0115f5412f2 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -10,7 +10,7 @@ LL | |     })
    |
    = note: defining type: case1::{closure#0} with closure substs [
                i32,
-               for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>)),
+               for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>)),
                (),
            ]
 
@@ -49,7 +49,7 @@ LL | |     })
    |
    = note: defining type: case2::{closure#0} with closure substs [
                i32,
-               for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>)),
+               for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>)),
                (),
            ]
    = note: number of external vids: 2
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index c7e68d02dcf..e55d033d2c7 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
@@ -12,7 +12,7 @@ LL | |     });
    |
    = note: defining type: supply::{closure#0} with closure substs [
                i16,
-               for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t1)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t2)) u32>)),
+               for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) u32>)),
                (),
            ]
    = note: late-bound region is '_#2r
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index abbc76eaf4d..ac4a4579c9c 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
@@ -12,7 +12,7 @@ LL | |     });
    |
    = note: defining type: supply::{closure#0} with closure substs [
                i16,
-               for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t0)) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed('t1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t1)) u32>)),
+               for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>)),
                (),
            ]
    = note: late-bound region is '_#3r
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
index c91b514a796..60dca1baa40 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
@@ -11,7 +11,7 @@ LL | |     });
    |
    = note: defining type: test::{closure#0} with closure substs [
                i16,
-               for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>)),
+               for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)),
                (),
            ]
    = note: late-bound region is '_#3r
diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
index 4ddf6f8323f..cbb10eb187e 100644
--- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
@@ -10,7 +10,7 @@ LL | |         },
    |
    = note: defining type: supply::{closure#0} with closure substs [
                i16,
-               for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>)),
+               for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)),
                (),
            ]
    = note: late-bound region is '_#3r
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index 6dc6f456805..f9f1d8bb6ff 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -11,7 +11,7 @@ LL | |     });
    |
    = note: defining type: supply::{closure#0} with closure substs [
                i16,
-               for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>)),
+               for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)),
                (),
            ]
    = note: late-bound region is '_#2r
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 6bcada5c26c..1587c28e1be 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -11,7 +11,7 @@ LL | |     });
    |
    = note: defining type: supply::{closure#0} with closure substs [
                i16,
-               for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('s)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed('t3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed('t1)) u32>)),
+               for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>)),
                (),
            ]
    = note: late-bound region is '_#3r
diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
index 1da6c6d2c68..44f743310b4 100644
--- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
+++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
@@ -6,7 +6,7 @@ LL |     expect_sig(|a, b| b); // ought to return `a`
    |
    = note: defining type: test::{closure#0} with closure substs [
                i16,
-               for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) i32, &ReLateBound(DebruijnIndex(0), BrNamed('s)) i32)) -> &ReLateBound(DebruijnIndex(0), BrNamed('r)) i32,
+               for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32)) -> &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) i32,
                (),
            ]
 
diff --git a/src/test/ui/nll/closures-in-loops.stderr b/src/test/ui/nll/closures-in-loops.stderr
index 37638a93d77..2f134f83ced 100644
--- a/src/test/ui/nll/closures-in-loops.stderr
+++ b/src/test/ui/nll/closures-in-loops.stderr
@@ -15,7 +15,7 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
 LL |         v.push(|| x = String::new());
    |                ^^ - borrows occur due to use of `x` in closure
    |                |
-   |                mutable borrow starts here in previous iteration of loop
+   |                `x` was mutably borrowed here in the previous iteration of the loop
 
 error[E0524]: two closures require unique access to `x` at the same time
   --> $DIR/closures-in-loops.rs:20:16
diff --git a/src/test/ui/nll/issue-62007-assign-const-index.stderr b/src/test/ui/nll/issue-62007-assign-const-index.stderr
index 758a14d0177..0db9fe62c38 100644
--- a/src/test/ui/nll/issue-62007-assign-const-index.stderr
+++ b/src/test/ui/nll/issue-62007-assign-const-index.stderr
@@ -5,7 +5,7 @@ LL | fn to_refs<T>(mut list: [&mut List<T>; 2]) -> Vec<&mut T> {
    |                          - let's call the lifetime of this reference `'1`
 ...
 LL |         result.push(&mut list[0].value);
-   |                     ^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop
+   |                     ^^^^^^^^^^^^^^^^^^ `list[_].value` was mutably borrowed here in the previous iteration of the loop
 ...
 LL |             return result;
    |                    ------ returning this value requires that `list[_].value` is borrowed for `'1`
@@ -19,7 +19,7 @@ LL | fn to_refs<T>(mut list: [&mut List<T>; 2]) -> Vec<&mut T> {
 LL |         if let Some(n) = list[0].next.as_mut() {
    |                          ^^^^^^^^^^^^---------
    |                          |
-   |                          mutable borrow starts here in previous iteration of loop
+   |                          `list[_].next` was mutably borrowed here in the previous iteration of the loop
    |                          argument requires that `list[_].next` is borrowed for `'1`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/nll/issue-62007-assign-differing-fields.stderr b/src/test/ui/nll/issue-62007-assign-differing-fields.stderr
index f942d7628b5..f1af2e855af 100644
--- a/src/test/ui/nll/issue-62007-assign-differing-fields.stderr
+++ b/src/test/ui/nll/issue-62007-assign-differing-fields.stderr
@@ -5,7 +5,7 @@ LL | fn to_refs<'a, T>(mut list: (&'a mut List<T>, &'a mut List<T>)) -> Vec<&'a
    |            -- lifetime `'a` defined here
 ...
 LL |         result.push(&mut (list.0).value);
-   |                     ^^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop
+   |                     ^^^^^^^^^^^^^^^^^^^ `list.0.value` was mutably borrowed here in the previous iteration of the loop
 ...
 LL |             return result;
    |                    ------ returning this value requires that `list.0.value` is borrowed for `'a`
@@ -19,7 +19,7 @@ LL | fn to_refs<'a, T>(mut list: (&'a mut List<T>, &'a mut List<T>)) -> Vec<&'a
 LL |         if let Some(n) = (list.0).next.as_mut() {
    |                          ^^^^^^^^^^^^^---------
    |                          |
-   |                          mutable borrow starts here in previous iteration of loop
+   |                          `list.0.next` was mutably borrowed here in the previous iteration of the loop
    |                          argument requires that `list.0.next` is borrowed for `'a`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/nll/polonius/assignment-to-differing-field.stderr b/src/test/ui/nll/polonius/assignment-to-differing-field.stderr
index 07ca021b53b..2fe6a53a49a 100644
--- a/src/test/ui/nll/polonius/assignment-to-differing-field.stderr
+++ b/src/test/ui/nll/polonius/assignment-to-differing-field.stderr
@@ -5,7 +5,7 @@ LL | fn assignment_to_field_projection<'a, T>(
    |                                   -- lifetime `'a` defined here
 ...
 LL |         result.push(&mut (list.0).value);
-   |                     ^^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop
+   |                     ^^^^^^^^^^^^^^^^^^^ `list.0.value` was mutably borrowed here in the previous iteration of the loop
 ...
 LL |             return result;
    |                    ------ returning this value requires that `list.0.value` is borrowed for `'a`
@@ -19,7 +19,7 @@ LL | fn assignment_to_field_projection<'a, T>(
 LL |         if let Some(n) = (list.0).next.as_mut() {
    |                          ^^^^^^^^^^^^^---------
    |                          |
-   |                          mutable borrow starts here in previous iteration of loop
+   |                          `list.0.next` was mutably borrowed here in the previous iteration of the loop
    |                          argument requires that `list.0.next` is borrowed for `'a`
 
 error[E0499]: cannot borrow `list.0.0.0.0.0.value` as mutable more than once at a time
@@ -29,7 +29,7 @@ LL | fn assignment_through_projection_chain<'a, T>(
    |                                        -- lifetime `'a` defined here
 ...
 LL |         result.push(&mut ((((list.0).0).0).0).0.value);
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `list.0.0.0.0.0.value` was mutably borrowed here in the previous iteration of the loop
 ...
 LL |             return result;
    |                    ------ returning this value requires that `list.0.0.0.0.0.value` is borrowed for `'a`
@@ -43,7 +43,7 @@ LL | fn assignment_through_projection_chain<'a, T>(
 LL |         if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() {
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^---------
    |                          |
-   |                          mutable borrow starts here in previous iteration of loop
+   |                          `list.0.0.0.0.0.next` was mutably borrowed here in the previous iteration of the loop
    |                          argument requires that `list.0.0.0.0.0.next` is borrowed for `'a`
 
 error: aborting due to 4 previous errors
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
index 7c0d63c368b..dbf76cd1329 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
@@ -6,7 +6,7 @@ LL |     twice(cell, value, |a, b| invoke(a, b));
    |
    = note: defining type: generic::<T>::{closure#0} with closure substs [
                i16,
-               for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('r)) ()>>, &ReLateBound(DebruijnIndex(0), BrNamed('s)) T)),
+               for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) T)),
                (),
            ]
    = note: number of external vids: 2
@@ -31,7 +31,7 @@ LL |     twice(cell, value, |a, b| invoke(a, b));
    |
    = note: defining type: generic_fail::<T>::{closure#0} with closure substs [
                i16,
-               for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed('r)) ()>>, &ReLateBound(DebruijnIndex(0), BrNamed('s)) T)),
+               for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) T)),
                (),
            ]
    = note: late-bound region is '_#2r
diff --git a/src/test/ui/no-std-macros.rs b/src/test/ui/no-std-macros.rs
new file mode 100644
index 00000000000..ada643c7ac0
--- /dev/null
+++ b/src/test/ui/no-std-macros.rs
@@ -0,0 +1,13 @@
+// compile-flags: --crate-type=lib
+// check-pass
+// issue #55482
+#![no_std]
+
+macro_rules! foo {
+    ($e:expr) => {
+        $crate::core::assert!($e);
+        $crate::core::assert_eq!($e, true);
+    };
+}
+
+pub fn foo() { foo!(true); }
diff --git a/src/test/ui/object-lifetime-default-from-rptr-box.rs b/src/test/ui/object-lifetime-default-from-rptr-box.rs
index 8ac45b3db71..b61083078cc 100644
--- a/src/test/ui/object-lifetime-default-from-rptr-box.rs
+++ b/src/test/ui/object-lifetime-default-from-rptr-box.rs
@@ -23,7 +23,7 @@ fn b<'a>(t: &'a Box<dyn Test>, mut ss: SomeStruct<'a>) {
     ss.u = t;
 }
 
-// see also compile-fail/object-lifetime-default-from-rptr-box-error.rs
+// see also ui/object-lifetime/object-lifetime-default-from-rptr-box-error.rs
 
 fn d<'a>(t: &'a Box<dyn Test+'a>, mut ss: SomeStruct<'a>) {
     ss.u = t;
diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs
index 512f1e283cb..184ffa85c40 100644
--- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs
+++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs
@@ -64,6 +64,35 @@ fn main() {
             | 2, ..] => {}
         _ => {}
     }
+    match &[][..] {
+        [true] => {}
+        [true | false, ..] => {}
+        _ => {}
+    }
+    match &[][..] {
+        [false] => {}
+        [true, ..] => {}
+        [true //~ ERROR unreachable
+            | false, ..] => {}
+        _ => {}
+    }
+    match (true, None) {
+        (true, Some(_)) => {}
+        (false, Some(true)) => {}
+        (true | false, None | Some(true //~ ERROR unreachable
+                                   | false)) => {}
+    }
+    macro_rules! t_or_f {
+        () => {
+            (true // FIXME: should be unreachable
+                        | false)
+        };
+    }
+    match (true, None) {
+        (true, Some(_)) => {}
+        (false, Some(true)) => {}
+        (true | false, None | Some(t_or_f!())) => {}
+    }
     match Some(0) {
         Some(0) => {}
         Some(0 //~ ERROR unreachable
diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr
index e968310d108..8b1003b5514 100644
--- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr
+++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr
@@ -95,28 +95,40 @@ LL |         [1
    |          ^
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:69:14
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:75:10
+   |
+LL |         [true
+   |          ^^^^
+
+error: unreachable pattern
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:82:36
+   |
+LL |         (true | false, None | Some(true
+   |                                    ^^^^
+
+error: unreachable pattern
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:98:14
    |
 LL |         Some(0
    |              ^
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:88:19
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:117:19
    |
 LL |                 | false) => {}
    |                   ^^^^^
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:96:15
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:125:15
    |
 LL |             | true) => {}
    |               ^^^^
 
 error: unreachable pattern
-  --> $DIR/exhaustiveness-unreachable-pattern.rs:102:15
+  --> $DIR/exhaustiveness-unreachable-pattern.rs:131:15
    |
 LL |             | true,
    |               ^^^^
 
-error: aborting due to 19 previous errors
+error: aborting due to 21 previous errors
 
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.rs b/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.rs
new file mode 100644
index 00000000000..9c3c5dd360e
--- /dev/null
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.rs
@@ -0,0 +1,15 @@
+// Test that :pat doesn't accept top-level or-patterns in edition 2018.
+
+// edition:2018
+
+#![feature(or_patterns)]
+
+fn main() {}
+
+// Test the `pat` macro fragment parser:
+macro_rules! accept_pat {
+    ($p:pat) => {};
+}
+
+accept_pat!(p | q); //~ ERROR no rules expected the token `|`
+accept_pat!(|p| q); //~ ERROR no rules expected the token `|`
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr
new file mode 100644
index 00000000000..7dbc3087663
--- /dev/null
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr
@@ -0,0 +1,20 @@
+error: no rules expected the token `|`
+  --> $DIR/or-patterns-syntactic-fail-2018.rs:14:15
+   |
+LL | macro_rules! accept_pat {
+   | ----------------------- when calling this macro
+...
+LL | accept_pat!(p | q);
+   |               ^ no rules expected this token in macro call
+
+error: no rules expected the token `|`
+  --> $DIR/or-patterns-syntactic-fail-2018.rs:15:13
+   |
+LL | macro_rules! accept_pat {
+   | ----------------------- when calling this macro
+...
+LL | accept_pat!(|p| q);
+   |             ^ no rules expected this token in macro call
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
index d2322005652..efe90b3e3c6 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
@@ -5,16 +5,6 @@
 
 fn main() {}
 
-// Test the `pat` macro fragment parser:
-macro_rules! accept_pat {
-    ($p:pat) => {}
-}
-
-accept_pat!(p | q); //~ ERROR no rules expected the token `|`
-accept_pat!(| p | q); //~ ERROR no rules expected the token `|`
-
-// Non-macro tests:
-
 enum E { A, B }
 use E::*;
 
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
index 861d274ab5c..989aeb52006 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
@@ -1,53 +1,53 @@
 error: an or-pattern parameter must be wrapped in parenthesis
-  --> $DIR/or-patterns-syntactic-fail.rs:27:13
+  --> $DIR/or-patterns-syntactic-fail.rs:17:13
    |
 LL |     fn fun1(A | B: E) {}
    |             ^^^^^ help: wrap the pattern in parenthesis: `(A | B)`
 
 error: a leading `|` is not allowed in a parameter pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:29:13
+  --> $DIR/or-patterns-syntactic-fail.rs:19:13
    |
 LL |     fn fun2(| A | B: E) {}
    |             ^ help: remove the `|`
 
 error: an or-pattern parameter must be wrapped in parenthesis
-  --> $DIR/or-patterns-syntactic-fail.rs:29:15
+  --> $DIR/or-patterns-syntactic-fail.rs:19:15
    |
 LL |     fn fun2(| A | B: E) {}
    |               ^^^^^ help: wrap the pattern in parenthesis: `(A | B)`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:40:11
+  --> $DIR/or-patterns-syntactic-fail.rs:30:11
    |
 LL |     let ( | A | B) = E::A;
    |           ^ help: remove the `|`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:41:11
+  --> $DIR/or-patterns-syntactic-fail.rs:31:11
    |
 LL |     let ( | A | B,) = (E::B,);
    |           ^ help: remove the `|`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:42:11
+  --> $DIR/or-patterns-syntactic-fail.rs:32:11
    |
 LL |     let [ | A | B ] = [E::A];
    |           ^ help: remove the `|`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:43:13
+  --> $DIR/or-patterns-syntactic-fail.rs:33:13
    |
 LL |     let TS( | A | B );
    |             ^ help: remove the `|`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:44:17
+  --> $DIR/or-patterns-syntactic-fail.rs:34:17
    |
 LL |     let NS { f: | A | B };
    |                 ^ help: remove the `|`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:46:11
+  --> $DIR/or-patterns-syntactic-fail.rs:36:11
    |
 LL |     let ( || A | B) = E::A;
    |           ^^ help: remove the `||`
@@ -55,7 +55,7 @@ LL |     let ( || A | B) = E::A;
    = note: alternatives in or-patterns are separated with `|`, not `||`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:47:11
+  --> $DIR/or-patterns-syntactic-fail.rs:37:11
    |
 LL |     let [ || A | B ] = [E::A];
    |           ^^ help: remove the `||`
@@ -63,7 +63,7 @@ LL |     let [ || A | B ] = [E::A];
    = note: alternatives in or-patterns are separated with `|`, not `||`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:48:13
+  --> $DIR/or-patterns-syntactic-fail.rs:38:13
    |
 LL |     let TS( || A | B );
    |             ^^ help: remove the `||`
@@ -71,33 +71,15 @@ LL |     let TS( || A | B );
    = note: alternatives in or-patterns are separated with `|`, not `||`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:49:17
+  --> $DIR/or-patterns-syntactic-fail.rs:39:17
    |
 LL |     let NS { f: || A | B };
    |                 ^^ help: remove the `||`
    |
    = note: alternatives in or-patterns are separated with `|`, not `||`
 
-error: no rules expected the token `|`
-  --> $DIR/or-patterns-syntactic-fail.rs:13:15
-   |
-LL | macro_rules! accept_pat {
-   | ----------------------- when calling this macro
-...
-LL | accept_pat!(p | q);
-   |               ^ no rules expected this token in macro call
-
-error: no rules expected the token `|`
-  --> $DIR/or-patterns-syntactic-fail.rs:14:13
-   |
-LL | macro_rules! accept_pat {
-   | ----------------------- when calling this macro
-...
-LL | accept_pat!(| p | q);
-   |             ^ no rules expected this token in macro call
-
 error[E0369]: no implementation for `E | ()`
-  --> $DIR/or-patterns-syntactic-fail.rs:23:22
+  --> $DIR/or-patterns-syntactic-fail.rs:13:22
    |
 LL |     let _ = |A | B: E| ();
    |                  ----^ -- ()
@@ -107,7 +89,7 @@ LL |     let _ = |A | B: E| ();
    = note: an implementation of `std::ops::BitOr` might be missing for `E`
 
 error[E0308]: mismatched types
-  --> $DIR/or-patterns-syntactic-fail.rs:51:36
+  --> $DIR/or-patterns-syntactic-fail.rs:41:36
    |
 LL |     let recovery_witness: String = 0;
    |                           ------   ^
@@ -116,7 +98,7 @@ LL |     let recovery_witness: String = 0;
    |                           |        help: try using a conversion method: `0.to_string()`
    |                           expected due to this
 
-error: aborting due to 16 previous errors
+error: aborting due to 14 previous errors
 
 Some errors have detailed explanations: E0308, E0369.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs
new file mode 100644
index 00000000000..f0ce7597aee
--- /dev/null
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs
@@ -0,0 +1,14 @@
+// Tests that :pat in macros in edition 2021 allows top-level or-patterns.
+
+// run-pass
+// ignore-test
+// edition:2021
+// FIXME(mark-i-m): unignore when 2021 machinery is in place.
+
+macro_rules! accept_pat {
+    ($p:pat) => {};
+}
+
+accept_pat!(p | q);
+
+fn main() {}
diff --git a/src/test/compile-fail/auxiliary/weak-lang-items.rs b/src/test/ui/panic-handler/auxiliary/weak-lang-items.rs
index 7a698cf76ae..7a698cf76ae 100644
--- a/src/test/compile-fail/auxiliary/weak-lang-items.rs
+++ b/src/test/ui/panic-handler/auxiliary/weak-lang-items.rs
diff --git a/src/test/compile-fail/panic-handler-missing.rs b/src/test/ui/panic-handler/panic-handler-missing.rs
index 1c380c99c18..6bb062ba657 100644
--- a/src/test/compile-fail/panic-handler-missing.rs
+++ b/src/test/ui/panic-handler/panic-handler-missing.rs
@@ -1,3 +1,4 @@
+// dont-check-compiler-stderr
 // error-pattern: `#[panic_handler]` function required, but not found
 
 #![feature(lang_items)]
diff --git a/src/test/compile-fail/panic-handler-twice.rs b/src/test/ui/panic-handler/panic-handler-twice.rs
index 0c5359b9bd8..05bef66d849 100644
--- a/src/test/compile-fail/panic-handler-twice.rs
+++ b/src/test/ui/panic-handler/panic-handler-twice.rs
@@ -1,3 +1,4 @@
+// dont-check-compiler-stderr
 // aux-build:some-panic-impl.rs
 
 #![feature(lang_items)]
diff --git a/src/test/compile-fail/weak-lang-item.rs b/src/test/ui/panic-handler/weak-lang-item.rs
index 3fa3822831b..3fa3822831b 100644
--- a/src/test/compile-fail/weak-lang-item.rs
+++ b/src/test/ui/panic-handler/weak-lang-item.rs
diff --git a/src/test/ui/panic-handler/weak-lang-item.stderr b/src/test/ui/panic-handler/weak-lang-item.stderr
new file mode 100644
index 00000000000..b7c040c7a85
--- /dev/null
+++ b/src/test/ui/panic-handler/weak-lang-item.stderr
@@ -0,0 +1,19 @@
+error[E0259]: the name `core` is defined multiple times
+  --> $DIR/weak-lang-item.rs:8:1
+   |
+LL | extern crate core;
+   | ^^^^^^^^^^^^^^^^^^ `core` reimported here
+   |
+   = note: `core` must be defined only once in the type namespace of this module
+help: you can use `as` to change the binding name of the import
+   |
+LL | extern crate core as other_core;
+   |
+
+error: `#[panic_handler]` function required, but not found
+
+error: language item required, but not found: `eh_personality`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0259`.
diff --git a/src/test/compile-fail/auxiliary/depends.rs b/src/test/ui/panic-runtime/auxiliary/depends.rs
index e9bc2f4893e..e9bc2f4893e 100644
--- a/src/test/compile-fail/auxiliary/depends.rs
+++ b/src/test/ui/panic-runtime/auxiliary/depends.rs
diff --git a/src/test/compile-fail/auxiliary/needs-panic-runtime.rs b/src/test/ui/panic-runtime/auxiliary/needs-panic-runtime.rs
index 3f030c169f6..3f030c169f6 100644
--- a/src/test/compile-fail/auxiliary/needs-panic-runtime.rs
+++ b/src/test/ui/panic-runtime/auxiliary/needs-panic-runtime.rs
diff --git a/src/test/compile-fail/runtime-depend-on-needs-runtime.rs b/src/test/ui/panic-runtime/runtime-depend-on-needs-runtime.rs
index 866c5b2e34b..d57f1643e98 100644
--- a/src/test/compile-fail/runtime-depend-on-needs-runtime.rs
+++ b/src/test/ui/panic-runtime/runtime-depend-on-needs-runtime.rs
@@ -1,3 +1,4 @@
+// dont-check-compiler-stderr
 // aux-build:needs-panic-runtime.rs
 // aux-build:depends.rs
 // error-pattern:cannot depend on a crate that needs a panic runtime
diff --git a/src/test/compile-fail/two-panic-runtimes.rs b/src/test/ui/panic-runtime/two-panic-runtimes.rs
index 671d44564e6..c968b5ea1e1 100644
--- a/src/test/compile-fail/two-panic-runtimes.rs
+++ b/src/test/ui/panic-runtime/two-panic-runtimes.rs
@@ -1,3 +1,5 @@
+// build-fail
+// dont-check-compiler-stderr
 // error-pattern:cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2
 // ignore-tidy-linelength
 // aux-build:panic-runtime-unwind.rs
diff --git a/src/test/compile-fail/unwind-tables-panic-required.rs b/src/test/ui/panic-runtime/unwind-tables-panic-required.rs
index 314d9e778d5..6393a27046b 100644
--- a/src/test/compile-fail/unwind-tables-panic-required.rs
+++ b/src/test/ui/panic-runtime/unwind-tables-panic-required.rs
@@ -1,6 +1,7 @@
 // Tests that the compiler errors if the user tries to turn off unwind tables
 // when they are required.
 //
+// dont-check-compiler-stderr
 // compile-flags: -C panic=unwind -C force-unwind-tables=no
 // ignore-tidy-linelength
 //
diff --git a/src/test/compile-fail/unwind-tables-target-required.rs b/src/test/ui/panic-runtime/unwind-tables-target-required.rs
index 14c17893764..14c17893764 100644
--- a/src/test/compile-fail/unwind-tables-target-required.rs
+++ b/src/test/ui/panic-runtime/unwind-tables-target-required.rs
diff --git a/src/test/compile-fail/want-abort-got-unwind.rs b/src/test/ui/panic-runtime/want-abort-got-unwind.rs
index 30782e18229..e33c3bcc3f0 100644
--- a/src/test/compile-fail/want-abort-got-unwind.rs
+++ b/src/test/ui/panic-runtime/want-abort-got-unwind.rs
@@ -1,3 +1,5 @@
+// build-fail
+// dont-check-compiler-stderr
 // error-pattern:is not compiled with this crate's panic strategy `abort`
 // aux-build:panic-runtime-unwind.rs
 // compile-flags:-C panic=abort
diff --git a/src/test/compile-fail/want-abort-got-unwind2.rs b/src/test/ui/panic-runtime/want-abort-got-unwind2.rs
index 35d8d46b55e..438f1d85a28 100644
--- a/src/test/compile-fail/want-abort-got-unwind2.rs
+++ b/src/test/ui/panic-runtime/want-abort-got-unwind2.rs
@@ -1,3 +1,5 @@
+// build-fail
+// dont-check-compiler-stderr
 // error-pattern:is not compiled with this crate's panic strategy `abort`
 // aux-build:panic-runtime-unwind.rs
 // aux-build:wants-panic-runtime-unwind.rs
diff --git a/src/test/ui/parser/fn-colon-return-type.rs b/src/test/ui/parser/fn-colon-return-type.rs
index c791fb3ae67..0001ef57c99 100644
--- a/src/test/ui/parser/fn-colon-return-type.rs
+++ b/src/test/ui/parser/fn-colon-return-type.rs
@@ -1,4 +1,5 @@
-fn foo(x: i32): i32 { //~ ERROR expected one of `->`, `;`, `where`, or `{`, found `:`
+fn foo(x: i32): i32 {
+//~^ ERROR return types are denoted using `->`
     x
 }
 
diff --git a/src/test/ui/parser/fn-colon-return-type.stderr b/src/test/ui/parser/fn-colon-return-type.stderr
index 92df9bc60bd..1de91878205 100644
--- a/src/test/ui/parser/fn-colon-return-type.stderr
+++ b/src/test/ui/parser/fn-colon-return-type.stderr
@@ -1,8 +1,8 @@
-error: expected one of `->`, `;`, `where`, or `{`, found `:`
+error: return types are denoted using `->`
   --> $DIR/fn-colon-return-type.rs:1:15
    |
 LL | fn foo(x: i32): i32 {
-   |               ^ expected one of `->`, `;`, `where`, or `{`
+   |               ^ help: use `->` instead
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/incorrect-move-async-order-issue-79694.fixed b/src/test/ui/parser/incorrect-move-async-order-issue-79694.fixed
new file mode 100644
index 00000000000..055800d23b6
--- /dev/null
+++ b/src/test/ui/parser/incorrect-move-async-order-issue-79694.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+// edition:2018
+
+// Regression test for issue 79694
+
+fn main() {
+    let _ = async move { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect
+}
diff --git a/src/test/ui/parser/incorrect-move-async-order-issue-79694.rs b/src/test/ui/parser/incorrect-move-async-order-issue-79694.rs
new file mode 100644
index 00000000000..e8be16516d6
--- /dev/null
+++ b/src/test/ui/parser/incorrect-move-async-order-issue-79694.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+// edition:2018
+
+// Regression test for issue 79694
+
+fn main() {
+    let _ = move async { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect
+}
diff --git a/src/test/ui/parser/incorrect-move-async-order-issue-79694.stderr b/src/test/ui/parser/incorrect-move-async-order-issue-79694.stderr
new file mode 100644
index 00000000000..2add9fb33c7
--- /dev/null
+++ b/src/test/ui/parser/incorrect-move-async-order-issue-79694.stderr
@@ -0,0 +1,13 @@
+error: the order of `move` and `async` is incorrect
+  --> $DIR/incorrect-move-async-order-issue-79694.rs:7:13
+   |
+LL |     let _ = move async { };
+   |             ^^^^^^^^^^
+   |
+help: try switching the order
+   |
+LL |     let _ = async move { };
+   |             ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issue-14303-enum.stderr b/src/test/ui/parser/issue-14303-enum.stderr
index 46f16ea0cc4..bcecd75b1ab 100644
--- a/src/test/ui/parser/issue-14303-enum.stderr
+++ b/src/test/ui/parser/issue-14303-enum.stderr
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
   --> $DIR/issue-14303-enum.rs:1:15
    |
 LL | enum X<'a, T, 'b> {
-   |       --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
+   |       --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-fn-def.stderr b/src/test/ui/parser/issue-14303-fn-def.stderr
index 8cbab4b9653..082c37e0be7 100644
--- a/src/test/ui/parser/issue-14303-fn-def.stderr
+++ b/src/test/ui/parser/issue-14303-fn-def.stderr
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
   --> $DIR/issue-14303-fn-def.rs:1:15
    |
 LL | fn foo<'a, T, 'b>(x: &'a T) {}
-   |       --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
+   |       --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-impl.stderr b/src/test/ui/parser/issue-14303-impl.stderr
index 56cd4fb3810..3b5615d2a9e 100644
--- a/src/test/ui/parser/issue-14303-impl.stderr
+++ b/src/test/ui/parser/issue-14303-impl.stderr
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
   --> $DIR/issue-14303-impl.rs:3:13
    |
 LL | impl<'a, T, 'b> X<T> {}
-   |     --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
+   |     --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-struct.stderr b/src/test/ui/parser/issue-14303-struct.stderr
index f31cb92ad66..dbd0b987dd1 100644
--- a/src/test/ui/parser/issue-14303-struct.stderr
+++ b/src/test/ui/parser/issue-14303-struct.stderr
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
   --> $DIR/issue-14303-struct.rs:1:17
    |
 LL | struct X<'a, T, 'b> {
-   |         --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
+   |         --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-trait.stderr b/src/test/ui/parser/issue-14303-trait.stderr
index 0e7399102bf..7dfa62d823f 100644
--- a/src/test/ui/parser/issue-14303-trait.stderr
+++ b/src/test/ui/parser/issue-14303-trait.stderr
@@ -2,7 +2,7 @@ error: lifetime parameters must be declared prior to type parameters
   --> $DIR/issue-14303-trait.rs:1:18
    |
 LL | trait Foo<'a, T, 'b> {}
-   |          --------^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, T>`
+   |          --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/macro/issue-33569.rs b/src/test/ui/parser/macro/issue-33569.rs
index cf81f0480a2..80e2d7c6545 100644
--- a/src/test/ui/parser/macro/issue-33569.rs
+++ b/src/test/ui/parser/macro/issue-33569.rs
@@ -2,7 +2,6 @@ macro_rules! foo {
     { $+ } => { //~ ERROR expected identifier, found `+`
                 //~^ ERROR missing fragment specifier
         $(x)(y) //~ ERROR expected one of: `*`, `+`, or `?`
-       //~^ ERROR attempted to repeat an expression containing no syntax variables
     }
 }
 
diff --git a/src/test/ui/parser/macro/issue-33569.stderr b/src/test/ui/parser/macro/issue-33569.stderr
index f54efaa6996..b4d38d3ce48 100644
--- a/src/test/ui/parser/macro/issue-33569.stderr
+++ b/src/test/ui/parser/macro/issue-33569.stderr
@@ -4,23 +4,17 @@ error: expected identifier, found `+`
 LL |     { $+ } => {
    |        ^
 
-error: missing fragment specifier
-  --> $DIR/issue-33569.rs:2:8
-   |
-LL |     { $+ } => {
-   |        ^
-
 error: expected one of: `*`, `+`, or `?`
   --> $DIR/issue-33569.rs:4:13
    |
 LL |         $(x)(y)
    |             ^^^
 
-error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth
-  --> $DIR/issue-33569.rs:4:10
+error: missing fragment specifier
+  --> $DIR/issue-33569.rs:2:8
    |
-LL |         $(x)(y)
-   |          ^^^
+LL |     { $+ } => {
+   |        ^
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.rs b/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.rs
new file mode 100644
index 00000000000..f3ae3aba9b9
--- /dev/null
+++ b/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.rs
@@ -0,0 +1,12 @@
+// Regression test for #80134.
+
+fn main() {
+    (()é);
+    //~^ ERROR: expected one of `)`, `,`, `.`, `?`, or an operator
+    //~| ERROR: cannot find value `é` in this scope
+    //~| ERROR: non-ascii idents are not fully supported
+    (()æ°·);
+    //~^ ERROR: expected one of `)`, `,`, `.`, `?`, or an operator
+    //~| ERROR: cannot find value `æ°·` in this scope
+    //~| ERROR: non-ascii idents are not fully supported
+}
diff --git a/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.stderr b/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.stderr
new file mode 100644
index 00000000000..892cc92b1bd
--- /dev/null
+++ b/src/test/ui/parser/multibyte-char-use-seperator-issue-80134.stderr
@@ -0,0 +1,52 @@
+error: expected one of `)`, `,`, `.`, `?`, or an operator, found `é`
+  --> $DIR/multibyte-char-use-seperator-issue-80134.rs:4:8
+   |
+LL |     (()é);
+   |        ^
+   |        |
+   |        expected one of `)`, `,`, `.`, `?`, or an operator
+   |        help: missing `,`
+
+error: expected one of `)`, `,`, `.`, `?`, or an operator, found `æ°·`
+  --> $DIR/multibyte-char-use-seperator-issue-80134.rs:8:8
+   |
+LL |     (()æ°·);
+   |        -^
+   |        |
+   |        expected one of `)`, `,`, `.`, `?`, or an operator
+   |        help: missing `,`
+
+error[E0425]: cannot find value `é` in this scope
+  --> $DIR/multibyte-char-use-seperator-issue-80134.rs:4:8
+   |
+LL |     (()é);
+   |        ^ not found in this scope
+
+error[E0425]: cannot find value `æ°·` in this scope
+  --> $DIR/multibyte-char-use-seperator-issue-80134.rs:8:8
+   |
+LL |     (()æ°·);
+   |        ^^ not found in this scope
+
+error[E0658]: non-ascii idents are not fully supported
+  --> $DIR/multibyte-char-use-seperator-issue-80134.rs:4:8
+   |
+LL |     (()é);
+   |        ^
+   |
+   = note: see issue #55467 <https://github.com/rust-lang/rust/issues/55467> for more information
+   = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable
+
+error[E0658]: non-ascii idents are not fully supported
+  --> $DIR/multibyte-char-use-seperator-issue-80134.rs:8:8
+   |
+LL |     (()æ°·);
+   |        ^^
+   |
+   = note: see issue #55467 <https://github.com/rust-lang/rust/issues/55467> for more information
+   = help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0425, E0658.
+For more information about an error, try `rustc --explain E0425`.
diff --git a/src/test/ui/parser/not-a-pred.rs b/src/test/ui/parser/not-a-pred.rs
index 1b3d9bf66bb..5518b554d8e 100644
--- a/src/test/ui/parser/not-a-pred.rs
+++ b/src/test/ui/parser/not-a-pred.rs
@@ -1,6 +1,15 @@
 fn f(a: isize, b: isize) : lt(a, b) { }
-//~^ ERROR expected one of `->`, `;`, `where`, or `{`, found `:`
+//~^ ERROR return types are denoted using `->`
+//~| ERROR expected type, found function `lt` [E0573]
+//~| ERROR expected type, found local variable `a` [E0573]
+//~| ERROR expected type, found local variable `b` [E0573]
 
 fn lt(a: isize, b: isize) { }
 
-fn main() { let a: isize = 10; let b: isize = 23; check (lt(a, b)); f(a, b); }
+fn main() {
+    let a: isize = 10;
+    let b: isize = 23;
+    check (lt(a, b));
+    //~^ ERROR cannot find function `check` in this scope [E0425]
+    f(a, b);
+}
diff --git a/src/test/ui/parser/not-a-pred.stderr b/src/test/ui/parser/not-a-pred.stderr
index ec413c5594c..bcc64a687fd 100644
--- a/src/test/ui/parser/not-a-pred.stderr
+++ b/src/test/ui/parser/not-a-pred.stderr
@@ -1,8 +1,34 @@
-error: expected one of `->`, `;`, `where`, or `{`, found `:`
+error: return types are denoted using `->`
   --> $DIR/not-a-pred.rs:1:26
    |
 LL | fn f(a: isize, b: isize) : lt(a, b) { }
-   |                          ^ expected one of `->`, `;`, `where`, or `{`
+   |                          ^ help: use `->` instead
 
-error: aborting due to previous error
+error[E0573]: expected type, found function `lt`
+  --> $DIR/not-a-pred.rs:1:28
+   |
+LL | fn f(a: isize, b: isize) : lt(a, b) { }
+   |                            ^^^^^^^^ not a type
+
+error[E0573]: expected type, found local variable `a`
+  --> $DIR/not-a-pred.rs:1:31
+   |
+LL | fn f(a: isize, b: isize) : lt(a, b) { }
+   |                               ^ not a type
+
+error[E0573]: expected type, found local variable `b`
+  --> $DIR/not-a-pred.rs:1:34
+   |
+LL | fn f(a: isize, b: isize) : lt(a, b) { }
+   |                                  ^ not a type
+
+error[E0425]: cannot find function `check` in this scope
+  --> $DIR/not-a-pred.rs:12:5
+   |
+LL |     check (lt(a, b));
+   |     ^^^^^ not found in this scope
+
+error: aborting due to 5 previous errors
 
+Some errors have detailed explanations: E0425, E0573.
+For more information about an error, try `rustc --explain E0425`.
diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs
index 34aee7f6935..f2d97b7bac3 100644
--- a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs
+++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs
@@ -3,10 +3,10 @@
 fn main() {}
 
 trait X {
-    default const A: u8; //~ ERROR `default` is only allowed on items in `impl` definitions
-    default const B: u8 = 0;  //~ ERROR `default` is only allowed on items in `impl` definitions
-    default type D; //~ ERROR `default` is only allowed on items in `impl` definitions
-    default type C: Ord; //~ ERROR `default` is only allowed on items in `impl` definitions
-    default fn f1(); //~ ERROR `default` is only allowed on items in `impl` definitions
-    default fn f2() {} //~ ERROR `default` is only allowed on items in `impl` definitions
+    default const A: u8; //~ ERROR `default` is only allowed on items in trait impls
+    default const B: u8 = 0;  //~ ERROR `default` is only allowed on items in trait impls
+    default type D; //~ ERROR `default` is only allowed on items in trait impls
+    default type C: Ord; //~ ERROR `default` is only allowed on items in trait impls
+    default fn f1(); //~ ERROR `default` is only allowed on items in trait impls
+    default fn f2() {} //~ ERROR `default` is only allowed on items in trait impls
 }
diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr
index cdc9ee8d9e7..76fa860334d 100644
--- a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr
+++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr
@@ -1,4 +1,4 @@
-error: `default` is only allowed on items in `impl` definitions
+error: `default` is only allowed on items in trait impls
   --> $DIR/trait-item-with-defaultness-fail-semantic.rs:6:5
    |
 LL |     default const A: u8;
@@ -6,7 +6,7 @@ LL |     default const A: u8;
    |     |
    |     `default` because of this
 
-error: `default` is only allowed on items in `impl` definitions
+error: `default` is only allowed on items in trait impls
   --> $DIR/trait-item-with-defaultness-fail-semantic.rs:7:5
    |
 LL |     default const B: u8 = 0;
@@ -14,7 +14,7 @@ LL |     default const B: u8 = 0;
    |     |
    |     `default` because of this
 
-error: `default` is only allowed on items in `impl` definitions
+error: `default` is only allowed on items in trait impls
   --> $DIR/trait-item-with-defaultness-fail-semantic.rs:8:5
    |
 LL |     default type D;
@@ -22,7 +22,7 @@ LL |     default type D;
    |     |
    |     `default` because of this
 
-error: `default` is only allowed on items in `impl` definitions
+error: `default` is only allowed on items in trait impls
   --> $DIR/trait-item-with-defaultness-fail-semantic.rs:9:5
    |
 LL |     default type C: Ord;
@@ -30,7 +30,7 @@ LL |     default type C: Ord;
    |     |
    |     `default` because of this
 
-error: `default` is only allowed on items in `impl` definitions
+error: `default` is only allowed on items in trait impls
   --> $DIR/trait-item-with-defaultness-fail-semantic.rs:10:5
    |
 LL |     default fn f1();
@@ -38,7 +38,7 @@ LL |     default fn f1();
    |     |
    |     `default` because of this
 
-error: `default` is only allowed on items in `impl` definitions
+error: `default` is only allowed on items in trait impls
   --> $DIR/trait-item-with-defaultness-fail-semantic.rs:11:5
    |
 LL |     default fn f2() {}
diff --git a/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs b/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs
new file mode 100644
index 00000000000..a5e9b1db546
--- /dev/null
+++ b/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs
@@ -0,0 +1,9 @@
+// Regression test for correct pretty-printing of an AST representing `&(mut x)` in help
+// suggestion diagnostic.
+
+fn main() {
+    let mut &x = &0;
+    //~^ ERROR `mut` must be attached to each individual binding
+    //~| HELP add `mut` to each binding
+    //~| SUGGESTION &(mut x)
+}
diff --git a/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.stderr b/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.stderr
new file mode 100644
index 00000000000..75b6c163b2c
--- /dev/null
+++ b/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.stderr
@@ -0,0 +1,10 @@
+error: `mut` must be attached to each individual binding
+  --> $DIR/issue-80186-mut-binding-help-suggestion.rs:5:9
+   |
+LL |     let mut &x = &0;
+   |         ^^^^^^ help: add `mut` to each binding: `&(mut x)`
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pattern/or-pattern-macro-pat.rs b/src/test/ui/pattern/or-pattern-macro-pat.rs
new file mode 100644
index 00000000000..8749407675b
--- /dev/null
+++ b/src/test/ui/pattern/or-pattern-macro-pat.rs
@@ -0,0 +1,44 @@
+// run-pass
+// edition:2021
+// ignore-test
+// FIXME(mark-i-m): enable this test again when 2021 machinery is available
+
+#![feature(or_patterns)]
+
+use Foo::*;
+
+#[derive(Eq, PartialEq, Debug)]
+enum Foo {
+    A(u64),
+    B(u64),
+    C,
+    D,
+}
+
+macro_rules! foo {
+    ($orpat:pat, $val:expr) => {
+        match $val {
+            x @ ($orpat) => x, // leading vert would not be allowed in $orpat
+            _ => B(0xDEADBEEFu64),
+        }
+    };
+}
+
+macro_rules! bar {
+    ($orpat:pat, $val:expr) => {
+        match $val {
+            $orpat => 42, // leading vert allowed here
+            _ => 0xDEADBEEFu64,
+        }
+    };
+}
+
+fn main() {
+    // Test or-pattern.
+    let y = foo!(A(_)|B(_), A(32));
+    assert_eq!(y, A(32));
+
+    // Leading vert in or-pattern.
+    let y = bar!(|C| D, C);
+    assert_eq!(y, 42u64);
+}
diff --git a/src/test/ui/pattern/usefulness/consts-opaque.rs b/src/test/ui/pattern/usefulness/consts-opaque.rs
index f87f96e34fc..ca4fcd85bb6 100644
--- a/src/test/ui/pattern/usefulness/consts-opaque.rs
+++ b/src/test/ui/pattern/usefulness/consts-opaque.rs
@@ -25,10 +25,6 @@ enum Baz {
 impl Eq for Baz {}
 const BAZ: Baz = Baz::Baz1;
 
-type Quux = fn(usize, usize) -> usize;
-fn quux(a: usize, b: usize) -> usize { a + b }
-const QUUX: Quux = quux;
-
 fn main() {
     match FOO {
         FOO => {}
@@ -106,9 +102,44 @@ fn main() {
         //~^ ERROR unreachable pattern
     }
 
+    type Quux = fn(usize, usize) -> usize;
+    fn quux(a: usize, b: usize) -> usize { a + b }
+    const QUUX: Quux = quux;
+
     match QUUX {
         QUUX => {}
         QUUX => {}
         _ => {}
     }
+
+    #[derive(PartialEq, Eq)]
+    struct Wrap<T>(T);
+    const WRAPQUUX: Wrap<Quux> = Wrap(quux);
+
+    match WRAPQUUX {
+        WRAPQUUX => {}
+        WRAPQUUX => {}
+        Wrap(_) => {}
+    }
+
+    match WRAPQUUX {
+        Wrap(_) => {}
+        WRAPQUUX => {} // detected unreachable because we do inspect the `Wrap` layer
+        //~^ ERROR unreachable pattern
+    }
+
+    #[derive(PartialEq, Eq)]
+    enum WhoKnows<T> {
+        Yay(T),
+        Nope,
+    };
+    const WHOKNOWSQUUX: WhoKnows<Quux> = WhoKnows::Yay(quux);
+
+    match WHOKNOWSQUUX {
+        WHOKNOWSQUUX => {}
+        WhoKnows::Yay(_) => {}
+        WHOKNOWSQUUX => {} // detected unreachable because we do inspect the `WhoKnows` layer
+        //~^ ERROR unreachable pattern
+        WhoKnows::Nope => {}
+    }
 }
diff --git a/src/test/ui/pattern/usefulness/consts-opaque.stderr b/src/test/ui/pattern/usefulness/consts-opaque.stderr
index f10166d5a35..68451043cf5 100644
--- a/src/test/ui/pattern/usefulness/consts-opaque.stderr
+++ b/src/test/ui/pattern/usefulness/consts-opaque.stderr
@@ -1,11 +1,11 @@
 error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:34:9
+  --> $DIR/consts-opaque.rs:30:9
    |
 LL |         FOO => {}
    |         ^^^
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:36:9
+  --> $DIR/consts-opaque.rs:32:9
    |
 LL |         _ => {} // should not be emitting unreachable warning
    |         ^
@@ -17,19 +17,19 @@ LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:41:9
+  --> $DIR/consts-opaque.rs:37:9
    |
 LL |         FOO_REF => {}
    |         ^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:43:9
+  --> $DIR/consts-opaque.rs:39:9
    |
 LL |         Foo(_) => {} // should not be emitting unreachable warning
    |         ^^^^^^
 
 warning: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:49:9
+  --> $DIR/consts-opaque.rs:45:9
    |
 LL |         FOO_REF_REF => {}
    |         ^^^^^^^^^^^
@@ -39,13 +39,13 @@ LL |         FOO_REF_REF => {}
    = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
 
 error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:57:9
+  --> $DIR/consts-opaque.rs:53:9
    |
 LL |         BAR => {} // should not be emitting unreachable warning
    |         ^^^
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:57:9
+  --> $DIR/consts-opaque.rs:53:9
    |
 LL |         Bar => {}
    |         --- matches any value
@@ -53,7 +53,7 @@ LL |         BAR => {} // should not be emitting unreachable warning
    |         ^^^ unreachable pattern
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:60:9
+  --> $DIR/consts-opaque.rs:56:9
    |
 LL |         Bar => {}
    |         --- matches any value
@@ -62,19 +62,19 @@ LL |         _ => {}
    |         ^ unreachable pattern
 
 error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:65:9
+  --> $DIR/consts-opaque.rs:61:9
    |
 LL |         BAR => {}
    |         ^^^
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:67:9
+  --> $DIR/consts-opaque.rs:63:9
    |
 LL |         Bar => {} // should not be emitting unreachable warning
    |         ^^^
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:69:9
+  --> $DIR/consts-opaque.rs:65:9
    |
 LL |         Bar => {} // should not be emitting unreachable warning
    |         --- matches any value
@@ -83,76 +83,88 @@ LL |         _ => {}
    |         ^ unreachable pattern
 
 error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:74:9
+  --> $DIR/consts-opaque.rs:70:9
    |
 LL |         BAR => {}
    |         ^^^
 
 error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:76:9
+  --> $DIR/consts-opaque.rs:72:9
    |
 LL |         BAR => {} // should not be emitting unreachable warning
    |         ^^^
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:76:9
+  --> $DIR/consts-opaque.rs:72:9
    |
 LL |         BAR => {} // should not be emitting unreachable warning
    |         ^^^
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:79:9
+  --> $DIR/consts-opaque.rs:75:9
    |
 LL |         _ => {} // should not be emitting unreachable warning
    |         ^
 
 error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:84:9
+  --> $DIR/consts-opaque.rs:80:9
    |
 LL |         BAZ => {}
    |         ^^^
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:86:9
+  --> $DIR/consts-opaque.rs:82:9
    |
 LL |         Baz::Baz1 => {} // should not be emitting unreachable warning
    |         ^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:88:9
+  --> $DIR/consts-opaque.rs:84:9
    |
 LL |         _ => {}
    |         ^
 
 error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:94:9
+  --> $DIR/consts-opaque.rs:90:9
    |
 LL |         BAZ => {}
    |         ^^^
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:96:9
+  --> $DIR/consts-opaque.rs:92:9
    |
 LL |         _ => {}
    |         ^
 
 error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:101:9
+  --> $DIR/consts-opaque.rs:97:9
    |
 LL |         BAZ => {}
    |         ^^^
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:103:9
+  --> $DIR/consts-opaque.rs:99:9
    |
 LL |         Baz::Baz2 => {} // should not be emitting unreachable warning
    |         ^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/consts-opaque.rs:105:9
+  --> $DIR/consts-opaque.rs:101:9
    |
 LL |         _ => {} // should not be emitting unreachable warning
    |         ^
 
-error: aborting due to 22 previous errors; 1 warning emitted
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:127:9
+   |
+LL |         WRAPQUUX => {} // detected unreachable because we do inspect the `Wrap` layer
+   |         ^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:141:9
+   |
+LL |         WHOKNOWSQUUX => {} // detected unreachable because we do inspect the `WhoKnows` layer
+   |         ^^^^^^^^^^^^
+
+error: aborting due to 24 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs
index 5a44dfc28bb..ef573db8210 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs
+++ b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs
@@ -1,5 +1,6 @@
 #![feature(exclusive_range_pattern)]
 #![feature(assoc_char_consts)]
+#![allow(overlapping_range_endpoints)]
 #![deny(unreachable_patterns)]
 
 macro_rules! m {
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr
index 2e0023348e4..b1440375494 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr
+++ b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
-  --> $DIR/exhaustiveness.rs:47:8
+  --> $DIR/exhaustiveness.rs:48:8
    |
 LL |     m!(0u8, 0..255);
    |        ^^^ pattern `u8::MAX` not covered
@@ -8,7 +8,7 @@ LL |     m!(0u8, 0..255);
    = note: the matched value is of type `u8`
 
 error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
-  --> $DIR/exhaustiveness.rs:48:8
+  --> $DIR/exhaustiveness.rs:49:8
    |
 LL |     m!(0u8, 0..=254);
    |        ^^^ pattern `u8::MAX` not covered
@@ -17,7 +17,7 @@ LL |     m!(0u8, 0..=254);
    = note: the matched value is of type `u8`
 
 error[E0004]: non-exhaustive patterns: `0_u8` not covered
-  --> $DIR/exhaustiveness.rs:49:8
+  --> $DIR/exhaustiveness.rs:50:8
    |
 LL |     m!(0u8, 1..=255);
    |        ^^^ pattern `0_u8` not covered
@@ -26,7 +26,7 @@ LL |     m!(0u8, 1..=255);
    = note: the matched value is of type `u8`
 
 error[E0004]: non-exhaustive patterns: `42_u8` not covered
-  --> $DIR/exhaustiveness.rs:50:8
+  --> $DIR/exhaustiveness.rs:51:8
    |
 LL |     m!(0u8, 0..42 | 43..=255);
    |        ^^^ pattern `42_u8` not covered
@@ -35,7 +35,7 @@ LL |     m!(0u8, 0..42 | 43..=255);
    = note: the matched value is of type `u8`
 
 error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
-  --> $DIR/exhaustiveness.rs:51:8
+  --> $DIR/exhaustiveness.rs:52:8
    |
 LL |     m!(0i8, -128..127);
    |        ^^^ pattern `i8::MAX` not covered
@@ -44,7 +44,7 @@ LL |     m!(0i8, -128..127);
    = note: the matched value is of type `i8`
 
 error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
-  --> $DIR/exhaustiveness.rs:52:8
+  --> $DIR/exhaustiveness.rs:53:8
    |
 LL |     m!(0i8, -128..=126);
    |        ^^^ pattern `i8::MAX` not covered
@@ -53,7 +53,7 @@ LL |     m!(0i8, -128..=126);
    = note: the matched value is of type `i8`
 
 error[E0004]: non-exhaustive patterns: `i8::MIN` not covered
-  --> $DIR/exhaustiveness.rs:53:8
+  --> $DIR/exhaustiveness.rs:54:8
    |
 LL |     m!(0i8, -127..=127);
    |        ^^^ pattern `i8::MIN` not covered
@@ -62,7 +62,7 @@ LL |     m!(0i8, -127..=127);
    = note: the matched value is of type `i8`
 
 error[E0004]: non-exhaustive patterns: `0_i8` not covered
-  --> $DIR/exhaustiveness.rs:54:11
+  --> $DIR/exhaustiveness.rs:55:11
    |
 LL |     match 0i8 {
    |           ^^^ pattern `0_i8` not covered
@@ -71,7 +71,7 @@ LL |     match 0i8 {
    = note: the matched value is of type `i8`
 
 error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
-  --> $DIR/exhaustiveness.rs:59:8
+  --> $DIR/exhaustiveness.rs:60:8
    |
 LL |     m!(0u128, 0..=ALMOST_MAX);
    |        ^^^^^ pattern `u128::MAX` not covered
@@ -80,7 +80,7 @@ LL |     m!(0u128, 0..=ALMOST_MAX);
    = note: the matched value is of type `u128`
 
 error[E0004]: non-exhaustive patterns: `5_u128..=u128::MAX` not covered
-  --> $DIR/exhaustiveness.rs:60:8
+  --> $DIR/exhaustiveness.rs:61:8
    |
 LL |     m!(0u128, 0..=4);
    |        ^^^^^ pattern `5_u128..=u128::MAX` not covered
@@ -89,7 +89,7 @@ LL |     m!(0u128, 0..=4);
    = note: the matched value is of type `u128`
 
 error[E0004]: non-exhaustive patterns: `0_u128` not covered
-  --> $DIR/exhaustiveness.rs:61:8
+  --> $DIR/exhaustiveness.rs:62:8
    |
 LL |     m!(0u128, 1..=u128::MAX);
    |        ^^^^^ pattern `0_u128` not covered
@@ -98,7 +98,7 @@ LL |     m!(0u128, 1..=u128::MAX);
    = note: the matched value is of type `u128`
 
 error[E0004]: non-exhaustive patterns: `(126_u8..=127_u8, false)` not covered
-  --> $DIR/exhaustiveness.rs:69:11
+  --> $DIR/exhaustiveness.rs:70:11
    |
 LL |     match (0u8, true) {
    |           ^^^^^^^^^^^ pattern `(126_u8..=127_u8, false)` not covered
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs
index af720a05693..5ea92b07081 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs
+++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs
@@ -1,5 +1,5 @@
 #![feature(exclusive_range_pattern)]
-#![deny(overlapping_patterns)]
+#![deny(overlapping_range_endpoints)]
 
 macro_rules! m {
     ($s:expr, $t1:pat, $t2:pat) => {
@@ -12,27 +12,33 @@ macro_rules! m {
 }
 
 fn main() {
-    m!(0u8, 20..=30, 30..=40); //~ ERROR multiple patterns covering the same range
-    m!(0u8, 30..=40, 20..=30); //~ ERROR multiple patterns covering the same range
+    m!(0u8, 20..=30, 30..=40); //~ ERROR multiple patterns overlap on their endpoints
+    m!(0u8, 30..=40, 20..=30); //~ ERROR multiple patterns overlap on their endpoints
     m!(0u8, 20..=30, 31..=40);
     m!(0u8, 20..=30, 29..=40);
-    m!(0u8, 20.. 30, 29..=40); //~ ERROR multiple patterns covering the same range
+    m!(0u8, 20.. 30, 29..=40); //~ ERROR multiple patterns overlap on their endpoints
     m!(0u8, 20.. 30, 28..=40);
     m!(0u8, 20.. 30, 30..=40);
     m!(0u8, 20..=30, 30..=30);
-    m!(0u8, 20..=30, 30..=31); //~ ERROR multiple patterns covering the same range
+    m!(0u8, 20..=30, 30..=31); //~ ERROR multiple patterns overlap on their endpoints
     m!(0u8, 20..=30, 29..=30);
     m!(0u8, 20..=30, 20..=20);
     m!(0u8, 20..=30, 20..=21);
-    m!(0u8, 20..=30, 19..=20); //~ ERROR multiple patterns covering the same range
+    m!(0u8, 20..=30, 19..=20); //~ ERROR multiple patterns overlap on their endpoints
     m!(0u8, 20..=30, 20);
     m!(0u8, 20..=30, 25);
     m!(0u8, 20..=30, 30);
     m!(0u8, 20.. 30, 29);
-    m!(0u8, 20, 20..=30); //~ ERROR multiple patterns covering the same range
+    m!(0u8, 20, 20..=30);
     m!(0u8, 25, 20..=30);
-    m!(0u8, 30, 20..=30); //~ ERROR multiple patterns covering the same range
+    m!(0u8, 30, 20..=30);
 
+    match 0u8 {
+        0..=10 => {}
+        20..=30 => {}
+        10..=20 => {} //~ ERROR multiple patterns overlap on their endpoints
+        _ => {}
+    }
     match (0u8, true) {
         (0..=10, true) => {}
         (10..20, true) => {} // not detected
@@ -41,13 +47,13 @@ fn main() {
     }
     match (true, 0u8) {
         (true, 0..=10) => {}
-        (true, 10..20) => {} //~ ERROR multiple patterns covering the same range
+        (true, 10..20) => {} //~ ERROR multiple patterns overlap on their endpoints
         (false, 10..20) => {}
         _ => {}
     }
     match Some(0u8) {
         Some(0..=10) => {}
-        Some(10..20) => {} //~ ERROR multiple patterns covering the same range
+        Some(10..20) => {} //~ ERROR multiple patterns overlap on their endpoints
         _ => {}
     }
 }
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr
index 7bb747cdf6f..24c0419e1dd 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr
+++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr
@@ -1,80 +1,89 @@
-error: multiple patterns covering the same range
+error: multiple patterns overlap on their endpoints
   --> $DIR/overlapping_range_endpoints.rs:15:22
    |
 LL |     m!(0u8, 20..=30, 30..=40);
-   |             -------  ^^^^^^^ overlapping patterns
+   |             -------  ^^^^^^^ ... with this range
    |             |
-   |             this range overlaps on `30_u8`
+   |             this range overlaps on `30_u8`...
    |
 note: the lint level is defined here
   --> $DIR/overlapping_range_endpoints.rs:2:9
    |
-LL | #![deny(overlapping_patterns)]
-   |         ^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(overlapping_range_endpoints)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: you likely meant to write mutually exclusive ranges
 
-error: multiple patterns covering the same range
+error: multiple patterns overlap on their endpoints
   --> $DIR/overlapping_range_endpoints.rs:16:22
    |
 LL |     m!(0u8, 30..=40, 20..=30);
-   |             -------  ^^^^^^^ overlapping patterns
+   |             -------  ^^^^^^^ ... with this range
    |             |
-   |             this range overlaps on `30_u8`
+   |             this range overlaps on `30_u8`...
+   |
+   = note: you likely meant to write mutually exclusive ranges
 
-error: multiple patterns covering the same range
+error: multiple patterns overlap on their endpoints
   --> $DIR/overlapping_range_endpoints.rs:19:22
    |
 LL |     m!(0u8, 20.. 30, 29..=40);
-   |             -------  ^^^^^^^ overlapping patterns
+   |             -------  ^^^^^^^ ... with this range
    |             |
-   |             this range overlaps on `29_u8`
+   |             this range overlaps on `29_u8`...
+   |
+   = note: you likely meant to write mutually exclusive ranges
 
-error: multiple patterns covering the same range
+error: multiple patterns overlap on their endpoints
   --> $DIR/overlapping_range_endpoints.rs:23:22
    |
 LL |     m!(0u8, 20..=30, 30..=31);
-   |             -------  ^^^^^^^ overlapping patterns
+   |             -------  ^^^^^^^ ... with this range
    |             |
-   |             this range overlaps on `30_u8`
+   |             this range overlaps on `30_u8`...
+   |
+   = note: you likely meant to write mutually exclusive ranges
 
-error: multiple patterns covering the same range
+error: multiple patterns overlap on their endpoints
   --> $DIR/overlapping_range_endpoints.rs:27:22
    |
 LL |     m!(0u8, 20..=30, 19..=20);
-   |             -------  ^^^^^^^ overlapping patterns
+   |             -------  ^^^^^^^ ... with this range
    |             |
-   |             this range overlaps on `20_u8`
-
-error: multiple patterns covering the same range
-  --> $DIR/overlapping_range_endpoints.rs:32:17
+   |             this range overlaps on `20_u8`...
    |
-LL |     m!(0u8, 20, 20..=30);
-   |             --  ^^^^^^^ overlapping patterns
-   |             |
-   |             this range overlaps on `20_u8`
+   = note: you likely meant to write mutually exclusive ranges
 
-error: multiple patterns covering the same range
-  --> $DIR/overlapping_range_endpoints.rs:34:17
+error: multiple patterns overlap on their endpoints
+  --> $DIR/overlapping_range_endpoints.rs:39:9
    |
-LL |     m!(0u8, 30, 20..=30);
-   |             --  ^^^^^^^ overlapping patterns
-   |             |
-   |             this range overlaps on `30_u8`
+LL |         0..=10 => {}
+   |         ------ this range overlaps on `10_u8`...
+LL |         20..=30 => {}
+   |         ------- this range overlaps on `20_u8`...
+LL |         10..=20 => {}
+   |         ^^^^^^^ ... with this range
+   |
+   = note: you likely meant to write mutually exclusive ranges
 
-error: multiple patterns covering the same range
-  --> $DIR/overlapping_range_endpoints.rs:44:16
+error: multiple patterns overlap on their endpoints
+  --> $DIR/overlapping_range_endpoints.rs:50:16
    |
 LL |         (true, 0..=10) => {}
-   |                ------ this range overlaps on `10_u8`
+   |                ------ this range overlaps on `10_u8`...
 LL |         (true, 10..20) => {}
-   |                ^^^^^^ overlapping patterns
+   |                ^^^^^^ ... with this range
+   |
+   = note: you likely meant to write mutually exclusive ranges
 
-error: multiple patterns covering the same range
-  --> $DIR/overlapping_range_endpoints.rs:50:14
+error: multiple patterns overlap on their endpoints
+  --> $DIR/overlapping_range_endpoints.rs:56:14
    |
 LL |         Some(0..=10) => {}
-   |              ------ this range overlaps on `10_u8`
+   |              ------ this range overlaps on `10_u8`...
 LL |         Some(10..20) => {}
-   |              ^^^^^^ overlapping patterns
+   |              ^^^^^^ ... with this range
+   |
+   = note: you likely meant to write mutually exclusive ranges
 
-error: aborting due to 9 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs b/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs
index 6516925e939..fb4d59b0578 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs
+++ b/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs
@@ -1,4 +1,5 @@
 #![feature(exclusive_range_pattern)]
+#![allow(overlapping_range_endpoints)]
 #![deny(unreachable_patterns)]
 
 macro_rules! m {
diff --git a/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr b/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr
index e6878d950d6..9a02fac6a75 100644
--- a/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr
+++ b/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr
@@ -1,149 +1,149 @@
 error: unreachable pattern
-  --> $DIR/reachability.rs:16:17
+  --> $DIR/reachability.rs:17:17
    |
 LL |     m!(0u8, 42, 42);
    |                 ^^
    |
 note: the lint level is defined here
-  --> $DIR/reachability.rs:2:9
+  --> $DIR/reachability.rs:3:9
    |
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:20:22
+  --> $DIR/reachability.rs:21:22
    |
 LL |     m!(0u8, 20..=30, 20);
    |                      ^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:21:22
+  --> $DIR/reachability.rs:22:22
    |
 LL |     m!(0u8, 20..=30, 21);
    |                      ^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:22:22
+  --> $DIR/reachability.rs:23:22
    |
 LL |     m!(0u8, 20..=30, 25);
    |                      ^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:23:22
+  --> $DIR/reachability.rs:24:22
    |
 LL |     m!(0u8, 20..=30, 29);
    |                      ^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:24:22
+  --> $DIR/reachability.rs:25:22
    |
 LL |     m!(0u8, 20..=30, 30);
    |                      ^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:27:21
+  --> $DIR/reachability.rs:28:21
    |
 LL |     m!(0u8, 20..30, 20);
    |                     ^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:28:21
+  --> $DIR/reachability.rs:29:21
    |
 LL |     m!(0u8, 20..30, 21);
    |                     ^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:29:21
+  --> $DIR/reachability.rs:30:21
    |
 LL |     m!(0u8, 20..30, 25);
    |                     ^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:30:21
+  --> $DIR/reachability.rs:31:21
    |
 LL |     m!(0u8, 20..30, 29);
    |                     ^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:34:22
+  --> $DIR/reachability.rs:35:22
    |
 LL |     m!(0u8, 20..=30, 20..=30);
    |                      ^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:35:22
+  --> $DIR/reachability.rs:36:22
    |
 LL |     m!(0u8, 20.. 30, 20.. 30);
    |                      ^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:36:22
+  --> $DIR/reachability.rs:37:22
    |
 LL |     m!(0u8, 20..=30, 20.. 30);
    |                      ^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:38:22
+  --> $DIR/reachability.rs:39:22
    |
 LL |     m!(0u8, 20..=30, 21..=30);
    |                      ^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:39:22
+  --> $DIR/reachability.rs:40:22
    |
 LL |     m!(0u8, 20..=30, 20..=29);
    |                      ^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:41:24
+  --> $DIR/reachability.rs:42:24
    |
 LL |     m!('a', 'A'..='z', 'a'..='z');
    |                        ^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:48:9
+  --> $DIR/reachability.rs:49:9
    |
 LL |         5..=8 => {},
    |         ^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:54:9
+  --> $DIR/reachability.rs:55:9
    |
 LL |         5..15 => {},
    |         ^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:61:9
+  --> $DIR/reachability.rs:62:9
    |
 LL |         5..25 => {},
    |         ^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:69:9
+  --> $DIR/reachability.rs:70:9
    |
 LL |         5..25 => {},
    |         ^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:75:9
+  --> $DIR/reachability.rs:76:9
    |
 LL |         5..15 => {},
    |         ^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:82:9
+  --> $DIR/reachability.rs:83:9
    |
 LL |         '\u{D7FF}'..='\u{E000}' => {},
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:103:9
+  --> $DIR/reachability.rs:104:9
    |
 LL |         &FOO => {}
    |         ^^^^
 
 error: unreachable pattern
-  --> $DIR/reachability.rs:104:9
+  --> $DIR/reachability.rs:105:9
    |
 LL |         BAR => {}
    |         ^^^
diff --git a/src/test/ui/pattern/usefulness/issue-15129.rs b/src/test/ui/pattern/usefulness/issue-15129.rs
index ed134c175ed..d2b72a86b74 100644
--- a/src/test/ui/pattern/usefulness/issue-15129.rs
+++ b/src/test/ui/pattern/usefulness/issue-15129.rs
@@ -1,17 +1,17 @@
 pub enum T {
     T1(()),
-    T2(())
+    T2(()),
 }
 
 pub enum V {
     V1(isize),
-    V2(bool)
+    V2(bool),
 }
 
 fn main() {
     match (T::T1(()), V::V2(true)) {
-    //~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` not covered
+        //~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` and `(T2(()), V1(_))` not covered
         (T::T1(()), V::V1(i)) => (),
-        (T::T2(()), V::V2(b)) => ()
+        (T::T2(()), V::V2(b)) => (),
     }
 }
diff --git a/src/test/ui/pattern/usefulness/issue-15129.stderr b/src/test/ui/pattern/usefulness/issue-15129.stderr
index aa4434e72b5..79a77240937 100644
--- a/src/test/ui/pattern/usefulness/issue-15129.stderr
+++ b/src/test/ui/pattern/usefulness/issue-15129.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `(T1(()), V2(_))` not covered
+error[E0004]: non-exhaustive patterns: `(T1(()), V2(_))` and `(T2(()), V1(_))` not covered
   --> $DIR/issue-15129.rs:12:11
    |
 LL |     match (T::T1(()), V::V2(true)) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `(T1(()), V2(_))` not covered
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `(T1(()), V2(_))` and `(T2(()), V1(_))` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(T, V)`
diff --git a/src/test/ui/pattern/usefulness/issue-2111.rs b/src/test/ui/pattern/usefulness/issue-2111.rs
index 7e5835e8697..d27beaeffd6 100644
--- a/src/test/ui/pattern/usefulness/issue-2111.rs
+++ b/src/test/ui/pattern/usefulness/issue-2111.rs
@@ -1,12 +1,11 @@
 fn foo(a: Option<usize>, b: Option<usize>) {
-  match (a,b) {
-  //~^ ERROR: non-exhaustive patterns: `(None, None)` not covered
-    (Some(a), Some(b)) if a == b => { }
-    (Some(_), None) |
-    (None, Some(_)) => { }
-  }
+    match (a, b) {
+        //~^ ERROR: non-exhaustive patterns: `(None, None)` and `(Some(_), Some(_))` not covered
+        (Some(a), Some(b)) if a == b => {}
+        (Some(_), None) | (None, Some(_)) => {}
+    }
 }
 
 fn main() {
-  foo(None, None);
+    foo(None, None);
 }
diff --git a/src/test/ui/pattern/usefulness/issue-2111.stderr b/src/test/ui/pattern/usefulness/issue-2111.stderr
index a39a479e078..60d9b8514b7 100644
--- a/src/test/ui/pattern/usefulness/issue-2111.stderr
+++ b/src/test/ui/pattern/usefulness/issue-2111.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `(None, None)` not covered
-  --> $DIR/issue-2111.rs:2:9
+error[E0004]: non-exhaustive patterns: `(None, None)` and `(Some(_), Some(_))` not covered
+  --> $DIR/issue-2111.rs:2:11
    |
-LL |   match (a,b) {
-   |         ^^^^^ pattern `(None, None)` not covered
+LL |     match (a, b) {
+   |           ^^^^^^ patterns `(None, None)` and `(Some(_), Some(_))` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(Option<usize>, Option<usize>)`
diff --git a/src/test/ui/pattern/usefulness/issue-56379.rs b/src/test/ui/pattern/usefulness/issue-56379.rs
new file mode 100644
index 00000000000..9bccccca9c2
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-56379.rs
@@ -0,0 +1,14 @@
+enum Foo {
+    A(bool),
+    B(bool),
+    C(bool),
+}
+
+fn main() {
+    match Foo::A(true) {
+        //~^ ERROR non-exhaustive patterns: `A(false)`, `B(false)` and `C(false)` not covered
+        Foo::A(true) => {}
+        Foo::B(true) => {}
+        Foo::C(true) => {}
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/issue-56379.stderr b/src/test/ui/pattern/usefulness/issue-56379.stderr
new file mode 100644
index 00000000000..6a231b868c8
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/issue-56379.stderr
@@ -0,0 +1,22 @@
+error[E0004]: non-exhaustive patterns: `A(false)`, `B(false)` and `C(false)` not covered
+  --> $DIR/issue-56379.rs:8:11
+   |
+LL | / enum Foo {
+LL | |     A(bool),
+   | |     - not covered
+LL | |     B(bool),
+   | |     - not covered
+LL | |     C(bool),
+   | |     - not covered
+LL | | }
+   | |_- `Foo` defined here
+...
+LL |       match Foo::A(true) {
+   |             ^^^^^^^^^^^^ patterns `A(false)`, `B(false)` and `C(false)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `Foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
index a28cfb579f4..4ff12aa2ff5 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
@@ -15,7 +15,7 @@ fn main() {
                       //  and `(_, _, 5_i32..=i32::MAX)` not covered
       (_, _, 4) => {}
     }
-    match (T::A, T::A) { //~ ERROR non-exhaustive patterns: `(A, A)` not covered
+    match (T::A, T::A) { //~ ERROR non-exhaustive patterns: `(A, A)` and `(B, B)` not covered
       (T::A, T::B) => {}
       (T::B, T::A) => {}
     }
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
index 12412743b83..c953cd31440 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
@@ -45,11 +45,11 @@ LL |     match (2, 3, 4) {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(i32, i32, i32)`
 
-error[E0004]: non-exhaustive patterns: `(A, A)` not covered
+error[E0004]: non-exhaustive patterns: `(A, A)` and `(B, B)` not covered
   --> $DIR/non-exhaustive-match.rs:18:11
    |
 LL |     match (T::A, T::A) {
-   |           ^^^^^^^^^^^^ pattern `(A, A)` not covered
+   |           ^^^^^^^^^^^^ patterns `(A, A)` and `(B, B)` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `(T, T)`
diff --git a/src/test/ui/polymorphization/const_parameters/closures.stderr b/src/test/ui/polymorphization/const_parameters/closures.stderr
index 63335586b76..266b6e62afd 100644
--- a/src/test/ui/polymorphization/const_parameters/closures.stderr
+++ b/src/test/ui/polymorphization/const_parameters/closures.stderr
@@ -6,7 +6,6 @@ LL | #![feature(const_generics, rustc_attrs)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error: item has unused generic parameters
   --> $DIR/closures.rs:19:19
diff --git a/src/test/ui/polymorphization/const_parameters/functions.stderr b/src/test/ui/polymorphization/const_parameters/functions.stderr
index c976a5b62aa..e379e32c1fc 100644
--- a/src/test/ui/polymorphization/const_parameters/functions.stderr
+++ b/src/test/ui/polymorphization/const_parameters/functions.stderr
@@ -6,7 +6,6 @@ LL | #![feature(const_generics, rustc_attrs)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error: item has unused generic parameters
   --> $DIR/functions.rs:15:8
diff --git a/src/test/ui/polymorphization/generators.stderr b/src/test/ui/polymorphization/generators.stderr
index b2b32db045d..c59055ba9d6 100644
--- a/src/test/ui/polymorphization/generators.stderr
+++ b/src/test/ui/polymorphization/generators.stderr
@@ -6,7 +6,6 @@ LL | #![feature(const_generics, generators, generator_trait, rustc_attrs)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error: item has unused generic parameters
   --> $DIR/generators.rs:36:5
diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs
index 37ac45f7e05..0716cee21c6 100644
--- a/src/test/ui/print_type_sizes/niche-filling.rs
+++ b/src/test/ui/print_type_sizes/niche-filling.rs
@@ -15,12 +15,19 @@
 // padding and overall computed sizes can be quite different.
 
 #![feature(start)]
+#![feature(rustc_attrs)]
 #![allow(dead_code)]
 
 use std::num::NonZeroU32;
 
 pub enum MyOption<T> { None, Some(T) }
 
+#[rustc_layout_scalar_valid_range_start(0)]
+#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
+pub struct MyNotNegativeOne {
+  _i: i32,
+}
+
 impl<T> Default for MyOption<T> {
     fn default() -> Self { MyOption::None }
 }
@@ -77,17 +84,18 @@ fn start(_: isize, _: *const *const u8) -> isize {
     let _a: MyOption<bool> = Default::default();
     let _b: MyOption<char> = Default::default();
     let _c: MyOption<std::cmp::Ordering> = Default::default();
-    let _b: MyOption<MyOption<u8>> = Default::default();
+    let _d: MyOption<MyOption<u8>> = Default::default();
     let _e: Enum4<(), char, (), ()> = Enum4::One(());
     let _f: Enum4<(), (), bool, ()> = Enum4::One(());
     let _g: Enum4<(), (), (), MyOption<u8>> = Enum4::One(());
+    let _h: MyOption<MyNotNegativeOne> = Default::default();
 
     // Unions do not currently participate in niche filling.
-    let _h: MyOption<Union2<NonZeroU32, u32>> = Default::default();
+    let _i: MyOption<Union2<NonZeroU32, u32>> = Default::default();
 
     // ...even when theoretically possible.
-    let _i: MyOption<Union1<NonZeroU32>> = Default::default();
-    let _j: MyOption<Union2<NonZeroU32, NonZeroU32>> = Default::default();
+    let _j: MyOption<Union1<NonZeroU32>> = Default::default();
+    let _k: MyOption<Union2<NonZeroU32, NonZeroU32>> = Default::default();
 
     0
 }
diff --git a/src/test/ui/print_type_sizes/niche-filling.stdout b/src/test/ui/print_type_sizes/niche-filling.stdout
index 1894cd218ee..d1753c26ca8 100644
--- a/src/test/ui/print_type_sizes/niche-filling.stdout
+++ b/src/test/ui/print_type_sizes/niche-filling.stdout
@@ -43,6 +43,12 @@ print-type-size     variant `Three`: 0 bytes
 print-type-size         field `.0`: 0 bytes
 print-type-size     variant `Four`: 0 bytes
 print-type-size         field `.0`: 0 bytes
+print-type-size type: `MyNotNegativeOne`: 4 bytes, alignment: 4 bytes
+print-type-size     field `._i`: 4 bytes
+print-type-size type: `MyOption<MyNotNegativeOne>`: 4 bytes, alignment: 4 bytes
+print-type-size     variant `Some`: 4 bytes
+print-type-size         field `.0`: 4 bytes
+print-type-size     variant `None`: 0 bytes
 print-type-size type: `MyOption<char>`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Some`: 4 bytes
 print-type-size         field `.0`: 4 bytes
diff --git a/src/test/compile-fail/issue-46209-private-enum-variant-reexport.rs b/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.rs
index d54c9931479..d54c9931479 100644
--- a/src/test/compile-fail/issue-46209-private-enum-variant-reexport.rs
+++ b/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.rs
diff --git a/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.stderr b/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.stderr
new file mode 100644
index 00000000000..b876bab6c54
--- /dev/null
+++ b/src/test/ui/privacy/issue-46209-private-enum-variant-reexport.stderr
@@ -0,0 +1,44 @@
+error: variant `JuniorGrade` is private and cannot be re-exported
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:6:32
+   |
+LL |     pub use self::Lieutenant::{JuniorGrade, Full};
+   |                                ^^^^^^^^^^^
+...
+LL |     enum Lieutenant {
+   |     --------------- help: consider making the enum public: `pub enum Lieutenant`
+
+error: variant `Full` is private and cannot be re-exported
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:6:45
+   |
+LL |     pub use self::Lieutenant::{JuniorGrade, Full};
+   |                                             ^^^^
+
+error: enum is private and its variants cannot be re-exported
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:4:13
+   |
+LL |     pub use self::Professor::*;
+   |             ^^^^^^^^^^^^^^^^^^
+...
+LL |     enum Professor {
+   |     -------------- help: consider making the enum public: `pub enum Professor`
+
+error: enum is private and its variants cannot be re-exported
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:9:13
+   |
+LL |     pub use self::PettyOfficer::*;
+   |             ^^^^^^^^^^^^^^^^^^^^^
+...
+LL |     pub(in rank) enum PettyOfficer {
+   |     ------------------------------ help: consider making the enum public: `pub enum PettyOfficer`
+
+error: enum is private and its variants cannot be re-exported
+  --> $DIR/issue-46209-private-enum-variant-reexport.rs:11:13
+   |
+LL |     pub use self::Crewman::*;
+   |             ^^^^^^^^^^^^^^^^
+...
+LL |     crate enum Crewman {
+   |     ------------------ help: consider making the enum public: `pub enum Crewman`
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs
index 9f4f0abf324..142efb3c6cd 100644
--- a/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs
+++ b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs
@@ -17,7 +17,9 @@ fn test() {}
 #[bench] // OK, shadowed
 fn bench() {}
 
-fn non_macro_expanded_location<#[repr(C)] T>() { //~ ERROR `repr` is ambiguous
+fn non_macro_expanded_location<#[repr(C)] T>() {
+    //~^ ERROR `repr` is ambiguous
+    //~| ERROR attribute should be applied to a struct, enum, or union
     match 0u8 {
         #[repr(C)] //~ ERROR `repr` is ambiguous
         _ => {}
diff --git a/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr
index 23310f6c6f5..276ee1cfd35 100644
--- a/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr
+++ b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr
@@ -1,5 +1,5 @@
 error[E0425]: cannot find value `NonExistent` in this scope
-  --> $DIR/ambiguous-builtin-attrs.rs:30:5
+  --> $DIR/ambiguous-builtin-attrs.rs:32:5
    |
 LL |     NonExistent;
    |     ^^^^^^^^^^^ not found in this scope
@@ -47,7 +47,7 @@ LL | use builtin_attrs::*;
    = help: use `crate::repr` to refer to this attribute macro unambiguously
 
 error[E0659]: `repr` is ambiguous (built-in attribute vs any other name)
-  --> $DIR/ambiguous-builtin-attrs.rs:22:11
+  --> $DIR/ambiguous-builtin-attrs.rs:24:11
    |
 LL |         #[repr(C)]
    |           ^^^^ ambiguous name
@@ -74,7 +74,13 @@ LL | use builtin_attrs::*;
    |     ^^^^^^^^^^^^^^^^
    = help: use `crate::feature` to refer to this attribute macro unambiguously
 
-error: aborting due to 6 previous errors
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/ambiguous-builtin-attrs.rs:20:39
+   |
+LL | fn non_macro_expanded_location<#[repr(C)] T>() {
+   |                                       ^   - not a struct, enum, or union
+
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0425, E0659.
+Some errors have detailed explanations: E0425, E0517, E0659.
 For more information about an error, try `rustc --explain E0425`.
diff --git a/src/test/ui/proc-macro/capture-unglued-token.rs b/src/test/ui/proc-macro/capture-unglued-token.rs
new file mode 100644
index 00000000000..727b779776b
--- /dev/null
+++ b/src/test/ui/proc-macro/capture-unglued-token.rs
@@ -0,0 +1,20 @@
+// aux-build:test-macros.rs
+// compile-flags: -Z span-debug
+// check-pass
+
+// Tests that we properly handle parsing a nonterminal
+// where we have two consecutive angle brackets (one inside
+// the nonterminal, and one outside)
+
+#![no_std] // Don't load unnecessary hygiene information from std
+extern crate std;
+extern crate test_macros;
+
+macro_rules! trailing_angle {
+    (Option<$field:ty>) => {
+        test_macros::print_bang_consume!($field);
+    }
+}
+
+trailing_angle!(Option<Vec<u8>>);
+fn main() {}
diff --git a/src/test/ui/proc-macro/capture-unglued-token.stdout b/src/test/ui/proc-macro/capture-unglued-token.stdout
new file mode 100644
index 00000000000..7e6b540332c
--- /dev/null
+++ b/src/test/ui/proc-macro/capture-unglued-token.stdout
@@ -0,0 +1,28 @@
+PRINT-BANG INPUT (DISPLAY): Vec<u8>
+PRINT-BANG RE-COLLECTED (DISPLAY): Vec < u8 >
+PRINT-BANG INPUT (DEBUG): TokenStream [
+    Group {
+        delimiter: None,
+        stream: TokenStream [
+            Ident {
+                ident: "Vec",
+                span: $DIR/capture-unglued-token.rs:19:24: 19:27 (#0),
+            },
+            Punct {
+                ch: '<',
+                spacing: Alone,
+                span: $DIR/capture-unglued-token.rs:19:27: 19:28 (#0),
+            },
+            Ident {
+                ident: "u8",
+                span: $DIR/capture-unglued-token.rs:19:28: 19:30 (#0),
+            },
+            Punct {
+                ch: '>',
+                spacing: Alone,
+                span: $DIR/capture-unglued-token.rs:19:30: 19:31 (#0),
+            },
+        ],
+        span: $DIR/capture-unglued-token.rs:15:42: 15:48 (#4),
+    },
+]
diff --git a/src/test/ui/regions/regions-early-bound-trait-param.rs b/src/test/ui/regions/regions-early-bound-trait-param.rs
index cc2bde78d85..276a64b8e9a 100644
--- a/src/test/ui/regions/regions-early-bound-trait-param.rs
+++ b/src/test/ui/regions/regions-early-bound-trait-param.rs
@@ -117,7 +117,7 @@ pub fn main() {
     let m : Box<dyn Trait> = make_val();
     // assert_eq!(object_invoke1(&*m), (4,5));
     //            ~~~~~~~~~~~~~~~~~~~
-    // this call yields a compilation error; see compile-fail/dropck-object-cycle.rs
+    // this call yields a compilation error; see ui/span/dropck-object-cycle.rs
     // for details.
     assert_eq!(object_invoke2(&*m), 5);
 
diff --git a/src/test/ui/regions/regions-variance-contravariant-use-contravariant.rs b/src/test/ui/regions/regions-variance-contravariant-use-contravariant.rs
index f10d5a25f16..e6377867018 100644
--- a/src/test/ui/regions/regions-variance-contravariant-use-contravariant.rs
+++ b/src/test/ui/regions/regions-variance-contravariant-use-contravariant.rs
@@ -4,7 +4,7 @@
 // Test that a type which is contravariant with respect to its region
 // parameter compiles successfully when used in a contravariant way.
 //
-// Note: see compile-fail/variance-regions-*.rs for the tests that check that the
+// Note: see ui/variance/variance-regions-*.rs for the tests that check that the
 // variance inference works in the first place.
 
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/regions/regions-variance-covariant-use-covariant.rs b/src/test/ui/regions/regions-variance-covariant-use-covariant.rs
index 9316aa15d32..c5c80ce54f1 100644
--- a/src/test/ui/regions/regions-variance-covariant-use-covariant.rs
+++ b/src/test/ui/regions/regions-variance-covariant-use-covariant.rs
@@ -3,7 +3,7 @@
 // Test that a type which is covariant with respect to its region
 // parameter is successful when used in a covariant way.
 //
-// Note: see compile-fail/variance-regions-*.rs for the tests that
+// Note: see ui/variance/variance-regions-*.rs for the tests that
 // check that the variance inference works in the first place.
 
 // This is covariant with respect to 'a, meaning that
diff --git a/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr b/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr
index 5de8eb21582..7f8151db06f 100644
--- a/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr
+++ b/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr
@@ -48,7 +48,6 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 error: aborting due to 5 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/rfc-2294-if-let-guard/bindings.rs b/src/test/ui/rfc-2294-if-let-guard/bindings.rs
new file mode 100644
index 00000000000..4e2d70e3290
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/bindings.rs
@@ -0,0 +1,10 @@
+#![feature(if_let_guard)]
+#![allow(incomplete_features)]
+
+fn main() {
+    match Some(None) {
+        Some(x) if let Some(y) = x => (x, y),
+        _ => y, //~ ERROR cannot find value `y`
+    }
+    y //~ ERROR cannot find value `y`
+}
diff --git a/src/test/ui/rfc-2294-if-let-guard/bindings.stderr b/src/test/ui/rfc-2294-if-let-guard/bindings.stderr
new file mode 100644
index 00000000000..9c5d92a33ad
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/bindings.stderr
@@ -0,0 +1,15 @@
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/bindings.rs:7:14
+   |
+LL |         _ => y,
+   |              ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/bindings.rs:9:5
+   |
+LL |     y
+   |     ^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
index c0a9bbc36b2..4ba7e1eeefa 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
@@ -5,8 +5,7 @@ use std::ops::Range;
 fn _if_let_guard() {
     match () {
         () if let 0 = 1 => {}
-        //~^ ERROR `if let` guard is not implemented
-        //~| ERROR `let` expressions are not supported here
+        //~^ ERROR `if let` guards are experimental
 
         () if (let 0 = 1) => {}
         //~^ ERROR `let` expressions in this position are experimental
@@ -75,7 +74,7 @@ fn _macros() {
     match () {
         #[cfg(FALSE)]
         () if let 0 = 1 => {}
-        //~^ ERROR `if let` guard is not implemented
+        //~^ ERROR `if let` guards are experimental
         _ => {}
     }
     use_expr!(let 0 = 1);
diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
index 5c7f8190dd6..113870c19f5 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
@@ -1,5 +1,5 @@
 error: no rules expected the token `let`
-  --> $DIR/feature-gate.rs:81:15
+  --> $DIR/feature-gate.rs:80:15
    |
 LL |     macro_rules! use_expr {
    |     --------------------- when calling this macro
@@ -7,7 +7,7 @@ LL |     macro_rules! use_expr {
 LL |     use_expr!(let 0 = 1);
    |               ^^^ no rules expected this token in macro call
 
-error[E0658]: `if let` guard is not implemented
+error[E0658]: `if let` guards are experimental
   --> $DIR/feature-gate.rs:7:12
    |
 LL |         () if let 0 = 1 => {}
@@ -16,8 +16,8 @@ LL |         () if let 0 = 1 => {}
    = note: see issue #51114 <https://github.com/rust-lang/rust/issues/51114> for more information
    = help: add `#![feature(if_let_guard)]` to the crate attributes to enable
 
-error[E0658]: `if let` guard is not implemented
-  --> $DIR/feature-gate.rs:77:12
+error[E0658]: `if let` guards are experimental
+  --> $DIR/feature-gate.rs:76:12
    |
 LL |         () if let 0 = 1 => {}
    |            ^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL |         () if let 0 = 1 => {}
    = help: add `#![feature(if_let_guard)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:11:16
+  --> $DIR/feature-gate.rs:10:16
    |
 LL |         () if (let 0 = 1) => {}
    |                ^^^^^^^^^
@@ -35,7 +35,7 @@ LL |         () if (let 0 = 1) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:15:18
+  --> $DIR/feature-gate.rs:14:18
    |
 LL |         () if (((let 0 = 1))) => {}
    |                  ^^^^^^^^^
@@ -44,7 +44,7 @@ LL |         () if (((let 0 = 1))) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:19:23
+  --> $DIR/feature-gate.rs:18:23
    |
 LL |         () if true && let 0 = 1 => {}
    |                       ^^^^^^^^^
@@ -53,7 +53,7 @@ LL |         () if true && let 0 = 1 => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:23:15
+  --> $DIR/feature-gate.rs:22:15
    |
 LL |         () if let 0 = 1 && true => {}
    |               ^^^^^^^^^
@@ -62,7 +62,7 @@ LL |         () if let 0 = 1 && true => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:27:16
+  --> $DIR/feature-gate.rs:26:16
    |
 LL |         () if (let 0 = 1) && true => {}
    |                ^^^^^^^^^
@@ -71,7 +71,7 @@ LL |         () if (let 0 = 1) && true => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:31:24
+  --> $DIR/feature-gate.rs:30:24
    |
 LL |         () if true && (let 0 = 1) => {}
    |                        ^^^^^^^^^
@@ -80,7 +80,7 @@ LL |         () if true && (let 0 = 1) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:35:16
+  --> $DIR/feature-gate.rs:34:16
    |
 LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    |                ^^^^^^^^^
@@ -89,7 +89,7 @@ LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:35:31
+  --> $DIR/feature-gate.rs:34:31
    |
 LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    |                               ^^^^^^^^^
@@ -98,7 +98,7 @@ LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:41:15
+  --> $DIR/feature-gate.rs:40:15
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |               ^^^^^^^^^
@@ -107,7 +107,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:41:28
+  --> $DIR/feature-gate.rs:40:28
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                            ^^^^^^^^^
@@ -116,7 +116,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:41:42
+  --> $DIR/feature-gate.rs:40:42
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                          ^^^^^^^^^
@@ -125,7 +125,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:41:55
+  --> $DIR/feature-gate.rs:40:55
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                                       ^^^^^^^^^
@@ -134,7 +134,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:41:68
+  --> $DIR/feature-gate.rs:40:68
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                                                    ^^^^^^^^^
@@ -143,7 +143,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:53:15
+  --> $DIR/feature-gate.rs:52:15
    |
 LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -152,7 +152,7 @@ LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:69:16
+  --> $DIR/feature-gate.rs:68:16
    |
 LL |     use_expr!((let 0 = 1 && 0 == 0));
    |                ^^^^^^^^^
@@ -161,7 +161,7 @@ LL |     use_expr!((let 0 = 1 && 0 == 0));
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:72:16
+  --> $DIR/feature-gate.rs:71:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^^^^^^^
@@ -170,16 +170,7 @@ LL |     use_expr!((let 0 = 1));
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:7:15
-   |
-LL |         () if let 0 = 1 => {}
-   |               ^^^^^^^^^
-   |
-   = note: only supported directly in conditions of `if`- and `while`-expressions
-   = note: as well as when nested within `&&` and parenthesis in those conditions
-
-error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:11:16
+  --> $DIR/feature-gate.rs:10:16
    |
 LL |         () if (let 0 = 1) => {}
    |                ^^^^^^^^^
@@ -188,7 +179,7 @@ LL |         () if (let 0 = 1) => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:15:18
+  --> $DIR/feature-gate.rs:14:18
    |
 LL |         () if (((let 0 = 1))) => {}
    |                  ^^^^^^^^^
@@ -197,7 +188,7 @@ LL |         () if (((let 0 = 1))) => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:19:23
+  --> $DIR/feature-gate.rs:18:23
    |
 LL |         () if true && let 0 = 1 => {}
    |                       ^^^^^^^^^
@@ -206,7 +197,7 @@ LL |         () if true && let 0 = 1 => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:23:15
+  --> $DIR/feature-gate.rs:22:15
    |
 LL |         () if let 0 = 1 && true => {}
    |               ^^^^^^^^^
@@ -215,7 +206,7 @@ LL |         () if let 0 = 1 && true => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:27:16
+  --> $DIR/feature-gate.rs:26:16
    |
 LL |         () if (let 0 = 1) && true => {}
    |                ^^^^^^^^^
@@ -224,7 +215,7 @@ LL |         () if (let 0 = 1) && true => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:31:24
+  --> $DIR/feature-gate.rs:30:24
    |
 LL |         () if true && (let 0 = 1) => {}
    |                        ^^^^^^^^^
@@ -233,7 +224,7 @@ LL |         () if true && (let 0 = 1) => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:35:16
+  --> $DIR/feature-gate.rs:34:16
    |
 LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    |                ^^^^^^^^^
@@ -242,7 +233,7 @@ LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:35:31
+  --> $DIR/feature-gate.rs:34:31
    |
 LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    |                               ^^^^^^^^^
@@ -251,7 +242,7 @@ LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:41:15
+  --> $DIR/feature-gate.rs:40:15
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |               ^^^^^^^^^
@@ -260,7 +251,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:41:28
+  --> $DIR/feature-gate.rs:40:28
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                            ^^^^^^^^^
@@ -269,7 +260,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:41:42
+  --> $DIR/feature-gate.rs:40:42
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                          ^^^^^^^^^
@@ -278,7 +269,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:41:55
+  --> $DIR/feature-gate.rs:40:55
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                                       ^^^^^^^^^
@@ -287,7 +278,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:41:68
+  --> $DIR/feature-gate.rs:40:68
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                                                    ^^^^^^^^^
@@ -296,7 +287,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:53:15
+  --> $DIR/feature-gate.rs:52:15
    |
 LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -305,7 +296,7 @@ LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:69:16
+  --> $DIR/feature-gate.rs:68:16
    |
 LL |     use_expr!((let 0 = 1 && 0 == 0));
    |                ^^^^^^^^^
@@ -314,7 +305,7 @@ LL |     use_expr!((let 0 = 1 && 0 == 0));
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:72:16
+  --> $DIR/feature-gate.rs:71:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^^^^^^^
@@ -322,6 +313,6 @@ LL |     use_expr!((let 0 = 1));
    = note: only supported directly in conditions of `if`- and `while`-expressions
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
-error: aborting due to 36 previous errors
+error: aborting due to 35 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2294-if-let-guard/run-pass.rs b/src/test/ui/rfc-2294-if-let-guard/run-pass.rs
new file mode 100644
index 00000000000..a3663003790
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/run-pass.rs
@@ -0,0 +1,34 @@
+// run-pass
+
+#![feature(if_let_guard)]
+#![allow(incomplete_features)]
+
+enum Foo {
+    Bar,
+    Baz,
+    Qux(u8),
+}
+
+fn bar(x: bool) -> Foo {
+    if x { Foo::Baz } else { Foo::Bar }
+}
+
+fn baz(x: u8) -> Foo {
+    if x % 2 == 0 { Foo::Bar } else { Foo::Baz }
+}
+
+fn qux(x: u8) -> Foo {
+    Foo::Qux(x.rotate_left(1))
+}
+
+fn main() {
+    match Some((true, 3)) {
+        Some((x, _)) if let Foo::Bar = bar(x) => panic!(),
+        Some((_, x)) if let Foo::Baz = baz(x) => {},
+        _ => panic!(),
+    }
+    match Some(42) {
+        Some(x) if let Foo::Qux(y) = qux(x) => assert_eq!(y, 84),
+        _ => panic!(),
+    }
+}
diff --git a/src/test/ui/rfc-2294-if-let-guard/typeck.rs b/src/test/ui/rfc-2294-if-let-guard/typeck.rs
new file mode 100644
index 00000000000..a4fc7f8cf2b
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/typeck.rs
@@ -0,0 +1,16 @@
+#![feature(if_let_guard)]
+#![allow(incomplete_features)]
+
+fn ok() -> Result<Option<bool>, ()> {
+    Ok(Some(true))
+}
+
+fn main() {
+    match ok() {
+        Ok(x) if let Err(_) = x => {},
+        //~^ ERROR mismatched types
+        Ok(x) if let 0 = x => {},
+        //~^ ERROR mismatched types
+        _ => {}
+    }
+}
diff --git a/src/test/ui/rfc-2294-if-let-guard/typeck.stderr b/src/test/ui/rfc-2294-if-let-guard/typeck.stderr
new file mode 100644
index 00000000000..7ce93fe7348
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/typeck.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+  --> $DIR/typeck.rs:10:22
+   |
+LL |         Ok(x) if let Err(_) = x => {},
+   |                      ^^^^^^ expected enum `Option`, found enum `std::result::Result`
+   |
+   = note: expected enum `Option<bool>`
+              found enum `std::result::Result<_, _>`
+
+error[E0308]: mismatched types
+  --> $DIR/typeck.rs:12:22
+   |
+LL |         Ok(x) if let 0 = x => {},
+   |                      ^ expected enum `Option`, found integer
+   |
+   = note: expected enum `Option<bool>`
+              found type `{integer}`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/rfc-2294-if-let-guard/warns.rs b/src/test/ui/rfc-2294-if-let-guard/warns.rs
new file mode 100644
index 00000000000..9691a12f45b
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/warns.rs
@@ -0,0 +1,22 @@
+#![feature(if_let_guard)]
+#![allow(incomplete_features)]
+
+#[deny(irrefutable_let_patterns)]
+fn irrefutable_let_guard() {
+    match Some(()) {
+        Some(x) if let () = x => {}
+        //~^ ERROR irrefutable if-let guard
+        _ => {}
+    }
+}
+
+#[deny(unreachable_patterns)]
+fn unreachable_pattern() {
+    match Some(()) {
+        x if let None | None = x => {}
+        //~^ ERROR unreachable pattern
+        _ => {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2294-if-let-guard/warns.stderr b/src/test/ui/rfc-2294-if-let-guard/warns.stderr
new file mode 100644
index 00000000000..45720f9fbc5
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/warns.stderr
@@ -0,0 +1,26 @@
+error: irrefutable if-let guard
+  --> $DIR/warns.rs:7:24
+   |
+LL |         Some(x) if let () = x => {}
+   |                        ^^
+   |
+note: the lint level is defined here
+  --> $DIR/warns.rs:4:8
+   |
+LL | #[deny(irrefutable_let_patterns)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/warns.rs:16:25
+   |
+LL |         x if let None | None = x => {}
+   |                         ^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/warns.rs:13:8
+   |
+LL | #[deny(unreachable_patterns)]
+   |        ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index 11155038a91..861a4a80ad6 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -521,7 +521,6 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 warning: the feature `let_chains` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/disallowed-positions.rs:22:12
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.rs b/src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.rs
new file mode 100644
index 00000000000..936c90e88aa
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.rs
@@ -0,0 +1,13 @@
+#![feature(const_trait_impl)]
+#![allow(incomplete_features)]
+
+struct Foo;
+
+const impl Foo { //~ ERROR: expected identifier, found keyword
+    fn bar() {}
+}
+
+fn main() {
+     // shouldn't error here because we shouldn't have been able to recover above
+     Foo::bar();
+}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.stderr
new file mode 100644
index 00000000000..612511a4799
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-norecover.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found keyword `impl`
+  --> $DIR/const-impl-norecover.rs:6:7
+   |
+LL | const impl Foo {
+   |       ^^^^ expected identifier, found keyword
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs b/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs
new file mode 100644
index 00000000000..fd3dd2cef9d
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.rs
@@ -0,0 +1,16 @@
+#![feature(const_trait_impl)]
+#![allow(incomplete_features)]
+
+trait Foo {}
+
+const impl Foo for i32 {} //~ ERROR: expected identifier, found keyword
+
+trait Bar {}
+
+const impl<T: Foo> Bar for T {} //~ ERROR: expected identifier, found keyword
+
+const fn still_implements<T: Bar>() {}
+
+const _: () = still_implements::<i32>();
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr
new file mode 100644
index 00000000000..84fb619dc96
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-recovery.stderr
@@ -0,0 +1,24 @@
+error: expected identifier, found keyword `impl`
+  --> $DIR/const-impl-recovery.rs:6:7
+   |
+LL | const impl Foo for i32 {}
+   |       ^^^^ expected identifier, found keyword
+   |
+help: you might have meant to write a const trait impl
+   |
+LL | impl const Foo for i32 {}
+   |--    ^^^^^
+
+error: expected identifier, found keyword `impl`
+  --> $DIR/const-impl-recovery.rs:10:7
+   |
+LL | const impl<T: Foo> Bar for T {}
+   |       ^^^^ expected identifier, found keyword
+   |
+help: you might have meant to write a const trait impl
+   |
+LL | impl<T: Foo> const Bar for T {}
+   |--            ^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/simd/simd-array-type.rs b/src/test/ui/simd/simd-array-type.rs
index e84186a42ad..7d66395a3c8 100644
--- a/src/test/ui/simd/simd-array-type.rs
+++ b/src/test/ui/simd/simd-array-type.rs
@@ -3,7 +3,7 @@
 
 // pretty-expanded FIXME #23616
 
-#![feature(repr_simd, platform_intrinsics, min_const_generics)]
+#![feature(repr_simd, platform_intrinsics)]
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
diff --git a/src/test/ui/simd/simd-generics.rs b/src/test/ui/simd/simd-generics.rs
index dedca6276cd..50a4bfd9f51 100644
--- a/src/test/ui/simd/simd-generics.rs
+++ b/src/test/ui/simd/simd-generics.rs
@@ -1,6 +1,6 @@
 // run-pass
 #![allow(non_camel_case_types)]
-#![feature(repr_simd, platform_intrinsics, min_const_generics)]
+#![feature(repr_simd, platform_intrinsics)]
 
 use std::ops;
 
diff --git a/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs
index 4c459fa4bc8..c11d14b99d4 100644
--- a/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs
+++ b/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs
@@ -2,7 +2,7 @@
 // ignore-emscripten
 
 #![allow(non_camel_case_types)]
-#![feature(repr_simd, platform_intrinsics, min_const_generics)]
+#![feature(repr_simd, platform_intrinsics)]
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
diff --git a/src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs b/src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs
index 5b0ff88432e..96c2c6c5399 100644
--- a/src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs
+++ b/src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs
@@ -3,7 +3,7 @@
 
 // ignore-emscripten FIXME(#45351) hits an LLVM assert
 
-#![feature(repr_simd, platform_intrinsics, min_const_generics)]
+#![feature(repr_simd, platform_intrinsics)]
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
diff --git a/src/test/ui/similar-tokens.fixed b/src/test/ui/similar-tokens.fixed
deleted file mode 100644
index addba76ae3b..00000000000
--- a/src/test/ui/similar-tokens.fixed
+++ /dev/null
@@ -1,13 +0,0 @@
-// run-rustfix
-
-#![allow(unused_imports)]
-
-pub mod x {
-    pub struct A;
-    pub struct B;
-}
-
-// `.` is similar to `,` so list parsing should continue to closing `}`
-use x::{A, B}; //~ ERROR expected one of `,`, `::`, `as`, or `}`, found `.`
-
-fn main() {}
diff --git a/src/test/ui/similar-tokens.rs b/src/test/ui/similar-tokens.rs
index 3d1bf5fe54a..e3024c61ad2 100644
--- a/src/test/ui/similar-tokens.rs
+++ b/src/test/ui/similar-tokens.rs
@@ -1,5 +1,3 @@
-// run-rustfix
-
 #![allow(unused_imports)]
 
 pub mod x {
diff --git a/src/test/ui/similar-tokens.stderr b/src/test/ui/similar-tokens.stderr
index 6a8d09ebae6..90acfc052dd 100644
--- a/src/test/ui/similar-tokens.stderr
+++ b/src/test/ui/similar-tokens.stderr
@@ -1,5 +1,5 @@
 error: expected one of `,`, `::`, `as`, or `}`, found `.`
-  --> $DIR/similar-tokens.rs:11:10
+  --> $DIR/similar-tokens.rs:9:10
    |
 LL | use x::{A. B};
    |          ^
diff --git a/src/test/ui/span/dropck_arr_cycle_checked.rs b/src/test/ui/span/dropck_arr_cycle_checked.rs
index ac31e4910d5..a14db5ff089 100644
--- a/src/test/ui/span/dropck_arr_cycle_checked.rs
+++ b/src/test/ui/span/dropck_arr_cycle_checked.rs
@@ -1,7 +1,7 @@
 // Reject mixing cyclic structure and Drop when using fixed length
 // arrays.
 //
-// (Compare against compile-fail/dropck_vec_cycle_checked.rs)
+// (Compare against ui/span/dropck_vec_cycle_checked.rs)
 
 
 
diff --git a/src/test/ui/span/dropck_vec_cycle_checked.rs b/src/test/ui/span/dropck_vec_cycle_checked.rs
index bacd99c6825..c5d21507d76 100644
--- a/src/test/ui/span/dropck_vec_cycle_checked.rs
+++ b/src/test/ui/span/dropck_vec_cycle_checked.rs
@@ -1,6 +1,6 @@
 // Reject mixing cyclic structure and Drop when using Vec.
 //
-// (Compare against compile-fail/dropck_arr_cycle_checked.rs)
+// (Compare against ui/span/dropck_arr_cycle_checked.rs)
 
 use std::cell::Cell;
 use id::Id;
diff --git a/src/test/ui/specialization/defaultimpl/projection.rs b/src/test/ui/specialization/defaultimpl/projection.rs
index 4a914096932..f19c55b043b 100644
--- a/src/test/ui/specialization/defaultimpl/projection.rs
+++ b/src/test/ui/specialization/defaultimpl/projection.rs
@@ -4,7 +4,7 @@
 #![feature(specialization)] //~ WARN the feature `specialization` is incomplete
 
 // Make sure we *can* project non-defaulted associated types
-// cf compile-fail/specialization-default-projection.rs
+// cf ui/specialization/specialization-default-projection.rs
 
 // First, do so without any use of specialization
 
diff --git a/src/test/compile-fail/specialization/issue-50452.rs b/src/test/ui/specialization/issue-50452-fail.rs
index 958f0eb2668..fe21e9b6ede 100644
--- a/src/test/compile-fail/specialization/issue-50452.rs
+++ b/src/test/ui/specialization/issue-50452-fail.rs
@@ -1,4 +1,3 @@
-// compile-fail
 #![feature(specialization)]
 //~^ WARN the feature `specialization` is incomplete
 
diff --git a/src/test/ui/specialization/issue-50452-fail.stderr b/src/test/ui/specialization/issue-50452-fail.stderr
new file mode 100644
index 00000000000..8e7c5037eff
--- /dev/null
+++ b/src/test/ui/specialization/issue-50452-fail.stderr
@@ -0,0 +1,26 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/issue-50452-fail.rs:1:12
+   |
+LL | #![feature(specialization)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+   = help: consider using `min_specialization` instead, which is more stable and complete
+
+error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
+  --> $DIR/issue-50452-fail.rs:10:5
+   |
+LL |       fn foo() {}
+   |       ^^^^^^^^^^^ cannot specialize default item `foo`
+...
+LL | / impl<T> Foo for T {
+LL | |     fn foo() {}
+LL | | }
+   | |_- parent `impl` is here
+   |
+   = note: to specialize, `foo` in the parent `impl` must be marked `default`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0520`.
diff --git a/src/test/ui/specialization/specialization-projection.rs b/src/test/ui/specialization/specialization-projection.rs
index 700975e3b82..78afe7a9495 100644
--- a/src/test/ui/specialization/specialization-projection.rs
+++ b/src/test/ui/specialization/specialization-projection.rs
@@ -4,7 +4,7 @@
 #![feature(specialization)] //~ WARN the feature `specialization` is incomplete
 
 // Make sure we *can* project non-defaulted associated types
-// cf compile-fail/specialization-default-projection.rs
+// cf ui/specialization/specialization-default-projection.rs
 
 // First, do so without any use of specialization
 
diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.rs b/src/test/ui/stability-attribute/stability-attribute-sanity.rs
index abd603b356e..0c40f8ae1c6 100644
--- a/src/test/ui/stability-attribute/stability-attribute-sanity.rs
+++ b/src/test/ui/stability-attribute/stability-attribute-sanity.rs
@@ -63,7 +63,11 @@ fn multiple3() { }
 #[rustc_const_unstable(feature = "c", issue = "none")]
 #[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
 pub const fn multiple4() { }
-//~^ ERROR Invalid stability or deprecation version found
+//~^ ERROR Invalid stability version found
+
+#[stable(feature = "a", since = "1.0.0")]
+#[rustc_deprecated(since = "invalid", reason = "text")]
+fn invalid_deprecation_version() {} //~ ERROR Invalid deprecation version found
 
 #[rustc_deprecated(since = "a", reason = "text")]
 fn deprecated_without_unstable_or_stable() { }
diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
index 97089f7df52..ee9a93359f0 100644
--- a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
+++ b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
@@ -96,19 +96,25 @@ error[E0544]: multiple stability levels
 LL | #[rustc_const_unstable(feature = "d", issue = "none")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: Invalid stability or deprecation version found
+error: Invalid stability version found
   --> $DIR/stability-attribute-sanity.rs:65:1
    |
 LL | pub const fn multiple4() { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: Invalid deprecation version found
+  --> $DIR/stability-attribute-sanity.rs:70:1
+   |
+LL | fn invalid_deprecation_version() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0549]: rustc_deprecated attribute must be paired with either stable or unstable attribute
-  --> $DIR/stability-attribute-sanity.rs:68:1
+  --> $DIR/stability-attribute-sanity.rs:72:1
    |
 LL | #[rustc_deprecated(since = "a", reason = "text")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 18 previous errors
+error: aborting due to 19 previous errors
 
 Some errors have detailed explanations: E0539, E0541, E0546, E0550.
 For more information about an error, try `rustc --explain E0539`.
diff --git a/src/test/ui/structs-enums/discrim-explicit-23030.rs b/src/test/ui/structs-enums/discrim-explicit-23030.rs
index af7ab865e32..e17025e9e88 100644
--- a/src/test/ui/structs-enums/discrim-explicit-23030.rs
+++ b/src/test/ui/structs-enums/discrim-explicit-23030.rs
@@ -2,7 +2,7 @@
 // Issue 23030: Workaround overflowing discriminant
 // with explicit assignments.
 
-// See also compile-fail/overflow-discrim.rs, which shows what
+// See also ui/discrim/discrim-overflow.rs, which shows what
 // happens if you leave the OhNo explicit cases out here.
 
 fn f_i8() {
diff --git a/src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs b/src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs
index 1fc52ead48e..d3e92e16246 100644
--- a/src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs
+++ b/src/test/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs
@@ -27,7 +27,7 @@ fn b<'a>(t: &'a MyBox<dyn Test>, mut ss: SomeStruct<'a>) {
     ss.u = t;
 }
 
-// see also compile-fail/object-lifetime-default-from-rptr-box-error.rs
+// see also ui/object-lifetime/object-lifetime-default-from-rptr-box-error.rs
 
 fn d<'a>(t: &'a MyBox<dyn Test+'a>, mut ss: SomeStruct<'a>) {
     ss.u = t;
diff --git a/src/test/ui/suggestions/impl-trait-with-missing-bounds.rs b/src/test/ui/suggestions/impl-trait-with-missing-bounds.rs
index d401328077a..949b2360071 100644
--- a/src/test/ui/suggestions/impl-trait-with-missing-bounds.rs
+++ b/src/test/ui/suggestions/impl-trait-with-missing-bounds.rs
@@ -39,6 +39,14 @@ fn bak(constraints: impl  Iterator + std::fmt::Debug) {
     }
 }
 
+#[rustfmt::skip]
+fn baw<>(constraints: impl Iterator) {
+    for constraint in constraints {
+        qux(constraint);
+//~^ ERROR `<impl Iterator as Iterator>::Item` doesn't implement `Debug`
+    }
+}
+
 fn qux(_: impl std::fmt::Debug) {}
 
 fn main() {}
diff --git a/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr b/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr
index 099eb1c9d00..0de3b9aec19 100644
--- a/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr
+++ b/src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr
@@ -73,6 +73,21 @@ help: introduce a type parameter with a trait bound instead of using `impl Trait
 LL | fn bak<I: Iterator + std::fmt::Debug>(constraints: I) where <I as Iterator>::Item: Debug {
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^              ^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 5 previous errors
+error[E0277]: `<impl Iterator as Iterator>::Item` doesn't implement `Debug`
+  --> $DIR/impl-trait-with-missing-bounds.rs:45:13
+   |
+LL |         qux(constraint);
+   |             ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+...
+LL | fn qux(_: impl std::fmt::Debug) {}
+   |                --------------- required by this bound in `qux`
+   |
+   = help: the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
+help: introduce a type parameter with a trait bound instead of using `impl Trait`
+   |
+LL | fn baw<I: Iterator>(constraints: I) where <I as Iterator>::Item: Debug {
+   |       ^^^^^^^^^^^^^              ^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs b/src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs
new file mode 100644
index 00000000000..3cd6d336e13
--- /dev/null
+++ b/src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs
@@ -0,0 +1,32 @@
+// Regression test: if we suggest replacing an `impl Trait` argument to an async
+// fn with a named type parameter in order to add bounds, the suggested function
+// signature should be well-formed.
+//
+// edition:2018
+
+trait Foo {
+    type Bar;
+    fn bar(&self) -> Self::Bar;
+}
+
+async fn run(_: &(), foo: impl Foo) -> std::io::Result<()> {
+    let bar = foo.bar();
+    assert_is_send(&bar);
+//~^ ERROR: `<impl Foo as Foo>::Bar` cannot be sent between threads safely
+
+    Ok(())
+}
+
+// Test our handling of cases where there is a generic parameter list in the
+// source, but only synthetic generic parameters
+async fn run2< >(_: &(), foo: impl Foo) -> std::io::Result<()> {
+    let bar = foo.bar();
+    assert_is_send(&bar);
+//~^ ERROR: `<impl Foo as Foo>::Bar` cannot be sent between threads safely
+
+    Ok(())
+}
+
+fn assert_is_send<T: Send>(_: &T) {}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr b/src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr
new file mode 100644
index 00000000000..9404c3bb583
--- /dev/null
+++ b/src/test/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr
@@ -0,0 +1,33 @@
+error[E0277]: `<impl Foo as Foo>::Bar` cannot be sent between threads safely
+  --> $DIR/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs:14:20
+   |
+LL |     assert_is_send(&bar);
+   |                    ^^^^ `<impl Foo as Foo>::Bar` cannot be sent between threads safely
+...
+LL | fn assert_is_send<T: Send>(_: &T) {}
+   |                      ---- required by this bound in `assert_is_send`
+   |
+   = help: the trait `Send` is not implemented for `<impl Foo as Foo>::Bar`
+help: introduce a type parameter with a trait bound instead of using `impl Trait`
+   |
+LL | async fn run<F: Foo>(_: &(), foo: F) -> std::io::Result<()> where <F as Foo>::Bar: Send {
+   |             ^^^^^^^^              ^                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `<impl Foo as Foo>::Bar` cannot be sent between threads safely
+  --> $DIR/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs:24:20
+   |
+LL |     assert_is_send(&bar);
+   |                    ^^^^ `<impl Foo as Foo>::Bar` cannot be sent between threads safely
+...
+LL | fn assert_is_send<T: Send>(_: &T) {}
+   |                      ---- required by this bound in `assert_is_send`
+   |
+   = help: the trait `Send` is not implemented for `<impl Foo as Foo>::Bar`
+help: introduce a type parameter with a trait bound instead of using `impl Trait`
+   |
+LL | async fn run2<F: Foo>(_: &(), foo: F) -> std::io::Result<()> where <F as Foo>::Bar: Send {
+   |              ^^^^^^^^              ^                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr
index 1851c8deaa8..657914d1c8c 100644
--- a/src/test/ui/suggestions/suggest-move-lifetimes.stderr
+++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr
@@ -2,25 +2,25 @@ error: lifetime parameters must be declared prior to type parameters
   --> $DIR/suggest-move-lifetimes.rs:1:13
    |
 LL | struct A<T, 'a> {
-   |         ----^^- help: reorder the parameters: lifetimes, then types: `<'a, T>`
+   |         ----^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T>`
 
 error: lifetime parameters must be declared prior to type parameters
   --> $DIR/suggest-move-lifetimes.rs:5:13
    |
 LL | struct B<T, 'a, U> {
-   |         ----^^---- help: reorder the parameters: lifetimes, then types: `<'a, T, U>`
+   |         ----^^---- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>`
 
 error: lifetime parameters must be declared prior to type parameters
   --> $DIR/suggest-move-lifetimes.rs:10:16
    |
 LL | struct C<T, U, 'a> {
-   |         -------^^- help: reorder the parameters: lifetimes, then types: `<'a, T, U>`
+   |         -------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>`
 
 error: lifetime parameters must be declared prior to type parameters
   --> $DIR/suggest-move-lifetimes.rs:15:16
    |
 LL | struct D<T, U, 'a, 'b, V, 'c> {
-   |         -------^^--^^-----^^- help: reorder the parameters: lifetimes, then types: `<'a, 'b, 'c, T, U, V>`
+   |         -------^^--^^-----^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, 'c, T, U, V>`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/svh/auxiliary/svh-uta-base.rs b/src/test/ui/svh/auxiliary/svh-uta-base.rs
index c138f1a5ba8..221a096e083 100644
--- a/src/test/ui/svh/auxiliary/svh-uta-base.rs
+++ b/src/test/ui/svh/auxiliary/svh-uta-base.rs
@@ -1,4 +1,4 @@
-//! "compile-fail/svh-uta-trait.rs" is checking that we detect a
+//! "svh-uta-trait.rs" is checking that we detect a
 //! change from `use foo::TraitB` to use `foo::TraitB` in the hash
 //! (SVH) computation (#14132), since that will affect method
 //! resolution.
diff --git a/src/test/ui/svh/auxiliary/svh-uta-change-use-trait.rs b/src/test/ui/svh/auxiliary/svh-uta-change-use-trait.rs
index 76a472b5b26..823d29571aa 100644
--- a/src/test/ui/svh/auxiliary/svh-uta-change-use-trait.rs
+++ b/src/test/ui/svh/auxiliary/svh-uta-change-use-trait.rs
@@ -1,4 +1,4 @@
-//! "compile-fail/svh-uta-trait.rs" is checking that we detect a
+//! "svh-uta-trait.rs" is checking that we detect a
 //! change from `use foo::TraitB` to use `foo::TraitB` in the hash
 //! (SVH) computation (#14132), since that will affect method
 //! resolution.
diff --git a/src/test/ui/svh/auxiliary/svh-utb.rs b/src/test/ui/svh/auxiliary/svh-utb.rs
index 2f27e99a961..a03e29dcedc 100644
--- a/src/test/ui/svh/auxiliary/svh-utb.rs
+++ b/src/test/ui/svh/auxiliary/svh-utb.rs
@@ -1,4 +1,4 @@
-//! "compile-fail/svh-uta-trait.rs" is checking that we detect a
+//! "svh-uta-trait.rs" is checking that we detect a
 //! change from `use foo::TraitB` to use `foo::TraitB` in the hash
 //! (SVH) computation (#14132), since that will affect method
 //! resolution.
diff --git a/src/test/ui/svh/svh-use-trait.rs b/src/test/ui/svh/svh-use-trait.rs
index 93daca034c0..e5c427e096a 100644
--- a/src/test/ui/svh/svh-use-trait.rs
+++ b/src/test/ui/svh/svh-use-trait.rs
@@ -6,7 +6,7 @@
 // aux-build:svh-uta-change-use-trait.rs
 // normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2"
 
-//! "compile-fail/svh-uta-trait.rs" is checking that we detect a
+//! "svh-uta-trait.rs" is checking that we detect a
 //! change from `use foo::TraitB` to use `foo::TraitB` in the hash
 //! (SVH) computation (#14132), since that will affect method
 //! resolution.
diff --git a/src/test/ui/symbol-names/const-generics-demangling.rs b/src/test/ui/symbol-names/const-generics-demangling.rs
index e002124059f..55ab17fcd5a 100644
--- a/src/test/ui/symbol-names/const-generics-demangling.rs
+++ b/src/test/ui/symbol-names/const-generics-demangling.rs
@@ -1,7 +1,6 @@
 // build-fail
 // compile-flags: -Z symbol-mangling-version=v0
-
-#![feature(min_const_generics, rustc_attrs)]
+#![feature(rustc_attrs)]
 
 pub struct Unsigned<const F: u8>;
 
diff --git a/src/test/ui/symbol-names/const-generics-demangling.stderr b/src/test/ui/symbol-names/const-generics-demangling.stderr
index 022b3188373..a9574cacea3 100644
--- a/src/test/ui/symbol-names/const-generics-demangling.stderr
+++ b/src/test/ui/symbol-names/const-generics-demangling.stderr
@@ -1,71 +1,71 @@
 error: symbol-name(_RMCs4fqI2P2rA04_25const_generics_demanglingINtB0_8UnsignedKhb_E)
-  --> $DIR/const-generics-demangling.rs:8:1
+  --> $DIR/const-generics-demangling.rs:7:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling(<const_generics_demangling[317d481089b8c8fe]::Unsigned<11: u8>>)
-  --> $DIR/const-generics-demangling.rs:8:1
+  --> $DIR/const-generics-demangling.rs:7:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling-alt(<const_generics_demangling::Unsigned<11>>)
-  --> $DIR/const-generics-demangling.rs:8:1
+  --> $DIR/const-generics-demangling.rs:7:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: symbol-name(_RMs_Cs4fqI2P2rA04_25const_generics_demanglingINtB2_6SignedKsn98_E)
-  --> $DIR/const-generics-demangling.rs:16:1
+  --> $DIR/const-generics-demangling.rs:15:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling(<const_generics_demangling[317d481089b8c8fe]::Signed<-152: i16>>)
-  --> $DIR/const-generics-demangling.rs:16:1
+  --> $DIR/const-generics-demangling.rs:15:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling-alt(<const_generics_demangling::Signed<-152>>)
-  --> $DIR/const-generics-demangling.rs:16:1
+  --> $DIR/const-generics-demangling.rs:15:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: symbol-name(_RMs0_Cs4fqI2P2rA04_25const_generics_demanglingINtB3_4BoolKb1_E)
-  --> $DIR/const-generics-demangling.rs:24:1
+  --> $DIR/const-generics-demangling.rs:23:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling(<const_generics_demangling[317d481089b8c8fe]::Bool<true: bool>>)
-  --> $DIR/const-generics-demangling.rs:24:1
+  --> $DIR/const-generics-demangling.rs:23:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling-alt(<const_generics_demangling::Bool<true>>)
-  --> $DIR/const-generics-demangling.rs:24:1
+  --> $DIR/const-generics-demangling.rs:23:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: symbol-name(_RMs1_Cs4fqI2P2rA04_25const_generics_demanglingINtB3_4CharKc2202_E)
-  --> $DIR/const-generics-demangling.rs:32:1
+  --> $DIR/const-generics-demangling.rs:31:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling(<const_generics_demangling[317d481089b8c8fe]::Char<'∂': char>>)
-  --> $DIR/const-generics-demangling.rs:32:1
+  --> $DIR/const-generics-demangling.rs:31:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling-alt(<const_generics_demangling::Char<'∂'>>)
-  --> $DIR/const-generics-demangling.rs:32:1
+  --> $DIR/const-generics-demangling.rs:31:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/symbol-names/const-generics.rs b/src/test/ui/symbol-names/const-generics.rs
index 823995e5be3..2d136e6a99a 100644
--- a/src/test/ui/symbol-names/const-generics.rs
+++ b/src/test/ui/symbol-names/const-generics.rs
@@ -1,87 +1,85 @@
 // check-pass
 // revisions: legacy v0
 //[legacy]compile-flags: -Z symbol-mangling-version=legacy --crate-type=lib
-    //[v0]compile-flags: -Z symbol-mangling-version=v0 --crate-type=lib
+//[v0]compile-flags: -Z symbol-mangling-version=v0 --crate-type=lib
 
-    #![feature(min_const_generics)]
+// `char`
+pub struct Char<const F: char>;
 
-    // `char`
-    pub struct Char<const F: char>;
+impl Char<'A'> {
+    pub fn foo() {}
+}
 
-    impl Char<'A'> {
-        pub fn foo() {}
-    }
+impl<const F: char> Char<F> {
+    pub fn bar() {}
+}
 
-    impl<const F: char> Char<F> {
-        pub fn bar() {}
-    }
+// `i8`
+pub struct I8<const F: i8>;
 
-    // `i8`
-    pub struct I8<const F: i8>;
+impl I8<{i8::MIN}> {
+    pub fn foo() {}
+}
 
-    impl I8<{i8::MIN}> {
-        pub fn foo() {}
-    }
+impl I8<{i8::MAX}> {
+    pub fn foo() {}
+}
 
-    impl I8<{i8::MAX}> {
-        pub fn foo() {}
-    }
+impl<const F: i8> I8<F> {
+    pub fn bar() {}
+}
 
-    impl<const F: i8> I8<F> {
-        pub fn bar() {}
-    }
+// `i16`
+pub struct I16<const F: i16>;
 
-    // `i16`
-    pub struct I16<const F: i16>;
+impl I16<{i16::MIN}> {
+    pub fn foo() {}
+}
 
-    impl I16<{i16::MIN}> {
-        pub fn foo() {}
-    }
+impl<const F: i16> I16<F> {
+    pub fn bar() {}
+}
 
-    impl<const F: i16> I16<F> {
-        pub fn bar() {}
-    }
+// `i32`
+pub struct I32<const F: i32>;
 
-    // `i32`
-    pub struct I32<const F: i32>;
+impl I32<{i32::MIN}> {
+    pub fn foo() {}
+}
 
-    impl I32<{i32::MIN}> {
-        pub fn foo() {}
-    }
+impl<const F: i32> I32<F> {
+    pub fn bar() {}
+}
 
-    impl<const F: i32> I32<F> {
-        pub fn bar() {}
-    }
+// `i64`
+pub struct I64<const F: i64>;
 
-    // `i64`
-    pub struct I64<const F: i64>;
+impl I64<{i64::MIN}> {
+    pub fn foo() {}
+}
 
-    impl I64<{i64::MIN}> {
-        pub fn foo() {}
-    }
+impl<const F: i64> I64<F> {
+    pub fn bar() {}
+}
 
-    impl<const F: i64> I64<F> {
-        pub fn bar() {}
-    }
+// `i128`
+pub struct I128<const F: i128>;
 
-    // `i128`
-    pub struct I128<const F: i128>;
+impl I128<{i128::MIN}> {
+    pub fn foo() {}
+}
 
-    impl I128<{i128::MIN}> {
-        pub fn foo() {}
-    }
+impl<const F: i128> I128<F> {
+    pub fn bar() {}
+}
 
-    impl<const F: i128> I128<F> {
-        pub fn bar() {}
-    }
+// `isize`
+pub struct ISize<const F: isize>;
 
-    // `isize`
-    pub struct ISize<const F: isize>;
+impl ISize<3> {
+    pub fn foo() {}
+}
 
-    impl ISize<3> {
-        pub fn foo() {}
-    }
-
-    impl<const F: isize> ISize<F> {
-        pub fn bar() {}
-    }
+impl<const F: isize> ISize<F> {
+    pub fn bar() {}
+}
diff --git a/src/test/ui/symbol-names/issue-76365.rs b/src/test/ui/symbol-names/issue-76365.rs
index 61ba255dac0..c2e9f92f7b5 100644
--- a/src/test/ui/symbol-names/issue-76365.rs
+++ b/src/test/ui/symbol-names/issue-76365.rs
@@ -1,9 +1,8 @@
 // check-pass
 // revisions: legacy v0
 //[legacy]compile-flags: -Z symbol-mangling-version=legacy --crate-type=lib
-    //[v0]compile-flags: -Z symbol-mangling-version=v0 --crate-type=lib
+//[v0]compile-flags: -Z symbol-mangling-version=v0 --crate-type=lib
 
-#![feature(min_const_generics)]
 
 pub struct Bar<const F: bool>;
 
diff --git a/src/test/compile-fail/issue-43733-2.rs b/src/test/ui/threads-sendsync/issue-43733-2.rs
index 61dd3a923f2..21ea8e9a209 100644
--- a/src/test/compile-fail/issue-43733-2.rs
+++ b/src/test/ui/threads-sendsync/issue-43733-2.rs
@@ -1,3 +1,5 @@
+// dont-check-compiler-stderr
+
 #![feature(cfg_target_thread_local, thread_local_internals)]
 
 // On platforms *without* `#[thread_local]`, use
diff --git a/src/test/ui/issues/issue-43733.rs b/src/test/ui/threads-sendsync/issue-43733.rs
index a602d7667c4..a602d7667c4 100644
--- a/src/test/ui/issues/issue-43733.rs
+++ b/src/test/ui/threads-sendsync/issue-43733.rs
diff --git a/src/test/ui/issues/issue-43733.stderr b/src/test/ui/threads-sendsync/issue-43733.stderr
index ee6a3b065d6..ee6a3b065d6 100644
--- a/src/test/ui/issues/issue-43733.stderr
+++ b/src/test/ui/threads-sendsync/issue-43733.stderr
diff --git a/src/test/ui/traits/impl-evaluation-order.rs b/src/test/ui/traits/impl-evaluation-order.rs
new file mode 100644
index 00000000000..57809d89aa6
--- /dev/null
+++ b/src/test/ui/traits/impl-evaluation-order.rs
@@ -0,0 +1,39 @@
+// Regression test for #79902
+
+// Check that evaluation (which is used to determine whether to copy a type in
+// MIR building) evaluates bounds from normalizing an impl after evaluating
+// any bounds on the impl.
+
+// check-pass
+
+trait A {
+    type B;
+}
+trait M {}
+
+struct G<T, U>(*const T, *const U);
+
+impl<T, U> Clone for G<T, U> {
+    fn clone(&self) -> Self {
+        G { ..*self }
+    }
+}
+
+impl<T, U> Copy for G<T, U::B>
+where
+    T: A<B = U>,
+    U: A,
+{
+}
+
+impl A for () {
+    type B = ();
+}
+
+fn is_m<T: M>(_: T) {}
+
+fn main() {
+    let x = G(&(), &());
+    drop(x);
+    drop(x);
+}
diff --git a/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs b/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs
new file mode 100644
index 00000000000..3e336933937
--- /dev/null
+++ b/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.rs
@@ -0,0 +1,53 @@
+// This tests issue #79683: note in the error message that the trait is
+// explicitely unimplemented instead of suggesting to implement it.
+
+#![feature(negative_impls)]
+
+struct Qux;
+//~^ NOTE method `clone` not found for this
+//~^^ NOTE method `foo` not found for this
+
+impl !Clone for Qux {}
+
+trait Bar {
+    fn bar(&self);
+}
+
+impl !Bar for u32 {}
+
+trait Foo {
+    fn foo(&self);
+}
+//~^^^ NOTE `Foo` defines an item `foo`, perhaps you need to implement it
+
+trait FooBar {
+    fn foo(&self);
+}
+
+impl !Foo for Qux {}
+
+impl !FooBar for Qux {}
+
+impl !FooBar for u32 {}
+
+fn main() {
+    Qux.clone();
+    //~^ ERROR no method named `clone` found for struct `Qux`
+    //~| NOTE method not found in `Qux`
+    //~| NOTE `Clone` defines an item `clone`, but is explicitely unimplemented
+
+    0_u32.bar();
+    //~^ ERROR no method named `bar` found for type `u32`
+    //~| NOTE method not found in `u32`
+    //~| NOTE `Bar` defines an item `bar`, but is explicitely unimplemented
+
+    Qux.foo();
+    //~^ ERROR no method named `foo` found for struct `Qux`
+    //~| NOTE method not found in `Qux`
+    //~| NOTE the following traits define an item `foo`, but are explicitely unimplemented
+
+    0_u32.foo();
+    //~^ ERROR no method named `foo` found for type `u32`
+    //~| NOTE method not found in `u32`
+    //~| NOTE `FooBar` defines an item `foo`, but is explicitely unimplemented
+}
diff --git a/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.stderr b/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.stderr
new file mode 100644
index 00000000000..d39daaba206
--- /dev/null
+++ b/src/test/ui/traits/negative-impls/explicitly-unimplemented-error-message.stderr
@@ -0,0 +1,60 @@
+error[E0599]: no method named `clone` found for struct `Qux` in the current scope
+  --> $DIR/explicitly-unimplemented-error-message.rs:34:9
+   |
+LL | struct Qux;
+   | ----------- method `clone` not found for this
+...
+LL |     Qux.clone();
+   |         ^^^^^ method not found in `Qux`
+   | 
+  ::: $SRC_DIR/core/src/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |        -----
+   |        |
+   |        the method is available for `Arc<Qux>` here
+   |        the method is available for `Rc<Qux>` here
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the trait `Clone` defines an item `clone`, but is explicitely unimplemented
+
+error[E0599]: no method named `bar` found for type `u32` in the current scope
+  --> $DIR/explicitly-unimplemented-error-message.rs:39:11
+   |
+LL |     0_u32.bar();
+   |           ^^^ method not found in `u32`
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the trait `Bar` defines an item `bar`, but is explicitely unimplemented
+
+error[E0599]: no method named `foo` found for struct `Qux` in the current scope
+  --> $DIR/explicitly-unimplemented-error-message.rs:44:9
+   |
+LL | struct Qux;
+   | ----------- method `foo` not found for this
+...
+LL |     Qux.foo();
+   |         ^^^ method not found in `Qux`
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the following traits define an item `foo`, but are explicitely unimplemented:
+           Foo
+           FooBar
+
+error[E0599]: no method named `foo` found for type `u32` in the current scope
+  --> $DIR/explicitly-unimplemented-error-message.rs:49:11
+   |
+LL |     0_u32.foo();
+   |           ^^^ method not found in `u32`
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+note: `Foo` defines an item `foo`, perhaps you need to implement it
+  --> $DIR/explicitly-unimplemented-error-message.rs:18:1
+   |
+LL | trait Foo {
+   | ^^^^^^^^^
+   = note: the trait `FooBar` defines an item `foo`, but is explicitely unimplemented
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/traits/traits-repeated-supertrait.rs b/src/test/ui/traits/traits-repeated-supertrait.rs
index 391d19c4385..339f9c37eea 100644
--- a/src/test/ui/traits/traits-repeated-supertrait.rs
+++ b/src/test/ui/traits/traits-repeated-supertrait.rs
@@ -2,7 +2,7 @@
 // Test a case of a trait which extends the same supertrait twice, but
 // with difference type parameters. Test that we can invoke the
 // various methods in various ways successfully.
-// See also `compile-fail/trait-repeated-supertrait-ambig.rs`.
+// See also `ui/traits/trait-repeated-supertrait-ambig.rs`.
 
 
 trait CompareTo<T> {
diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr b/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr
index c5b22f0026d..e0c1b023861 100644
--- a/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr
+++ b/src/test/ui/type-alias-impl-trait/assoc-type-const.stderr
@@ -6,7 +6,6 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
    = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-   = help: consider using `min_const_generics` instead, which is more stable and complete
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/union/union-unsafe.rs b/src/test/ui/union/union-unsafe.rs
index 10f0c467560..6adf0ac59b9 100644
--- a/src/test/ui/union/union-unsafe.rs
+++ b/src/test/ui/union/union-unsafe.rs
@@ -1,4 +1,6 @@
+#![feature(untagged_unions)]
 use std::mem::ManuallyDrop;
+use std::cell::RefCell;
 
 union U1 {
     a: u8
@@ -16,9 +18,28 @@ union U4<T: Copy> {
     a: T
 }
 
+union URef {
+    p: &'static mut i32,
+}
+
+union URefCell { // field that does not drop but is not `Copy`, either
+    a: (RefCell<i32>, i32),
+}
+
+fn deref_union_field(mut u: URef) {
+    // Not an assignment but an access to the union field!
+    *(u.p) = 13; //~ ERROR access to union field is unsafe
+}
+
+fn assign_noncopy_union_field(mut u: URefCell) {
+    u.a = (RefCell::new(0), 1); //~ ERROR assignment to union field that might need dropping
+    u.a.0 = RefCell::new(0); //~ ERROR assignment to union field that might need dropping
+    u.a.1 = 1; // OK
+}
+
 fn generic_noncopy<T: Default>() {
     let mut u3 = U3 { a: ManuallyDrop::new(T::default()) };
-    u3.a = ManuallyDrop::new(T::default()); //~ ERROR assignment to non-`Copy` union field is unsafe
+    u3.a = ManuallyDrop::new(T::default()); // OK (assignment does not drop)
     *u3.a = T::default(); //~ ERROR access to union field is unsafe
 }
 
@@ -41,7 +62,7 @@ fn main() {
     // let U1 { .. } = u1; // OK
 
     let mut u2 = U2 { a: ManuallyDrop::new(String::from("old")) }; // OK
-    u2.a = ManuallyDrop::new(String::from("new")); //~ ERROR assignment to non-`Copy` union
+    u2.a = ManuallyDrop::new(String::from("new")); // OK (assignment does not drop)
     *u2.a = String::from("new"); //~ ERROR access to union field is unsafe
 
     let mut u3 = U3 { a: ManuallyDrop::new(0) }; // OK
@@ -49,6 +70,6 @@ fn main() {
     *u3.a = 1; //~ ERROR access to union field is unsafe
 
     let mut u3 = U3 { a: ManuallyDrop::new(String::from("old")) }; // OK
-    u3.a = ManuallyDrop::new(String::from("new")); //~ ERROR assignment to non-`Copy` union
+    u3.a = ManuallyDrop::new(String::from("new")); // OK (assignment does not drop)
     *u3.a = String::from("new"); //~ ERROR access to union field is unsafe
 }
diff --git a/src/test/ui/union/union-unsafe.stderr b/src/test/ui/union/union-unsafe.stderr
index b50d9e17506..a25c09144f7 100644
--- a/src/test/ui/union/union-unsafe.stderr
+++ b/src/test/ui/union/union-unsafe.stderr
@@ -1,13 +1,29 @@
-error[E0133]: assignment to non-`Copy` union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:21:5
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-unsafe.rs:31:5
+   |
+LL |     *(u.p) = 13;
+   |     ^^^^^^^^^^^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
+  --> $DIR/union-unsafe.rs:35:5
    |
-LL |     u3.a = ManuallyDrop::new(T::default());
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to non-`Copy` union field
+LL |     u.a = (RefCell::new(0), 1);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that might need dropping
+   |
+   = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
+
+error[E0133]: assignment to union field that might need dropping is unsafe and requires unsafe function or block
+  --> $DIR/union-unsafe.rs:36:5
+   |
+LL |     u.a.0 = RefCell::new(0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ assignment to union field that might need dropping
    |
    = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:22:6
+  --> $DIR/union-unsafe.rs:43:6
    |
 LL |     *u3.a = T::default();
    |      ^^^^ access to union field
@@ -15,7 +31,7 @@ LL |     *u3.a = T::default();
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:28:6
+  --> $DIR/union-unsafe.rs:49:6
    |
 LL |     *u3.a = T::default();
    |      ^^^^ access to union field
@@ -23,7 +39,7 @@ LL |     *u3.a = T::default();
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:36:13
+  --> $DIR/union-unsafe.rs:57:13
    |
 LL |     let a = u1.a;
    |             ^^^^ access to union field
@@ -31,7 +47,7 @@ LL |     let a = u1.a;
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:39:14
+  --> $DIR/union-unsafe.rs:60:14
    |
 LL |     let U1 { a } = u1;
    |              ^ access to union field
@@ -39,23 +55,15 @@ LL |     let U1 { a } = u1;
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:40:20
+  --> $DIR/union-unsafe.rs:61:20
    |
 LL |     if let U1 { a: 12 } = u1 {}
    |                    ^^ access to union field
    |
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
-error[E0133]: assignment to non-`Copy` union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:44:5
-   |
-LL |     u2.a = ManuallyDrop::new(String::from("new"));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to non-`Copy` union field
-   |
-   = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
-
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:45:6
+  --> $DIR/union-unsafe.rs:66:6
    |
 LL |     *u2.a = String::from("new");
    |      ^^^^ access to union field
@@ -63,23 +71,15 @@ LL |     *u2.a = String::from("new");
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:49:6
+  --> $DIR/union-unsafe.rs:70:6
    |
 LL |     *u3.a = 1;
    |      ^^^^ access to union field
    |
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
-error[E0133]: assignment to non-`Copy` union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:52:5
-   |
-LL |     u3.a = ManuallyDrop::new(String::from("new"));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to non-`Copy` union field
-   |
-   = note: the previous content of the field will be dropped, which causes undefined behavior if the field was not properly initialized
-
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/union-unsafe.rs:53:6
+  --> $DIR/union-unsafe.rs:74:6
    |
 LL |     *u3.a = String::from("new");
    |      ^^^^ access to union field
diff --git a/src/test/ui/unsafe-fn-called-from-unsafe-blk.rs b/src/test/ui/unsafe-fn-called-from-unsafe-blk.rs
index 38271cc3c78..3713a7065f5 100644
--- a/src/test/ui/unsafe-fn-called-from-unsafe-blk.rs
+++ b/src/test/ui/unsafe-fn-called-from-unsafe-blk.rs
@@ -2,7 +2,7 @@
 
 #![allow(dead_code)]
 //
-// See also: compile-fail/unsafe-fn-called-from-safe.rs
+// See also: ui/unsafe/unsafe-fn-called-from-safe.rs
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/unsafe-fn-called-from-unsafe-fn.rs b/src/test/ui/unsafe-fn-called-from-unsafe-fn.rs
index 26acc913e87..5e953107686 100644
--- a/src/test/ui/unsafe-fn-called-from-unsafe-fn.rs
+++ b/src/test/ui/unsafe-fn-called-from-unsafe-fn.rs
@@ -2,7 +2,7 @@
 
 #![allow(dead_code)]
 //
-// See also: compile-fail/unsafe-fn-called-from-safe.rs
+// See also: ui/unsafe/unsafe-fn-called-from-safe.rs
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs b/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
new file mode 100644
index 00000000000..8386959cfb3
--- /dev/null
+++ b/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
@@ -0,0 +1,17 @@
+// Regression test for #80468.
+
+#![crate_type = "lib"]
+
+pub trait Trait {}
+
+#[repr(transparent)]
+pub struct Wrapper<T: Trait>(T);
+
+#[repr(transparent)]
+pub struct Ref<'a>(&'a u8);
+
+impl Trait for Ref {} //~ ERROR:  implicit elided lifetime not allowed here
+
+extern "C" {
+    pub fn repro(_: Wrapper<Ref>); //~ ERROR: mismatched types
+}
diff --git a/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr b/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
new file mode 100644
index 00000000000..bb839d0a5ec
--- /dev/null
+++ b/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
@@ -0,0 +1,24 @@
+error[E0726]: implicit elided lifetime not allowed here
+  --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:13:16
+   |
+LL | impl Trait for Ref {}
+   |                ^^^- help: indicate the anonymous lifetime: `<'_>`
+
+error[E0308]: mismatched types
+  --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21
+   |
+LL |     pub fn repro(_: Wrapper<Ref>);
+   |                     ^^^^^^^^^^^^ lifetime mismatch
+   |
+   = note: expected trait `Trait`
+              found trait `Trait`
+note: the anonymous lifetime #1 defined on the method body at 16:5...
+  --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:5
+   |
+LL |     pub fn repro(_: Wrapper<Ref>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...does not necessarily outlive the static lifetime
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 0462efaa9b0..73a4cbd0792 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -299,6 +299,7 @@ impl Builder {
         let mut package = |name, targets| self.package(name, &mut manifest.pkg, targets);
         package("rustc", HOSTS);
         package("rustc-dev", HOSTS);
+        package("reproducible-artifacts", HOSTS);
         package("rustc-docs", HOSTS);
         package("cargo", HOSTS);
         package("rust-mingw", MINGW);
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject d274fcf862b89264fa2c6b917b1523070525731
+Subproject 75d5d8cffe3464631f82dcd3c470b78dc1dda8b
diff --git a/src/tools/clippy/.github/workflows/clippy.yml b/src/tools/clippy/.github/workflows/clippy.yml
index cf4aa39e49b..530e60001f7 100644
--- a/src/tools/clippy/.github/workflows/clippy.yml
+++ b/src/tools/clippy/.github/workflows/clippy.yml
@@ -35,29 +35,11 @@ jobs:
       with:
         github_token: "${{ secrets.github_token }}"
 
-    - name: rust-toolchain
-      uses: actions-rs/toolchain@v1.0.6
-      with:
-        toolchain: nightly
-        target: x86_64-unknown-linux-gnu
-        profile: minimal
-
     - name: Checkout
       uses: actions/checkout@v2.3.3
 
-    - name: Run cargo update
-      run: cargo update
-
-    - name: Cache cargo dir
-      uses: actions/cache@v2
-      with:
-        path: ~/.cargo
-        key: ${{ runner.os }}-x86_64-unknown-linux-gnu-${{ hashFiles('Cargo.lock') }}
-        restore-keys: |
-          ${{ runner.os }}-x86_64-unknown-linux-gnu
-
-    - name: Master Toolchain Setup
-      run: bash setup-toolchain.sh
+    - name: Install toolchain
+      run: rustup show active-toolchain
 
     # Run
     - name: Set LD_LIBRARY_PATH (Linux)
@@ -66,13 +48,13 @@ jobs:
         echo "LD_LIBRARY_PATH=${SYSROOT}/lib${LD_LIBRARY_PATH+:${LD_LIBRARY_PATH}}" >> $GITHUB_ENV
 
     - name: Build
-      run: cargo build --features deny-warnings
+      run: cargo build --features deny-warnings,internal-lints
 
     - name: Test
-      run: cargo test --features deny-warnings
+      run: cargo test --features deny-warnings,internal-lints
 
     - name: Test clippy_lints
-      run: cargo test --features deny-warnings
+      run: cargo test --features deny-warnings,internal-lints
       working-directory: clippy_lints
 
     - name: Test rustc_tools_util
@@ -98,9 +80,3 @@ jobs:
         cargo dev new_lint --name new_late_pass --pass late
         cargo check
         git reset --hard HEAD
-
-    # Cleanup
-    - name: Run cargo-cache --autoclean
-      run: |
-        cargo +nightly install cargo-cache --no-default-features --features ci-autoclean cargo-cache
-        cargo cache
diff --git a/src/tools/clippy/.github/workflows/clippy_bors.yml b/src/tools/clippy/.github/workflows/clippy_bors.yml
index 784463fe0df..5d846eb64c7 100644
--- a/src/tools/clippy/.github/workflows/clippy_bors.yml
+++ b/src/tools/clippy/.github/workflows/clippy_bors.yml
@@ -23,6 +23,7 @@ jobs:
     - uses: rust-lang/simpleinfra/github-actions/cancel-outdated-builds@master
       with:
         github_token: "${{ secrets.github_token }}"
+
     - name: Checkout
       uses: actions/checkout@v2.3.3
       with:
@@ -84,31 +85,11 @@ jobs:
         sudo apt-get install gcc-multilib libssl-dev:i386 libgit2-dev:i386
       if: matrix.host == 'i686-unknown-linux-gnu'
 
-    - name: rust-toolchain
-      uses: actions-rs/toolchain@v1.0.6
-      with:
-        toolchain: nightly
-        target: ${{ matrix.host }}
-        profile: minimal
-
     - name: Checkout
       uses: actions/checkout@v2.3.3
 
-    - name: Run cargo update
-      run: cargo update
-
-    - name: Cache cargo dir
-      uses: actions/cache@v2
-      with:
-        path: ~/.cargo
-        key: ${{ runner.os }}-${{ matrix.host }}-${{ hashFiles('Cargo.lock') }}
-        restore-keys: |
-          ${{ runner.os }}-${{ matrix.host }}
-
-    - name: Master Toolchain Setup
-      run: bash setup-toolchain.sh
-      env:
-        HOST_TOOLCHAIN: ${{ matrix.host }}
+    - name: Install toolchain
+      run: rustup show active-toolchain
 
     # Run
     - name: Set LD_LIBRARY_PATH (Linux)
@@ -128,13 +109,13 @@ jobs:
         SYSROOT=$(rustc --print sysroot)
         echo "$SYSROOT/bin" >> $GITHUB_PATH
 
-    - name: Build with internal lints
+    - name: Build
       run: cargo build --features deny-warnings,internal-lints
 
-    - name: Test with internal lints
+    - name: Test
       run: cargo test --features deny-warnings,internal-lints
 
-    - name: Test clippy_lints with internal lints
+    - name: Test clippy_lints
       run: cargo test --features deny-warnings,internal-lints
       working-directory: clippy_lints
 
@@ -155,12 +136,6 @@ jobs:
       env:
         OS: ${{ runner.os }}
 
-    # Cleanup
-    - name: Run cargo-cache --autoclean
-      run: |
-        cargo +nightly install cargo-cache --no-default-features --features ci-autoclean cargo-cache
-        cargo cache
-
   integration_build:
     needs: changelog
     runs-on: ubuntu-latest
@@ -171,29 +146,11 @@ jobs:
       with:
         github_token: "${{ secrets.github_token }}"
 
-    - name: rust-toolchain
-      uses: actions-rs/toolchain@v1.0.6
-      with:
-        toolchain: nightly
-        target: x86_64-unknown-linux-gnu
-        profile: minimal
-
     - name: Checkout
       uses: actions/checkout@v2.3.3
 
-    - name: Run cargo update
-      run: cargo update
-
-    - name: Cache cargo dir
-      uses: actions/cache@v2
-      with:
-        path: ~/.cargo
-        key: ${{ runner.os }}-x86_64-unknown-linux-gnu-${{ hashFiles('Cargo.lock') }}
-        restore-keys: |
-          ${{ runner.os }}-x86_64-unknown-linux-gnu
-
-    - name: Master Toolchain Setup
-      run: bash setup-toolchain.sh
+    - name: Install toolchain
+      run: rustup show active-toolchain
 
     # Run
     - name: Build Integration Test
@@ -214,11 +171,6 @@ jobs:
         name: target
         path: target
 
-    # Cleanup
-    - name: Run cargo-cache --autoclean
-      run: |
-        cargo +nightly install cargo-cache --no-default-features --features ci-autoclean cargo-cache
-        cargo cache
   integration:
     needs: integration_build
     strategy:
@@ -252,29 +204,11 @@ jobs:
       with:
         github_token: "${{ secrets.github_token }}"
 
-    - name: rust-toolchain
-      uses: actions-rs/toolchain@v1.0.6
-      with:
-        toolchain: nightly
-        target: x86_64-unknown-linux-gnu
-        profile: minimal
-
     - name: Checkout
       uses: actions/checkout@v2.3.3
 
-    - name: Run cargo update
-      run: cargo update
-
-    - name: Cache cargo dir
-      uses: actions/cache@v2
-      with:
-        path: ~/.cargo
-        key: ${{ runner.os }}-x86_64-unknown-linux-gnu-${{ hashFiles('Cargo.lock') }}
-        restore-keys: |
-          ${{ runner.os }}-x86_64-unknown-linux-gnu
-
-    - name: Master Toolchain Setup
-      run: bash setup-toolchain.sh
+    - name: Install toolchain
+      run: rustup show active-toolchain
 
     # Download
     - name: Download target dir
@@ -288,16 +222,11 @@ jobs:
 
     # Run
     - name: Test ${{ matrix.integration }}
-      run: $CARGO_TARGET_DIR/debug/integration
+      run: |
+        RUSTUP_TOOLCHAIN="$(rustup show active-toolchain | grep -o -E "nightly-[0-9]{4}-[0-9]{2}-[0-9]{2}")" \
+          $CARGO_TARGET_DIR/debug/integration
       env:
         INTEGRATION: ${{ matrix.integration }}
-        RUSTUP_TOOLCHAIN: master
-
-    # Cleanup
-    - name: Run cargo-cache --autoclean
-      run: |
-        cargo +nightly install cargo-cache --no-default-features --features ci-autoclean cargo-cache
-        cargo cache
 
   # These jobs doesn't actually test anything, but they're only used to tell
   # bors the build completed, as there is no practical way to detect when a
diff --git a/src/tools/clippy/.github/workflows/clippy_dev.yml b/src/tools/clippy/.github/workflows/clippy_dev.yml
index 5ee157cf23b..95da775b7bc 100644
--- a/src/tools/clippy/.github/workflows/clippy_dev.yml
+++ b/src/tools/clippy/.github/workflows/clippy_dev.yml
@@ -22,6 +22,12 @@ jobs:
 
     steps:
     # Setup
+    - name: Checkout
+      uses: actions/checkout@v2.3.3
+
+    - name: remove toolchain file
+      run: rm rust-toolchain
+
     - name: rust-toolchain
       uses: actions-rs/toolchain@v1.0.6
       with:
@@ -29,9 +35,7 @@ jobs:
         target: x86_64-unknown-linux-gnu
         profile: minimal
         components: rustfmt
-
-    - name: Checkout
-      uses: actions/checkout@v2.3.3
+        default: true
 
     # Run
     - name: Build
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index c7e02aaf4e1..af3b1c1db2a 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -2006,6 +2006,7 @@ Released 2018-09-13
 [`possible_missing_comma`]: https://rust-lang.github.io/rust-clippy/master/index.html#possible_missing_comma
 [`precedence`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence
 [`print_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_literal
+[`print_stderr`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr
 [`print_stdout`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout
 [`print_with_newline`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_with_newline
 [`println_empty_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#println_empty_string
@@ -2024,6 +2025,7 @@ Released 2018-09-13
 [`redundant_closure`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
 [`redundant_closure_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_call
 [`redundant_closure_for_method_calls`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_for_method_calls
+[`redundant_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_else
 [`redundant_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names
 [`redundant_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern
 [`redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern_matching
@@ -2169,5 +2171,6 @@ Released 2018-09-13
 [`zero_divided_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_divided_by_zero
 [`zero_prefixed_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_prefixed_literal
 [`zero_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_ptr
+[`zero_sized_map_values`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_sized_map_values
 [`zst_offset`]: https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset
 <!-- end autogenerated links to lint list -->
diff --git a/src/tools/clippy/CONTRIBUTING.md b/src/tools/clippy/CONTRIBUTING.md
index f8c26e2d456..4cfeaa153a0 100644
--- a/src/tools/clippy/CONTRIBUTING.md
+++ b/src/tools/clippy/CONTRIBUTING.md
@@ -19,10 +19,10 @@ All contributors are expected to follow the [Rust Code of Conduct].
   - [Writing code](#writing-code)
   - [Getting code-completion for rustc internals to work](#getting-code-completion-for-rustc-internals-to-work)
   - [How Clippy works](#how-clippy-works)
-  - [Fixing build failures caused by Rust](#fixing-build-failures-caused-by-rust)
+  - [Syncing changes between Clippy and `rust-lang/rust`](#syncing-changes-between-clippy-and-rust-langrust)
     - [Patching git-subtree to work with big repos](#patching-git-subtree-to-work-with-big-repos)
-    - [Performing the sync](#performing-the-sync)
-    - [Syncing back changes in Clippy to [`rust-lang/rust`]](#syncing-back-changes-in-clippy-to-rust-langrust)
+    - [Performing the sync from `rust-lang/rust` to Clippy](#performing-the-sync-from-rust-langrust-to-clippy)
+    - [Performing the sync from Clippy to `rust-lang/rust`](#performing-the-sync-from-clippy-to-rust-langrust)
     - [Defining remotes](#defining-remotes)
   - [Issue and PR triage](#issue-and-pr-triage)
   - [Bors and Homu](#bors-and-homu)
@@ -49,7 +49,7 @@ first read the [Basics docs](doc/basics.md).**
 All issues on Clippy are mentored, if you want help with a bug just ask
 @Manishearth, @flip1995, @phansch or @yaahc.
 
-Some issues are easier than others. The [`good first issue`] label can be used to find the easy issues.
+Some issues are easier than others. The [`good-first-issue`] label can be used to find the easy issues.
 If you want to work on an issue, please leave a comment so that we can assign it to you!
 
 There are also some abandoned PRs, marked with [`S-inactive-closed`].
@@ -68,16 +68,16 @@ To figure out how this syntax structure is encoded in the AST, it is recommended
 Usually the lint will end up to be a nested series of matches and ifs, [like so][deep-nesting].
 But we can make it nest-less by using [if_chain] macro, [like this][nest-less].
 
-[`E-medium`] issues are generally pretty easy too, though it's recommended you work on an [`good first issue`]
+[`E-medium`] issues are generally pretty easy too, though it's recommended you work on an [`good-first-issue`]
 first. Sometimes they are only somewhat involved code wise, but not difficult per-se.
-Note that [`E-medium`] issues may require some knowledge of Clippy internals or some 
-debugging to find the actual problem behind the issue. 
+Note that [`E-medium`] issues may require some knowledge of Clippy internals or some
+debugging to find the actual problem behind the issue.
 
 [`T-middle`] issues can be more involved and require verifying types. The [`ty`] module contains a
 lot of methods that are useful, though one of the most useful would be `expr_ty` (gives the type of
 an AST expression). `match_def_path()` in Clippy's `utils` module can also be useful.
 
-[`good first issue`]: https://github.com/rust-lang/rust-clippy/labels/good%20first%20issue
+[`good-first-issue`]: https://github.com/rust-lang/rust-clippy/labels/good-first-issue
 [`S-inactive-closed`]: https://github.com/rust-lang/rust-clippy/pulls?q=is%3Aclosed+label%3AS-inactive-closed
 [`T-AST`]: https://github.com/rust-lang/rust-clippy/labels/T-AST
 [`T-middle`]: https://github.com/rust-lang/rust-clippy/labels/T-middle
@@ -111,7 +111,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 rust-analyzer will be able to understand.
-Run `cargo dev ra-setup --repo-path <repo-path>` where `<repo-path>` is an absolute path to the rustc repo
+Run `cargo dev ra_setup --repo-path <repo-path>` where `<repo-path>` is an absolute 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 rust-analyzer to understand most of the types that Clippy uses.
@@ -182,18 +182,26 @@ That's why the `else_if_without_else` example uses the `register_early_pass` fun
 [early_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html
 [late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html
 
-## Fixing build failures caused by Rust
+## Syncing changes between Clippy and [`rust-lang/rust`]
 
-Clippy currently gets built with `rustc` of the `rust-lang/rust` `master`
-branch. Most of the times we have to adapt to the changes and only very rarely
-there's an actual bug in Rust.
+Clippy currently gets built with a pinned nightly version.
 
-If you decide to make Clippy work again with a Rust commit that breaks it, you
-have to sync the `rust-lang/rust-clippy` repository with the `subtree` copy of
-Clippy in the `rust-lang/rust` repository.
+In the `rust-lang/rust` repository, where rustc resides, there's a copy of Clippy
+that compiler hackers modify from time to time to adapt to changes in the unstable
+API of the compiler.
 
-For general information about `subtree`s in the Rust repository see [Rust's
-`CONTRIBUTING.md`][subtree].
+We need to sync these changes back to this repository periodically, and the changes
+made to this repository in the meantime also need to be synced to the `rust-lang/rust` repository.
+
+To avoid flooding the `rust-lang/rust` PR queue, this two-way sync process is done
+in a bi-weekly basis if there's no urgent changes. This is done starting on the day of
+the Rust stable release and then every other week. That way we guarantee that we keep
+this repo up to date with the latest compiler API, and every feature in Clippy is available
+for 2 weeks in nightly, before it can get to beta. For reference, the first sync
+following this cadence was performed the 2020-08-27.
+
+This process is described in detail in the following sections. For general information
+about `subtree`s in the Rust repository see [Rust's `CONTRIBUTING.md`][subtree].
 
 ### Patching git-subtree to work with big repos
 
@@ -222,13 +230,14 @@ This shell has a hardcoded recursion limit set to 1000. In order to make this pr
 you need to force the script to run `bash` instead. You can do this by editing the first
 line of the `git-subtree` script and changing `sh` to `bash`.
 
-### Performing the sync
+### Performing the sync from [`rust-lang/rust`] to Clippy
 
 Here is a TL;DR version of the sync process (all of the following commands have
 to be run inside the `rust` directory):
 
-1. Clone the [`rust-lang/rust`] repository
-2. Sync the changes to the rust-copy of Clippy to your Clippy fork:
+1. Clone the [`rust-lang/rust`] repository or make sure it is up to date.
+2. Checkout the commit from the latest available nightly. You can get it using `rustup check`.
+3. Sync the changes to the rust-copy of Clippy to your Clippy fork:
     ```bash
     # Make sure to change `your-github-name` to your github name in the following command
     git subtree push -P src/tools/clippy git@github.com:your-github-name/rust-clippy sync-from-rust
@@ -246,17 +255,11 @@ to be run inside the `rust` directory):
     git checkout sync-from-rust
     git merge upstream/master
     ```
-3. Open a PR to `rust-lang/rust-clippy` and wait for it to get merged (to
+4. Open a PR to `rust-lang/rust-clippy` and wait for it to get merged (to
    accelerate the process ping the `@rust-lang/clippy` team in your PR and/or
    ~~annoy~~ ask them in the [Zulip] stream.)
-   
-### Syncing back changes in Clippy to [`rust-lang/rust`]
 
-To avoid flooding the [`rust-lang/rust`] PR queue, changes in Clippy's repo are synced back
-in a bi-weekly basis if there's no urgent changes. This is done starting on the day of
-the Rust stable release and then every other week. That way we guarantee that
-every feature in Clippy is available for 2 weeks in nightly, before it can get to beta.
-For reference, the first sync following this cadence was performed the 2020-08-27.
+### Performing the sync from Clippy to [`rust-lang/rust`]
 
 All of the following commands have to be run inside the `rust` directory.
 
diff --git a/src/tools/clippy/README.md b/src/tools/clippy/README.md
index fddf0614a0b..aaa55e11c7d 100644
--- a/src/tools/clippy/README.md
+++ b/src/tools/clippy/README.md
@@ -82,6 +82,22 @@ Note that this is still experimental and only supported on the nightly channel:
 cargo clippy --fix -Z unstable-options
 ```
 
+#### Workspaces
+
+All the usual workspace options should work with Clippy. For example the following command
+will run Clippy on the `example` crate:
+
+```terminal
+cargo clippy -p example
+```
+
+As with `cargo check`, this includes dependencies that are members of the workspace, like path dependencies.
+If you want to run Clippy **only** on the given crate, use the `--no-deps` option like this:
+
+```terminal
+cargo clippy -p example -- --no-deps 
+```
+
 ### Running Clippy from the command line without installing it
 
 To have cargo compile your crate with Clippy without Clippy installation
diff --git a/src/tools/clippy/clippy_dev/src/bless.rs b/src/tools/clippy/clippy_dev/src/bless.rs
new file mode 100644
index 00000000000..645098e4cfc
--- /dev/null
+++ b/src/tools/clippy/clippy_dev/src/bless.rs
@@ -0,0 +1,74 @@
+//! `bless` updates the reference files in the repo with changed output files
+//! from the last test run.
+
+use std::env;
+use std::ffi::OsStr;
+use std::fs;
+use std::lazy::SyncLazy;
+use std::path::PathBuf;
+use walkdir::WalkDir;
+
+use crate::clippy_project_root;
+
+// NOTE: this is duplicated with tests/cargo/mod.rs What to do?
+pub static CARGO_TARGET_DIR: SyncLazy<PathBuf> = SyncLazy::new(|| match env::var_os("CARGO_TARGET_DIR") {
+    Some(v) => v.into(),
+    None => env::current_dir().unwrap().join("target"),
+});
+
+pub fn bless() {
+    let test_dirs = [
+        clippy_project_root().join("tests").join("ui"),
+        clippy_project_root().join("tests").join("ui-toml"),
+        clippy_project_root().join("tests").join("ui-cargo"),
+    ];
+    for test_dir in &test_dirs {
+        WalkDir::new(test_dir)
+            .into_iter()
+            .filter_map(Result::ok)
+            .filter(|f| f.path().extension() == Some(OsStr::new("rs")))
+            .for_each(|f| {
+                update_reference_file(f.path().with_extension("stdout"));
+                update_reference_file(f.path().with_extension("stderr"));
+                update_reference_file(f.path().with_extension("fixed"));
+            });
+    }
+}
+
+fn update_reference_file(reference_file_path: PathBuf) {
+    let test_output_path = build_dir().join(PathBuf::from(reference_file_path.file_name().unwrap()));
+    let relative_reference_file_path = reference_file_path.strip_prefix(clippy_project_root()).unwrap();
+
+    // If compiletest did not write any changes during the test run,
+    // we don't have to update anything
+    if !test_output_path.exists() {
+        return;
+    }
+
+    let test_output_file = fs::read(&test_output_path).expect("Unable to read test output file");
+    let reference_file = fs::read(&reference_file_path).unwrap_or_default();
+
+    if test_output_file != reference_file {
+        // If a test run caused an output file to change, update the reference file
+        println!("updating {}", &relative_reference_file_path.display());
+        fs::copy(test_output_path, &reference_file_path).expect("Could not update reference file");
+
+        // We need to re-read the file now because it was potentially updated from copying
+        let reference_file = fs::read(&reference_file_path).unwrap_or_default();
+
+        if reference_file.is_empty() {
+            // If we copied over an empty output file, we remove the now empty reference file
+            println!("removing {}", &relative_reference_file_path.display());
+            fs::remove_file(reference_file_path).expect("Could not remove reference file");
+        }
+    }
+}
+
+fn build_dir() -> PathBuf {
+    let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
+    let mut path = PathBuf::new();
+    path.push(CARGO_TARGET_DIR.clone());
+    path.push(profile);
+    path.push("test_build_base");
+    path
+}
diff --git a/src/tools/clippy/clippy_dev/src/fmt.rs b/src/tools/clippy/clippy_dev/src/fmt.rs
index 6ae3f58c1f2..6b528d219df 100644
--- a/src/tools/clippy/clippy_dev/src/fmt.rs
+++ b/src/tools/clippy/clippy_dev/src/fmt.rs
@@ -1,9 +1,9 @@
 use crate::clippy_project_root;
 use shell_escape::escape;
 use std::ffi::OsStr;
-use std::io;
 use std::path::Path;
 use std::process::{self, Command};
+use std::{fs, io};
 use walkdir::WalkDir;
 
 #[derive(Debug)]
@@ -12,6 +12,7 @@ pub enum CliError {
     IoError(io::Error),
     RustfmtNotInstalled,
     WalkDirError(walkdir::Error),
+    RaSetupActive,
 }
 
 impl From<io::Error> for CliError {
@@ -31,12 +32,23 @@ struct FmtContext {
     verbose: bool,
 }
 
+// the "main" function of cargo dev fmt
 pub fn run(check: bool, verbose: bool) {
     fn try_run(context: &FmtContext) -> Result<bool, CliError> {
         let mut success = true;
 
         let project_root = clippy_project_root();
 
+        // if we added a local rustc repo as path dependency to clippy for rust analyzer, we do NOT want to
+        // format because rustfmt would also format the entire rustc repo as it is a local
+        // dependency
+        if fs::read_to_string(project_root.join("Cargo.toml"))
+            .expect("Failed to read clippy Cargo.toml")
+            .contains(&"[target.'cfg(NOT_A_PLATFORM)'.dependencies]")
+        {
+            return Err(CliError::RaSetupActive);
+        }
+
         rustfmt_test(context)?;
 
         success &= cargo_fmt(context, project_root.as_path())?;
@@ -75,6 +87,13 @@ pub fn run(check: bool, verbose: bool) {
             CliError::WalkDirError(err) => {
                 eprintln!("error: {}", err);
             },
+            CliError::RaSetupActive => {
+                eprintln!(
+                    "error: a local rustc repo is enabled as path dependency via `cargo dev ra_setup`.
+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/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs
index f51c45e9eb5..17cc08ee10f 100644
--- a/src/tools/clippy/clippy_dev/src/lib.rs
+++ b/src/tools/clippy/clippy_dev/src/lib.rs
@@ -10,6 +10,7 @@ use std::lazy::SyncLazy;
 use std::path::{Path, PathBuf};
 use walkdir::WalkDir;
 
+pub mod bless;
 pub mod fmt;
 pub mod new_lint;
 pub mod ra_setup;
diff --git a/src/tools/clippy/clippy_dev/src/main.rs b/src/tools/clippy/clippy_dev/src/main.rs
index 7a8cbd5251d..4fdae38e3ab 100644
--- a/src/tools/clippy/clippy_dev/src/main.rs
+++ b/src/tools/clippy/clippy_dev/src/main.rs
@@ -1,10 +1,53 @@
 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
 
-use clap::{App, Arg, SubCommand};
-use clippy_dev::{fmt, new_lint, ra_setup, serve, stderr_length_check, update_lints};
+use clap::{App, Arg, ArgMatches, SubCommand};
+use clippy_dev::{bless, fmt, new_lint, ra_setup, serve, stderr_length_check, update_lints};
 
 fn main() {
-    let matches = App::new("Clippy developer tooling")
+    let matches = get_clap_config();
+
+    match matches.subcommand() {
+        ("bless", Some(_)) => {
+            bless::bless();
+        },
+        ("fmt", Some(matches)) => {
+            fmt::run(matches.is_present("check"), matches.is_present("verbose"));
+        },
+        ("update_lints", Some(matches)) => {
+            if matches.is_present("print-only") {
+                update_lints::print_lints();
+            } else if matches.is_present("check") {
+                update_lints::run(update_lints::UpdateMode::Check);
+            } else {
+                update_lints::run(update_lints::UpdateMode::Change);
+            }
+        },
+        ("new_lint", Some(matches)) => {
+            match new_lint::create(
+                matches.value_of("pass"),
+                matches.value_of("name"),
+                matches.value_of("category"),
+            ) {
+                Ok(_) => update_lints::run(update_lints::UpdateMode::Change),
+                Err(e) => eprintln!("Unable to create lint: {}", e),
+            }
+        },
+        ("limit_stderr_length", _) => {
+            stderr_length_check::check();
+        },
+        ("ra_setup", Some(matches)) => ra_setup::run(matches.value_of("rustc-repo-path")),
+        ("serve", Some(matches)) => {
+            let port = matches.value_of("port").unwrap().parse().unwrap();
+            let lint = matches.value_of("lint");
+            serve::run(port, lint);
+        },
+        _ => {},
+    }
+}
+
+fn get_clap_config<'a>() -> ArgMatches<'a> {
+    App::new("Clippy developer tooling")
+        .subcommand(SubCommand::with_name("bless").about("bless the test output changes"))
         .subcommand(
             SubCommand::with_name("fmt")
                 .about("Run rustfmt on all projects and tests")
@@ -25,16 +68,16 @@ fn main() {
                 .about("Updates lint registration and information from the source code")
                 .long_about(
                     "Makes sure that:\n \
-                     * the lint count in README.md is correct\n \
-                     * the changelog contains markdown link references at the bottom\n \
-                     * all lint groups include the correct lints\n \
-                     * lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod`\n \
-                     * all lints are registered in the lint store",
+                 * the lint count in README.md is correct\n \
+                 * the changelog contains markdown link references at the bottom\n \
+                 * all lint groups include the correct lints\n \
+                 * lint modules in `clippy_lints/*` are visible in `src/lifb.rs` via `pub mod`\n \
+                 * all lints are registered in the lint store",
                 )
                 .arg(Arg::with_name("print-only").long("print-only").help(
                     "Print a table of lints to STDOUT. \
-                     This does not include deprecated and internal lints. \
-                     (Does not modify any files)",
+                 This does not include deprecated and internal lints. \
+                 (Does not modify any files)",
                 ))
                 .arg(
                     Arg::with_name("check")
@@ -88,7 +131,7 @@ fn main() {
                 .about("Ensures that stderr files do not grow longer than a certain amount of lines."),
         )
         .subcommand(
-            SubCommand::with_name("ra-setup")
+            SubCommand::with_name("ra_setup")
                 .about("Alter dependencies so rust-analyzer can find rustc internals")
                 .arg(
                     Arg::with_name("rustc-repo-path")
@@ -113,40 +156,5 @@ fn main() {
                 )
                 .arg(Arg::with_name("lint").help("Which lint's page to load initially (optional)")),
         )
-        .get_matches();
-
-    match matches.subcommand() {
-        ("fmt", Some(matches)) => {
-            fmt::run(matches.is_present("check"), matches.is_present("verbose"));
-        },
-        ("update_lints", Some(matches)) => {
-            if matches.is_present("print-only") {
-                update_lints::print_lints();
-            } else if matches.is_present("check") {
-                update_lints::run(update_lints::UpdateMode::Check);
-            } else {
-                update_lints::run(update_lints::UpdateMode::Change);
-            }
-        },
-        ("new_lint", Some(matches)) => {
-            match new_lint::create(
-                matches.value_of("pass"),
-                matches.value_of("name"),
-                matches.value_of("category"),
-            ) {
-                Ok(_) => update_lints::run(update_lints::UpdateMode::Change),
-                Err(e) => eprintln!("Unable to create lint: {}", e),
-            }
-        },
-        ("limit_stderr_length", _) => {
-            stderr_length_check::check();
-        },
-        ("ra-setup", Some(matches)) => ra_setup::run(matches.value_of("rustc-repo-path")),
-        ("serve", Some(matches)) => {
-            let port = matches.value_of("port").unwrap().parse().unwrap();
-            let lint = matches.value_of("lint");
-            serve::run(port, lint);
-        },
-        _ => {},
-    }
+        .get_matches()
 }
diff --git a/src/tools/clippy/clippy_dev/src/ra_setup.rs b/src/tools/clippy/clippy_dev/src/ra_setup.rs
index 9d9e836cc08..40bf4a9505a 100644
--- a/src/tools/clippy/clippy_dev/src/ra_setup.rs
+++ b/src/tools/clippy/clippy_dev/src/ra_setup.rs
@@ -52,7 +52,7 @@ fn inject_deps_into_manifest(
     // do not inject deps if we have aleady done so
     if cargo_toml.contains("[target.'cfg(NOT_A_PLATFORM)'.dependencies]") {
         eprintln!(
-            "cargo dev ra-setup: warning: deps already found inside {}, doing nothing.",
+            "cargo dev ra_setup: warning: deps already found inside {}, doing nothing.",
             manifest_path
         );
         return Ok(());
diff --git a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
index 58892024ce2..f136aa4572a 100644
--- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
+++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
@@ -99,7 +99,11 @@ impl LateLintPass<'_> for AwaitHolding {
             };
             let def_id = cx.tcx.hir().body_owner_def_id(body_id);
             let typeck_results = cx.tcx.typeck(def_id);
-            check_interior_types(cx, &typeck_results.generator_interior_types, body.value.span);
+            check_interior_types(
+                cx,
+                &typeck_results.generator_interior_types.as_ref().skip_binder(),
+                body.value.span,
+            );
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/checked_conversions.rs b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
index 28c1a54d2c5..54bc69e058b 100644
--- a/src/tools/clippy/clippy_lints/src/checked_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
@@ -6,9 +6,12 @@ use rustc_errors::Applicability;
 use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind, QPath, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_semver::RustcVersion;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
 
-use crate::utils::{snippet_with_applicability, span_lint_and_sugg, SpanlessEq};
+use crate::utils::{meets_msrv, snippet_with_applicability, span_lint_and_sugg, SpanlessEq};
+
+const CHECKED_CONVERSIONS_MSRV: RustcVersion = RustcVersion::new(1, 34, 0);
 
 declare_clippy_lint! {
     /// **What it does:** Checks for explicit bounds checking when casting.
@@ -39,10 +42,25 @@ declare_clippy_lint! {
     "`try_from` could replace manual bounds checking when casting"
 }
 
-declare_lint_pass!(CheckedConversions => [CHECKED_CONVERSIONS]);
+pub struct CheckedConversions {
+    msrv: Option<RustcVersion>,
+}
+
+impl CheckedConversions {
+    #[must_use]
+    pub fn new(msrv: Option<RustcVersion>) -> Self {
+        Self { msrv }
+    }
+}
+
+impl_lint_pass!(CheckedConversions => [CHECKED_CONVERSIONS]);
 
 impl<'tcx> LateLintPass<'tcx> for CheckedConversions {
     fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {
+        if !meets_msrv(self.msrv.as_ref(), &CHECKED_CONVERSIONS_MSRV) {
+            return;
+        }
+
         let result = if_chain! {
             if !in_external_macro(cx.sess(), item.span);
             if let ExprKind::Binary(op, ref left, ref right) = &item.kind;
@@ -74,6 +92,8 @@ impl<'tcx> LateLintPass<'tcx> for CheckedConversions {
             }
         }
     }
+
+    extract_msrv_attr!(LateContext);
 }
 
 /// Searches for a single check from unsigned to _ is done
diff --git a/src/tools/clippy/clippy_lints/src/create_dir.rs b/src/tools/clippy/clippy_lints/src/create_dir.rs
index 4002fb655a5..200b6a565cc 100644
--- a/src/tools/clippy/clippy_lints/src/create_dir.rs
+++ b/src/tools/clippy/clippy_lints/src/create_dir.rs
@@ -8,7 +8,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
 declare_clippy_lint! {
     /// **What it does:** Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
     ///
-    /// **Why is this bad?** Sometimes `std::fs::crate_dir` is mistakenly chosen over `std::fs::create_dir_all`.
+    /// **Why is this bad?** Sometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`.
     ///
     /// **Known problems:** None.
     ///
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index edecba57e44..aba65532795 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -14,6 +14,7 @@ use rustc_middle::ty;
 use rustc_parse::maybe_new_parser_from_source_str;
 use rustc_session::parse::ParseSess;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::edition::Edition;
 use rustc_span::source_map::{BytePos, FilePathMapping, MultiSpan, SourceMap, Span};
 use rustc_span::{sym, FileName, Pos};
 use std::io;
@@ -377,7 +378,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
     check_doc(cx, valid_idents, events, &spans)
 }
 
-const RUST_CODE: &[&str] = &["rust", "no_run", "should_panic", "compile_fail", "edition2018"];
+const RUST_CODE: &[&str] = &["rust", "no_run", "should_panic", "compile_fail"];
 
 fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize>)>>(
     cx: &LateContext<'_>,
@@ -400,13 +401,24 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
     let mut in_link = None;
     let mut in_heading = false;
     let mut is_rust = false;
+    let mut edition = None;
     for (event, range) in events {
         match event {
             Start(CodeBlock(ref kind)) => {
                 in_code = true;
                 if let CodeBlockKind::Fenced(lang) = kind {
-                    is_rust =
-                        lang.is_empty() || !lang.contains("ignore") && lang.split(',').any(|i| RUST_CODE.contains(&i));
+                    for item in lang.split(',') {
+                        if item == "ignore" {
+                            is_rust = false;
+                            break;
+                        }
+                        if let Some(stripped) = item.strip_prefix("edition") {
+                            is_rust = true;
+                            edition = stripped.parse::<Edition>().ok();
+                        } else if item.is_empty() || RUST_CODE.contains(&item) {
+                            is_rust = true;
+                        }
+                    }
                 }
             },
             End(CodeBlock(_)) => {
@@ -436,7 +448,8 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                 let (begin, span) = spans[index];
                 if in_code {
                     if is_rust {
-                        check_code(cx, &text, span);
+                        let edition = edition.unwrap_or_else(|| cx.tcx.sess.edition());
+                        check_code(cx, &text, edition, span);
                     }
                 } else {
                     // Adjust for the beginning of the current `Event`
@@ -450,67 +463,73 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
     headers
 }
 
-fn check_code(cx: &LateContext<'_>, text: &str, span: Span) {
-    fn has_needless_main(code: &str) -> bool {
-        let filename = FileName::anon_source_code(code);
-
-        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let emitter = EmitterWriter::new(box io::sink(), None, false, false, false, None, false);
-        let handler = Handler::with_emitter(false, None, box emitter);
-        let sess = ParseSess::with_span_handler(handler, sm);
-
-        let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code.into()) {
-            Ok(p) => p,
-            Err(errs) => {
-                for mut err in errs {
-                    err.cancel();
-                }
-                return false;
-            },
-        };
-
-        let mut relevant_main_found = false;
-        loop {
-            match parser.parse_item() {
-                Ok(Some(item)) => match &item.kind {
-                    // Tests with one of these items are ignored
-                    ItemKind::Static(..)
-                    | ItemKind::Const(..)
-                    | ItemKind::ExternCrate(..)
-                    | ItemKind::ForeignMod(..) => return false,
-                    // We found a main function ...
-                    ItemKind::Fn(_, sig, _, Some(block)) if item.ident.name == sym::main => {
-                        let is_async = matches!(sig.header.asyncness, Async::Yes{..});
-                        let returns_nothing = match &sig.decl.output {
-                            FnRetTy::Default(..) => true,
-                            FnRetTy::Ty(ty) if ty.kind.is_unit() => true,
-                            _ => false,
-                        };
-
-                        if returns_nothing && !is_async && !block.stmts.is_empty() {
-                            // This main function should be linted, but only if there are no other functions
-                            relevant_main_found = true;
-                        } else {
-                            // This main function should not be linted, we're done
-                            return false;
+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(|| {
+            rustc_span::with_session_globals(edition, || {
+                let filename = FileName::anon_source_code(code);
+
+                let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+                let emitter = EmitterWriter::new(box io::sink(), None, false, false, false, None, false);
+                let handler = Handler::with_emitter(false, None, box emitter);
+                let sess = ParseSess::with_span_handler(handler, sm);
+
+                let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code.into()) {
+                    Ok(p) => p,
+                    Err(errs) => {
+                        for mut err in errs {
+                            err.cancel();
                         }
+                        return false;
                     },
-                    // Another function was found; this case is ignored too
-                    ItemKind::Fn(..) => return false,
-                    _ => {},
-                },
-                Ok(None) => break,
-                Err(mut e) => {
-                    e.cancel();
-                    return false;
-                },
-            }
-        }
+                };
+
+                let mut relevant_main_found = false;
+                loop {
+                    match parser.parse_item() {
+                        Ok(Some(item)) => match &item.kind {
+                            // Tests with one of these items are ignored
+                            ItemKind::Static(..)
+                            | ItemKind::Const(..)
+                            | ItemKind::ExternCrate(..)
+                            | ItemKind::ForeignMod(..) => return false,
+                            // We found a main function ...
+                            ItemKind::Fn(_, sig, _, Some(block)) if item.ident.name == sym::main => {
+                                let is_async = matches!(sig.header.asyncness, Async::Yes { .. });
+                                let returns_nothing = match &sig.decl.output {
+                                    FnRetTy::Default(..) => true,
+                                    FnRetTy::Ty(ty) if ty.kind.is_unit() => true,
+                                    _ => false,
+                                };
+
+                                if returns_nothing && !is_async && !block.stmts.is_empty() {
+                                    // This main function should be linted, but only if there are no other functions
+                                    relevant_main_found = true;
+                                } else {
+                                    // This main function should not be linted, we're done
+                                    return false;
+                                }
+                            },
+                            // Another function was found; this case is ignored too
+                            ItemKind::Fn(..) => return false,
+                            _ => {},
+                        },
+                        Ok(None) => break,
+                        Err(mut e) => {
+                            e.cancel();
+                            return false;
+                        },
+                    }
+                }
 
-        relevant_main_found
+                relevant_main_found
+            })
+        })
+        .ok()
+        .unwrap_or_default()
     }
 
-    if has_needless_main(text) {
+    if has_needless_main(text, edition) {
         span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, "needless `fn main` in doctest");
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/functions.rs b/src/tools/clippy/clippy_lints/src/functions.rs
index 8b58d1f2601..fd93548b55c 100644
--- a/src/tools/clippy/clippy_lints/src/functions.rs
+++ b/src/tools/clippy/clippy_lints/src/functions.rs
@@ -405,13 +405,10 @@ impl<'tcx> Functions {
                     break;
                 }
                 if in_comment {
-                    match line.find("*/") {
-                        Some(i) => {
-                            line = &line[i + 2..];
-                            in_comment = false;
-                            continue;
-                        },
-                        None => break,
+                    if let Some(i) = line.find("*/") {
+                        line = &line[i + 2..];
+                        in_comment = false;
+                        continue;
                     }
                 } else {
                     let multi_idx = line.find("/*").unwrap_or_else(|| line.len());
@@ -423,8 +420,8 @@ impl<'tcx> Functions {
                         in_comment = true;
                         continue;
                     }
-                    break;
                 }
+                break;
             }
             if code_in_line {
                 line_count += 1;
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 8842901d90b..6fe53351090 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -222,9 +222,8 @@ fn check_impl_items(cx: &LateContext<'_>, item: &Item<'_>, impl_items: &[ImplIte
     let is_empty = if let Some(is_empty) = impl_items.iter().find(|i| is_named_self(cx, i, "is_empty")) {
         if cx.access_levels.is_exported(is_empty.id.hir_id) {
             return;
-        } else {
-            "a private"
         }
+        "a private"
     } else {
         "no corresponding"
     };
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 2b99ed570b1..02ba422a2f5 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -27,6 +27,7 @@ extern crate rustc_ast;
 extern crate rustc_ast_pretty;
 extern crate rustc_attr;
 extern crate rustc_data_structures;
+extern crate rustc_driver;
 extern crate rustc_errors;
 extern crate rustc_hir;
 extern crate rustc_hir_pretty;
@@ -294,6 +295,7 @@ mod question_mark;
 mod ranges;
 mod redundant_clone;
 mod redundant_closure_call;
+mod redundant_else;
 mod redundant_field_names;
 mod redundant_pub_crate;
 mod redundant_static_lifetimes;
@@ -344,6 +346,7 @@ mod wildcard_dependencies;
 mod wildcard_imports;
 mod write;
 mod zero_div_zero;
+mod zero_sized_map_values;
 // end lints modules, do not remove this comment, it’s used in `update_lints`
 
 pub use crate::utils::conf::Conf;
@@ -509,6 +512,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         #[cfg(feature = "internal-lints")]
         &utils::internal_lints::DEFAULT_LINT,
         #[cfg(feature = "internal-lints")]
+        &utils::internal_lints::INTERNING_DEFINED_SYMBOL,
+        #[cfg(feature = "internal-lints")]
         &utils::internal_lints::INVALID_PATHS,
         #[cfg(feature = "internal-lints")]
         &utils::internal_lints::LINT_WITHOUT_LINT_PASS,
@@ -831,6 +836,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &ranges::REVERSED_EMPTY_RANGES,
         &redundant_clone::REDUNDANT_CLONE,
         &redundant_closure_call::REDUNDANT_CLOSURE_CALL,
+        &redundant_else::REDUNDANT_ELSE,
         &redundant_field_names::REDUNDANT_FIELD_NAMES,
         &redundant_pub_crate::REDUNDANT_PUB_CRATE,
         &redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES,
@@ -934,6 +940,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &wildcard_imports::WILDCARD_IMPORTS,
         &write::PRINTLN_EMPTY_STRING,
         &write::PRINT_LITERAL,
+        &write::PRINT_STDERR,
         &write::PRINT_STDOUT,
         &write::PRINT_WITH_NEWLINE,
         &write::USE_DEBUG,
@@ -941,6 +948,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &write::WRITE_LITERAL,
         &write::WRITE_WITH_NEWLINE,
         &zero_div_zero::ZERO_DIVIDED_BY_ZERO,
+        &zero_sized_map_values::ZERO_SIZED_MAP_VALUES,
     ]);
     // end register lints, do not remove this comment, it’s used in `update_lints`
 
@@ -953,6 +961,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         store.register_late_pass(|| box utils::internal_lints::CollapsibleCalls);
         store.register_late_pass(|| box utils::internal_lints::CompilerLintFunctions::new());
         store.register_late_pass(|| box utils::internal_lints::InvalidPaths);
+        store.register_late_pass(|| box utils::internal_lints::InterningDefinedSymbol::default());
         store.register_late_pass(|| box utils::internal_lints::LintWithoutLintPass::default());
         store.register_late_pass(|| box utils::internal_lints::MatchTypeOnDiagItem);
         store.register_late_pass(|| box utils::internal_lints::OuterExpnDataPass);
@@ -1000,6 +1009,14 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(move || box matches::Matches::new(msrv));
     store.register_early_pass(move || box manual_non_exhaustive::ManualNonExhaustive::new(msrv));
     store.register_late_pass(move || box manual_strip::ManualStrip::new(msrv));
+    store.register_early_pass(move || box redundant_static_lifetimes::RedundantStaticLifetimes::new(msrv));
+    store.register_early_pass(move || box redundant_field_names::RedundantFieldNames::new(msrv));
+    store.register_late_pass(move || box checked_conversions::CheckedConversions::new(msrv));
+    store.register_late_pass(move || box mem_replace::MemReplace::new(msrv));
+    store.register_late_pass(move || box ranges::Ranges::new(msrv));
+    store.register_late_pass(move || box use_self::UseSelf::new(msrv));
+    store.register_late_pass(move || box missing_const_for_fn::MissingConstForFn::new(msrv));
+
     store.register_late_pass(|| box size_of_in_element_count::SizeOfInElementCount);
     store.register_late_pass(|| box map_clone::MapClone);
     store.register_late_pass(|| box map_err_ignore::MapErrIgnore);
@@ -1010,7 +1027,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| box main_recursion::MainRecursion::default());
     store.register_late_pass(|| box lifetimes::Lifetimes);
     store.register_late_pass(|| box entry::HashMapPass);
-    store.register_late_pass(|| box ranges::Ranges);
     store.register_late_pass(|| box types::Casts);
     let type_complexity_threshold = conf.type_complexity_threshold;
     store.register_late_pass(move || box types::TypeComplexity::new(type_complexity_threshold));
@@ -1055,7 +1071,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| box neg_multiply::NegMultiply);
     store.register_late_pass(|| box mem_discriminant::MemDiscriminant);
     store.register_late_pass(|| box mem_forget::MemForget);
-    store.register_late_pass(|| box mem_replace::MemReplace);
     store.register_late_pass(|| box arithmetic::Arithmetic::default());
     store.register_late_pass(|| box assign_ops::AssignOps);
     store.register_late_pass(|| box let_if_seq::LetIfSeq);
@@ -1077,7 +1092,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(move || box pass_by_ref_or_value);
     store.register_late_pass(|| box ref_option_ref::RefOptionRef);
     store.register_late_pass(|| box try_err::TryErr);
-    store.register_late_pass(|| box use_self::UseSelf);
     store.register_late_pass(|| box bytecount::ByteCount);
     store.register_late_pass(|| box infinite_iter::InfiniteIter);
     store.register_late_pass(|| box inline_fn_without_body::InlineFnWithoutBody);
@@ -1103,10 +1117,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| box unnecessary_wraps::UnnecessaryWraps);
     store.register_late_pass(|| box types::RefToMut);
     store.register_late_pass(|| box assertions_on_constants::AssertionsOnConstants);
-    store.register_late_pass(|| box missing_const_for_fn::MissingConstForFn);
     store.register_late_pass(|| box transmuting_null::TransmutingNull);
     store.register_late_pass(|| box path_buf_push_overwrite::PathBufPushOverwrite);
-    store.register_late_pass(|| box checked_conversions::CheckedConversions);
     store.register_late_pass(|| box integer_division::IntegerDivision);
     store.register_late_pass(|| box inherent_to_string::InherentToString);
     let max_trait_bounds = conf.max_trait_bounds;
@@ -1132,9 +1144,9 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_early_pass(|| box items_after_statements::ItemsAfterStatements);
     store.register_early_pass(|| box precedence::Precedence);
     store.register_early_pass(|| box needless_continue::NeedlessContinue);
+    store.register_early_pass(|| box redundant_else::RedundantElse);
     store.register_late_pass(|| box create_dir::CreateDir);
     store.register_early_pass(|| box needless_arbitrary_self_type::NeedlessArbitrarySelfType);
-    store.register_early_pass(|| box redundant_static_lifetimes::RedundantStaticLifetimes);
     store.register_late_pass(|| box cargo_common_metadata::CargoCommonMetadata);
     store.register_late_pass(|| box multiple_crate_versions::MultipleCrateVersions);
     store.register_late_pass(|| box wildcard_dependencies::WildcardDependencies);
@@ -1174,7 +1186,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| box mut_mutex_lock::MutMutexLock);
     store.register_late_pass(|| box match_on_vec_items::MatchOnVecItems);
     store.register_late_pass(|| box manual_async_fn::ManualAsyncFn);
-    store.register_early_pass(|| box redundant_field_names::RedundantFieldNames);
     store.register_late_pass(|| box vec_resize_to_zero::VecResizeToZero);
     store.register_late_pass(|| box panic_in_result_fn::PanicInResultFn);
     let single_char_binding_names_threshold = conf.single_char_binding_names_threshold;
@@ -1200,6 +1211,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| box undropped_manually_drops::UndroppedManuallyDrops);
     store.register_late_pass(|| box strings::StrToString);
     store.register_late_pass(|| box strings::StringToString);
+    store.register_late_pass(|| box zero_sized_map_values::ZeroSizedMapValues);
 
     store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
         LintId::of(&arithmetic::FLOAT_ARITHMETIC),
@@ -1247,6 +1259,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&types::RC_BUFFER),
         LintId::of(&unwrap_in_result::UNWRAP_IN_RESULT),
         LintId::of(&verbose_file_reads::VERBOSE_FILE_READS),
+        LintId::of(&write::PRINT_STDERR),
         LintId::of(&write::PRINT_STDOUT),
         LintId::of(&write::USE_DEBUG),
     ]);
@@ -1308,6 +1321,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF),
         LintId::of(&ranges::RANGE_MINUS_ONE),
         LintId::of(&ranges::RANGE_PLUS_ONE),
+        LintId::of(&redundant_else::REDUNDANT_ELSE),
         LintId::of(&ref_option_ref::REF_OPTION_REF),
         LintId::of(&shadow::SHADOW_UNRELATED),
         LintId::of(&strings::STRING_ADD_ASSIGN),
@@ -1330,6 +1344,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&unused_self::UNUSED_SELF),
         LintId::of(&wildcard_imports::ENUM_GLOB_USE),
         LintId::of(&wildcard_imports::WILDCARD_IMPORTS),
+        LintId::of(&zero_sized_map_values::ZERO_SIZED_MAP_VALUES),
     ]);
 
     #[cfg(feature = "internal-lints")]
@@ -1338,6 +1353,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&utils::internal_lints::COLLAPSIBLE_SPAN_LINT_CALLS),
         LintId::of(&utils::internal_lints::COMPILER_LINT_FUNCTIONS),
         LintId::of(&utils::internal_lints::DEFAULT_LINT),
+        LintId::of(&utils::internal_lints::INTERNING_DEFINED_SYMBOL),
         LintId::of(&utils::internal_lints::INVALID_PATHS),
         LintId::of(&utils::internal_lints::LINT_WITHOUT_LINT_PASS),
         LintId::of(&utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM),
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index 4d737b3f49b..e84c8b4e5b3 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -501,7 +501,7 @@ impl<'tcx> Visitor<'tcx> for BodyLifetimeChecker {
 
     // for lifetimes as parameters of generics
     fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
-        if lifetime.name.ident().name != kw::Invalid && lifetime.name.ident().name != kw::StaticLifetime {
+        if lifetime.name.ident().name != kw::Empty && lifetime.name.ident().name != kw::StaticLifetime {
             self.lifetimes_used_in_body = true;
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/manual_ok_or.rs b/src/tools/clippy/clippy_lints/src/manual_ok_or.rs
index c99d2e35b94..b97d97ea1a5 100644
--- a/src/tools/clippy/clippy_lints/src/manual_ok_or.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_ok_or.rs
@@ -8,6 +8,7 @@ use rustc_lint::LintContext;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::symbol::sym;
 
 declare_clippy_lint! {
     /// **What it does:**
@@ -51,7 +52,7 @@ impl LateLintPass<'_> for ManualOkOr {
             if args.len() == 3;
             let method_receiver = &args[0];
             let ty = cx.typeck_results().expr_ty(method_receiver);
-            if is_type_diagnostic_item(cx, ty, sym!(option_type));
+            if is_type_diagnostic_item(cx, ty, sym::option_type);
             let or_expr = &args[1];
             if is_ok_wrapping(cx, &args[2]);
             if let ExprKind::Call(Expr { kind: ExprKind::Path(err_path), .. }, &[ref err_arg]) = or_expr.kind;
diff --git a/src/tools/clippy/clippy_lints/src/matches.rs b/src/tools/clippy/clippy_lints/src/matches.rs
index 274d20cfa80..04b35835c6b 100644
--- a/src/tools/clippy/clippy_lints/src/matches.rs
+++ b/src/tools/clippy/clippy_lints/src/matches.rs
@@ -4,8 +4,8 @@ use crate::utils::usage::is_unused;
 use crate::utils::{
     expr_block, get_arg_name, get_parent_expr, in_macro, indent_of, is_allowed, is_expn_of, is_refutable,
     is_type_diagnostic_item, is_wild, match_qpath, match_type, match_var, meets_msrv, multispan_sugg, remove_blocks,
-    snippet, snippet_block, snippet_with_applicability, span_lint_and_help, span_lint_and_note, span_lint_and_sugg,
-    span_lint_and_then,
+    snippet, snippet_block, snippet_opt, snippet_with_applicability, span_lint_and_help, span_lint_and_note,
+    span_lint_and_sugg, span_lint_and_then,
 };
 use crate::utils::{paths, search_same, SpanlessEq, SpanlessHash};
 use if_chain::if_chain;
@@ -689,10 +689,9 @@ fn check_single_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], exp
             if stmts.len() == 1 && block_expr.is_none() || stmts.is_empty() && block_expr.is_some() {
                 // single statement/expr "else" block, don't lint
                 return;
-            } else {
-                // block with 2+ statements or 1 expr and 1+ statement
-                Some(els)
             }
+            // block with 2+ statements or 1 expr and 1+ statement
+            Some(els)
         } else {
             // not a block, don't lint
             return;
@@ -1238,6 +1237,24 @@ fn check_match_single_binding<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[A
     if in_macro(expr.span) || arms.len() != 1 || is_refutable(cx, arms[0].pat) {
         return;
     }
+
+    // HACK:
+    // This is a hack to deal with arms that are excluded by macros like `#[cfg]`. It is only used here
+    // to prevent false positives as there is currently no better way to detect if code was excluded by
+    // a macro. See PR #6435
+    if_chain! {
+        if let Some(match_snippet) = snippet_opt(cx, expr.span);
+        if let Some(arm_snippet) = snippet_opt(cx, arms[0].span);
+        if let Some(ex_snippet) = snippet_opt(cx, ex.span);
+        let rest_snippet = match_snippet.replace(&arm_snippet, "").replace(&ex_snippet, "");
+        if rest_snippet.contains("=>");
+        then {
+            // The code it self contains another thick arrow "=>"
+            // -> Either another arm or a comment
+            return;
+        }
+    }
+
     let matched_vars = ex.span;
     let bind_names = arms[0].pat.span;
     let match_body = remove_blocks(&arms[0].body);
diff --git a/src/tools/clippy/clippy_lints/src/mem_replace.rs b/src/tools/clippy/clippy_lints/src/mem_replace.rs
index bb0acecc5a9..19087b02077 100644
--- a/src/tools/clippy/clippy_lints/src/mem_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/mem_replace.rs
@@ -1,13 +1,14 @@
 use crate::utils::{
-    in_macro, match_def_path, match_qpath, paths, snippet, snippet_with_applicability, span_lint_and_help,
+    in_macro, match_def_path, match_qpath, meets_msrv, paths, snippet, snippet_with_applicability, span_lint_and_help,
     span_lint_and_sugg, span_lint_and_then,
 };
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, QPath};
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_semver::RustcVersion;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::Span;
 use rustc_span::symbol::sym;
 
@@ -94,7 +95,7 @@ declare_clippy_lint! {
     "replacing a value of type `T` with `T::default()` instead of using `std::mem::take`"
 }
 
-declare_lint_pass!(MemReplace =>
+impl_lint_pass!(MemReplace =>
     [MEM_REPLACE_OPTION_WITH_NONE, MEM_REPLACE_WITH_UNINIT, MEM_REPLACE_WITH_DEFAULT]);
 
 fn check_replace_option_with_none(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) {
@@ -224,6 +225,19 @@ fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<
     }
 }
 
+const MEM_REPLACE_WITH_DEFAULT_MSRV: RustcVersion = RustcVersion::new(1, 40, 0);
+
+pub struct MemReplace {
+    msrv: Option<RustcVersion>,
+}
+
+impl MemReplace {
+    #[must_use]
+    pub fn new(msrv: Option<RustcVersion>) -> Self {
+        Self { msrv }
+    }
+}
+
 impl<'tcx> LateLintPass<'tcx> for MemReplace {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if_chain! {
@@ -236,8 +250,11 @@ impl<'tcx> LateLintPass<'tcx> for MemReplace {
             then {
                 check_replace_option_with_none(cx, src, dest, expr.span);
                 check_replace_with_uninit(cx, src, dest, expr.span);
-                check_replace_with_default(cx, src, dest, expr.span);
+                if meets_msrv(self.msrv.as_ref(), &MEM_REPLACE_WITH_DEFAULT_MSRV) {
+                    check_replace_with_default(cx, src, dest, expr.span);
+                }
             }
         }
     }
+    extract_msrv_attr!(LateContext);
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 8002c27a5e9..e99fe1b97ff 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -22,6 +22,7 @@ use rustc_semver::RustcVersion;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::Span;
 use rustc_span::symbol::{sym, SymbolStr};
+use rustc_typeck::hir_ty_to_ty;
 
 use crate::consts::{constant, Constant};
 use crate::utils::eager_or_lazy::is_lazyness_candidate;
@@ -1487,7 +1488,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
             ["expect", ..] => lint_expect(cx, expr, arg_lists[0]),
             ["unwrap_or", "map"] => option_map_unwrap_or::lint(cx, expr, arg_lists[1], arg_lists[0], method_spans[1]),
             ["unwrap_or_else", "map"] => {
-                if !lint_map_unwrap_or_else(cx, expr, arg_lists[1], arg_lists[0]) {
+                if !lint_map_unwrap_or_else(cx, expr, arg_lists[1], arg_lists[0], self.msrv.as_ref()) {
                     unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "unwrap_or");
                 }
             },
@@ -1509,7 +1510,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
             ["next", "iter"] => lint_iter_next(cx, expr, arg_lists[1]),
             ["map", "filter"] => lint_filter_map(cx, expr, arg_lists[1], arg_lists[0]),
             ["map", "filter_map"] => lint_filter_map_map(cx, expr, arg_lists[1], arg_lists[0]),
-            ["next", "filter_map"] => lint_filter_map_next(cx, expr, arg_lists[1]),
+            ["next", "filter_map"] => lint_filter_map_next(cx, expr, arg_lists[1], self.msrv.as_ref()),
             ["map", "find"] => lint_find_map(cx, expr, arg_lists[1], arg_lists[0]),
             ["flat_map", "filter"] => lint_filter_flat_map(cx, expr, arg_lists[1], arg_lists[0]),
             ["flat_map", "filter_map"] => lint_filter_map_flat_map(cx, expr, arg_lists[1], arg_lists[0]),
@@ -1568,7 +1569,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
                 lint_expect_fun_call(cx, expr, *method_span, &method_call.ident.as_str(), args);
 
                 let self_ty = cx.typeck_results().expr_ty_adjusted(&args[0]);
-                if args.len() == 1 && method_call.ident.name == sym!(clone) {
+                if args.len() == 1 && method_call.ident.name == sym::clone {
                     lint_clone_on_copy(cx, expr, &args[0], self_ty);
                     lint_clone_on_ref_ptr(cx, expr, &args[0]);
                 }
@@ -1592,7 +1593,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
                             }
                         }
                     },
-                    ty::Ref(..) if method_call.ident.name == sym!(into_iter) => {
+                    ty::Ref(..) if method_call.ident.name == sym::into_iter => {
                         lint_into_iter(cx, expr, self_ty, *method_span);
                     },
                     _ => (),
@@ -1623,10 +1624,15 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
         let item = cx.tcx.hir().expect_item(parent);
         let def_id = cx.tcx.hir().local_def_id(item.hir_id);
         let self_ty = cx.tcx.type_of(def_id);
+
+        // if this impl block implements a trait, lint in trait definition instead
+        if let hir::ItemKind::Impl { of_trait: Some(_), .. } = item.kind {
+            return;
+        }
+
         if_chain! {
             if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind;
             if let Some(first_arg) = iter_input_pats(&sig.decl, cx.tcx.hir().body(id)).next();
-            if let hir::ItemKind::Impl{ of_trait: None, .. } = item.kind;
 
             let method_def_id = cx.tcx.hir().local_def_id(impl_item.hir_id);
             let method_sig = cx.tcx.fn_sig(method_def_id);
@@ -1668,40 +1674,17 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
                     }
                 }
 
-                if let Some((ref conv, self_kinds)) = &CONVENTIONS
-                    .iter()
-                    .find(|(ref conv, _)| conv.check(&name))
-                {
-                    if !self_kinds.iter().any(|k| k.matches(cx, self_ty, first_arg_ty)) {
-                        let lint = if item.vis.node.is_pub() {
-                            WRONG_PUB_SELF_CONVENTION
-                        } else {
-                            WRONG_SELF_CONVENTION
-                        };
-
-                        span_lint(
-                            cx,
-                            lint,
-                            first_arg.pat.span,
-                            &format!("methods called `{}` usually take {}; consider choosing a less ambiguous name",
-                                conv,
-                                &self_kinds
-                                    .iter()
-                                    .map(|k| k.description())
-                                    .collect::<Vec<_>>()
-                                    .join(" or ")
-                            ),
-                        );
-                    }
-                }
+                lint_wrong_self_convention(
+                    cx,
+                    &name,
+                    item.vis.node.is_pub(),
+                    self_ty,
+                    first_arg_ty,
+                    first_arg.pat.span
+                );
             }
         }
 
-        // if this impl block implements a trait, lint in trait definition instead
-        if let hir::ItemKind::Impl { of_trait: Some(_), .. } = item.kind {
-            return;
-        }
-
         if let hir::ImplItemKind::Fn(_, _) = impl_item.kind {
             let ret_ty = return_ty(cx, impl_item.hir_id);
 
@@ -1735,8 +1718,23 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
+        if in_external_macro(cx.tcx.sess, item.span) {
+            return;
+        }
+
+        if_chain! {
+            if let TraitItemKind::Fn(ref sig, _) = item.kind;
+            if let Some(first_arg_ty) = sig.decl.inputs.iter().next();
+            let first_arg_span = first_arg_ty.span;
+            let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty);
+            let self_ty = TraitRef::identity(cx.tcx, item.hir_id.owner.to_def_id()).self_ty();
+
+            then {
+                lint_wrong_self_convention(cx, &item.ident.name.as_str(), false, self_ty, first_arg_ty, first_arg_span);
+            }
+        }
+
         if_chain! {
-            if !in_external_macro(cx.tcx.sess, item.span);
             if item.ident.name == sym::new;
             if let TraitItemKind::Fn(_, _) = item.kind;
             let ret_ty = return_ty(cx, item.hir_id);
@@ -1757,6 +1755,39 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
     extract_msrv_attr!(LateContext);
 }
 
+fn lint_wrong_self_convention<'tcx>(
+    cx: &LateContext<'tcx>,
+    item_name: &str,
+    is_pub: bool,
+    self_ty: &'tcx TyS<'tcx>,
+    first_arg_ty: &'tcx TyS<'tcx>,
+    first_arg_span: Span,
+) {
+    let lint = if is_pub {
+        WRONG_PUB_SELF_CONVENTION
+    } else {
+        WRONG_SELF_CONVENTION
+    };
+    if let Some((ref conv, self_kinds)) = &CONVENTIONS.iter().find(|(ref conv, _)| conv.check(item_name)) {
+        if !self_kinds.iter().any(|k| k.matches(cx, self_ty, first_arg_ty)) {
+            span_lint(
+                cx,
+                lint,
+                first_arg_span,
+                &format!(
+                    "methods called `{}` usually take {}; consider choosing a less ambiguous name",
+                    conv,
+                    &self_kinds
+                        .iter()
+                        .map(|k| k.description())
+                        .collect::<Vec<_>>()
+                        .join(" or ")
+                ),
+            );
+        }
+    }
+}
+
 /// Checks for the `OR_FUN_CALL` lint.
 #[allow(clippy::too_many_lines)]
 fn lint_or_fun_call<'tcx>(
@@ -2100,8 +2131,11 @@ fn lint_clone_on_copy(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Exp
                 cx,
                 CLONE_DOUBLE_REF,
                 expr.span,
-                "using `clone` on a double-reference; \
-                this will copy the reference instead of cloning the inner type",
+                &format!(
+                    "using `clone` on a double-reference; \
+                    this will copy the reference of type `{}` instead of cloning the inner type",
+                    ty
+                ),
                 |diag| {
                     if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) {
                         let mut ty = innermost;
@@ -2174,11 +2208,17 @@ fn lint_clone_on_copy(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Exp
         } else {
             snip = None;
         }
-        span_lint_and_then(cx, CLONE_ON_COPY, expr.span, "using `clone` on a `Copy` type", |diag| {
-            if let Some((text, snip)) = snip {
-                diag.span_suggestion(expr.span, text, snip, Applicability::MachineApplicable);
-            }
-        });
+        span_lint_and_then(
+            cx,
+            CLONE_ON_COPY,
+            expr.span,
+            &format!("using `clone` on type `{}` which implements the `Copy` trait", ty),
+            |diag| {
+                if let Some((text, snip)) = snip {
+                    diag.span_suggestion(expr.span, text, snip, Applicability::MachineApplicable);
+                }
+            },
+        );
     }
 }
 
@@ -2638,9 +2678,9 @@ fn lint_unwrap(cx: &LateContext<'_>, expr: &hir::Expr<'_>, unwrap_args: &[hir::E
 fn lint_expect(cx: &LateContext<'_>, expr: &hir::Expr<'_>, expect_args: &[hir::Expr<'_>]) {
     let obj_ty = cx.typeck_results().expr_ty(&expect_args[0]).peel_refs();
 
-    let mess = if is_type_diagnostic_item(cx, obj_ty, sym!(option_type)) {
+    let mess = if is_type_diagnostic_item(cx, obj_ty, sym::option_type) {
         Some((EXPECT_USED, "an Option", "None"))
-    } else if is_type_diagnostic_item(cx, obj_ty, sym!(result_type)) {
+    } else if is_type_diagnostic_item(cx, obj_ty, sym::result_type) {
         Some((EXPECT_USED, "a Result", "Err"))
     } else {
         None
@@ -2733,6 +2773,8 @@ fn lint_map_flatten<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map
     }
 }
 
+const MAP_UNWRAP_OR_MSRV: RustcVersion = RustcVersion::new(1, 41, 0);
+
 /// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s
 /// Return true if lint triggered
 fn lint_map_unwrap_or_else<'tcx>(
@@ -2740,7 +2782,11 @@ fn lint_map_unwrap_or_else<'tcx>(
     expr: &'tcx hir::Expr<'_>,
     map_args: &'tcx [hir::Expr<'_>],
     unwrap_args: &'tcx [hir::Expr<'_>],
+    msrv: Option<&RustcVersion>,
 ) -> bool {
+    if !meets_msrv(msrv, &MAP_UNWRAP_OR_MSRV) {
+        return false;
+    }
     // lint if the caller of `map()` is an `Option`
     let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym::option_type);
     let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym::result_type);
@@ -2923,9 +2969,20 @@ fn lint_filter_map<'tcx>(
     }
 }
 
+const FILTER_MAP_NEXT_MSRV: RustcVersion = RustcVersion::new(1, 30, 0);
+
 /// lint use of `filter_map().next()` for `Iterators`
-fn lint_filter_map_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, filter_args: &'tcx [hir::Expr<'_>]) {
+fn lint_filter_map_next<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr: &'tcx hir::Expr<'_>,
+    filter_args: &'tcx [hir::Expr<'_>],
+    msrv: Option<&RustcVersion>,
+) {
     if match_trait_method(cx, expr, &paths::ITERATOR) {
+        if !meets_msrv(msrv, &FILTER_MAP_NEXT_MSRV) {
+            return;
+        }
+
         let msg = "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling \
                    `.find_map(..)` instead.";
         let filter_snippet = snippet(cx, filter_args[1].span, "..");
@@ -3116,7 +3173,7 @@ fn lint_search_is_some<'tcx>(
     else if search_method == "find" {
         let is_string_or_str_slice = |e| {
             let self_ty = cx.typeck_results().expr_ty(e).peel_refs();
-            if is_type_diagnostic_item(cx, self_ty, sym!(string_type)) {
+            if is_type_diagnostic_item(cx, self_ty, sym::string_type) {
                 true
             } else {
                 *self_ty.kind() == ty::Str
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
index 75e123eb593..d082a88cd2d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
@@ -69,10 +69,9 @@ fn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tc
                             }
                         }
                         return (true, false);
-                    } else {
-                        // We don't know. It might do anything.
-                        return (true, true);
                     }
+                    // We don't know. It might do anything.
+                    return (true, true);
                 }
             }
             (true, true)
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index 25245b3dbf0..6ebeaced62a 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -1,14 +1,19 @@
 use crate::utils::qualify_min_const_fn::is_min_const_fn;
-use crate::utils::{fn_has_unsatisfiable_preds, has_drop, is_entrypoint_fn, span_lint, trait_ref_of_method};
+use crate::utils::{
+    fn_has_unsatisfiable_preds, has_drop, is_entrypoint_fn, meets_msrv, span_lint, trait_ref_of_method,
+};
 use rustc_hir as hir;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId};
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_semver::RustcVersion;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::Span;
 use rustc_typeck::hir_ty_to_ty;
 
+const MISSING_CONST_FOR_FN_MSRV: RustcVersion = RustcVersion::new(1, 37, 0);
+
 declare_clippy_lint! {
     /// **What it does:**
     ///
@@ -69,7 +74,18 @@ declare_clippy_lint! {
     "Lint functions definitions that could be made `const fn`"
 }
 
-declare_lint_pass!(MissingConstForFn => [MISSING_CONST_FOR_FN]);
+impl_lint_pass!(MissingConstForFn => [MISSING_CONST_FOR_FN]);
+
+pub struct MissingConstForFn {
+    msrv: Option<RustcVersion>,
+}
+
+impl MissingConstForFn {
+    #[must_use]
+    pub fn new(msrv: Option<RustcVersion>) -> Self {
+        Self { msrv }
+    }
+}
 
 impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
     fn check_fn(
@@ -81,6 +97,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
         span: Span,
         hir_id: HirId,
     ) {
+        if !meets_msrv(self.msrv.as_ref(), &MISSING_CONST_FOR_FN_MSRV) {
+            return;
+        }
+
         let def_id = cx.tcx.hir().local_def_id(hir_id);
 
         if in_external_macro(cx.tcx.sess, span) || is_entrypoint_fn(cx, def_id.to_def_id()) {
@@ -99,7 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
                 let has_const_generic_params = generics
                     .params
                     .iter()
-                    .any(|param| matches!(param.kind, GenericParamKind::Const{ .. }));
+                    .any(|param| matches!(param.kind, GenericParamKind::Const { .. }));
 
                 if already_const(header) || has_const_generic_params {
                     return;
@@ -126,6 +146,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
             span_lint(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`");
         }
     }
+    extract_msrv_attr!(LateContext);
 }
 
 /// Returns true if any of the method parameters is a type that implements `Drop`. The method
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index 4678f6872f3..27f1074a0dd 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -2,7 +2,7 @@
 // *rustc*'s
 // [`missing_doc`].
 //
-// [`missing_doc`]: https://github.com/rust-lang/rust/blob/d6d05904697d89099b55da3331155392f1db9c00/src/librustc_lint/builtin.rs#L246
+// [`missing_doc`]: https://github.com/rust-lang/rust/blob/cf9cf7c923eb01146971429044f216a3ca905e06/compiler/rustc_lint/src/builtin.rs#L415
 //
 
 use crate::utils::span_lint;
@@ -70,7 +70,14 @@ impl MissingDoc {
         }
     }
 
-    fn check_missing_docs_attrs(&self, cx: &LateContext<'_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) {
+    fn check_missing_docs_attrs(
+        &self,
+        cx: &LateContext<'_>,
+        attrs: &[ast::Attribute],
+        sp: Span,
+        article: &'static str,
+        desc: &'static str,
+    ) {
         // If we're building a test harness, then warning about
         // documentation is probably not really relevant right now.
         if cx.sess().opts.test {
@@ -94,7 +101,7 @@ impl MissingDoc {
                 cx,
                 MISSING_DOCS_IN_PRIVATE_ITEMS,
                 sp,
-                &format!("missing documentation for {}", desc),
+                &format!("missing documentation for {} {}", article, desc),
             );
         }
     }
@@ -120,13 +127,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
     }
 
     fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) {
-        self.check_missing_docs_attrs(cx, &krate.item.attrs, krate.item.span, "crate");
+        self.check_missing_docs_attrs(cx, &krate.item.attrs, krate.item.span, "the", "crate");
     }
 
     fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
-        let desc = match it.kind {
-            hir::ItemKind::Const(..) => "a constant",
-            hir::ItemKind::Enum(..) => "an enum",
+        match it.kind {
             hir::ItemKind::Fn(..) => {
                 // ignore main()
                 if it.ident.name == sym::main {
@@ -136,16 +141,17 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
                         return;
                     }
                 }
-                "a function"
             },
-            hir::ItemKind::Mod(..) => "a module",
-            hir::ItemKind::Static(..) => "a static",
-            hir::ItemKind::Struct(..) => "a struct",
-            hir::ItemKind::Trait(..) => "a trait",
-            hir::ItemKind::TraitAlias(..) => "a trait alias",
-            hir::ItemKind::TyAlias(..) => "a type alias",
-            hir::ItemKind::Union(..) => "a union",
-            hir::ItemKind::OpaqueTy(..) => "an existential type",
+            hir::ItemKind::Const(..)
+            | hir::ItemKind::Enum(..)
+            | hir::ItemKind::Mod(..)
+            | hir::ItemKind::Static(..)
+            | hir::ItemKind::Struct(..)
+            | hir::ItemKind::Trait(..)
+            | hir::ItemKind::TraitAlias(..)
+            | hir::ItemKind::TyAlias(..)
+            | hir::ItemKind::Union(..)
+            | hir::ItemKind::OpaqueTy(..) => {},
             hir::ItemKind::ExternCrate(..)
             | hir::ItemKind::ForeignMod { .. }
             | hir::ItemKind::GlobalAsm(..)
@@ -153,17 +159,17 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             | hir::ItemKind::Use(..) => return,
         };
 
-        self.check_missing_docs_attrs(cx, &it.attrs, it.span, desc);
+        let def_id = cx.tcx.hir().local_def_id(it.hir_id);
+        let (article, desc) = cx.tcx.article_and_description(def_id.to_def_id());
+
+        self.check_missing_docs_attrs(cx, &it.attrs, it.span, article, desc);
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) {
-        let desc = match trait_item.kind {
-            hir::TraitItemKind::Const(..) => "an associated constant",
-            hir::TraitItemKind::Fn(..) => "a trait method",
-            hir::TraitItemKind::Type(..) => "an associated type",
-        };
+        let def_id = cx.tcx.hir().local_def_id(trait_item.hir_id);
+        let (article, desc) = cx.tcx.article_and_description(def_id.to_def_id());
 
-        self.check_missing_docs_attrs(cx, &trait_item.attrs, trait_item.span, desc);
+        self.check_missing_docs_attrs(cx, &trait_item.attrs, trait_item.span, article, desc);
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
@@ -178,21 +184,17 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             },
         }
 
-        let desc = match impl_item.kind {
-            hir::ImplItemKind::Const(..) => "an associated constant",
-            hir::ImplItemKind::Fn(..) => "a method",
-            hir::ImplItemKind::TyAlias(_) => "an associated type",
-        };
-        self.check_missing_docs_attrs(cx, &impl_item.attrs, impl_item.span, desc);
+        let (article, desc) = cx.tcx.article_and_description(def_id.to_def_id());
+        self.check_missing_docs_attrs(cx, &impl_item.attrs, impl_item.span, article, desc);
     }
 
     fn check_struct_field(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::StructField<'_>) {
         if !sf.is_positional() {
-            self.check_missing_docs_attrs(cx, &sf.attrs, sf.span, "a struct field");
+            self.check_missing_docs_attrs(cx, &sf.attrs, sf.span, "a", "struct field");
         }
     }
 
     fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) {
-        self.check_missing_docs_attrs(cx, &v.attrs, v.span, "a variant");
+        self.check_missing_docs_attrs(cx, &v.attrs, v.span, "a", "variant");
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrow.rs b/src/tools/clippy/clippy_lints/src/needless_borrow.rs
index 405c21d608d..bff53eb8cca 100644
--- a/src/tools/clippy/clippy_lints/src/needless_borrow.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_borrow.rs
@@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrow {
             return;
         }
         if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, ref inner) = e.kind {
-            if let ty::Ref(..) = cx.typeck_results().expr_ty(inner).kind() {
+            if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty(inner).kind() {
                 for adj3 in cx.typeck_results().expr_adjustments(e).windows(3) {
                     if let [Adjustment {
                         kind: Adjust::Deref(_), ..
@@ -62,8 +62,11 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrow {
                             cx,
                             NEEDLESS_BORROW,
                             e.span,
-                            "this expression borrows a reference that is immediately dereferenced \
+                            &format!(
+                                "this expression borrows a reference (`&{}`) that is immediately dereferenced \
                              by the compiler",
+                                ty
+                            ),
                             |diag| {
                                 if let Some(snippet) = snippet_opt(cx, inner.span) {
                                     diag.span_suggestion(
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index 532c0266946..5043b7b1fc3 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -90,9 +90,10 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
 
         // Exclude non-inherent impls
         if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
-            if matches!(item.kind, ItemKind::Impl{ of_trait: Some(_), .. } |
-                ItemKind::Trait(..))
-            {
+            if matches!(
+                item.kind,
+                ItemKind::Impl { of_trait: Some(_), .. } | ItemKind::Trait(..)
+            ) {
                 return;
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/needless_update.rs b/src/tools/clippy/clippy_lints/src/needless_update.rs
index 98e9078094a..41cf541ecf5 100644
--- a/src/tools/clippy/clippy_lints/src/needless_update.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_update.rs
@@ -8,6 +8,9 @@ declare_clippy_lint! {
     /// **What it does:** Checks for needlessly including a base struct on update
     /// when all fields are changed anyway.
     ///
+    /// This lint is not applied to structs marked with
+    /// [non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html).
+    ///
     /// **Why is this bad?** This will cost resources (because the base has to be
     /// somewhere), and make the code less readable.
     ///
@@ -49,7 +52,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessUpdate {
         if let ExprKind::Struct(_, ref fields, Some(ref base)) = expr.kind {
             let ty = cx.typeck_results().expr_ty(expr);
             if let ty::Adt(def, _) = ty.kind() {
-                if fields.len() == def.non_enum_variant().fields.len() {
+                if fields.len() == def.non_enum_variant().fields.len()
+                    && !def.variants[0_usize.into()].is_field_list_non_exhaustive()
+                {
                     span_lint(
                         cx,
                         NEEDLESS_UPDATE,
diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
index 5b42b61fcde..446426b3e61 100644
--- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
+++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
@@ -409,11 +409,10 @@ fn levenstein_not_1(a_name: &str, b_name: &str) -> bool {
         if let Some(b2) = b_chars.next() {
             // check if there's just one character inserted
             return a != b2 || a_chars.ne(b_chars);
-        } else {
-            // tuple
-            // ntuple
-            return true;
         }
+        // tuple
+        // ntuple
+        return true;
     }
     // for item in items
     true
diff --git a/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs b/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs
index 72dfccc1089..37e2b50def1 100644
--- a/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs
@@ -1,18 +1,16 @@
-use crate::utils::{is_expn_of, is_type_diagnostic_item, return_ty, span_lint_and_then};
+use crate::utils::{find_macro_calls, is_type_diagnostic_item, return_ty, span_lint_and_then};
 use rustc_hir as hir;
-use rustc_hir::intravisit::{self, FnKind, NestedVisitorMap, Visitor};
-use rustc_hir::Expr;
+use rustc_hir::intravisit::FnKind;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::hir::map::Map;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::{sym, Span};
 
 declare_clippy_lint! {
-    /// **What it does:** Checks for usage of `panic!`, `unimplemented!`, `todo!` or `unreachable!` in a function of type result.
+    /// **What it does:** Checks for usage of `panic!`, `unimplemented!`, `todo!`, `unreachable!` or assertions in a function of type result.
     ///
-    /// **Why is this bad?** For some codebases, it is desirable for functions of type result to return an error instead of crashing. Hence unimplemented, panic and unreachable should be avoided.
+    /// **Why is this bad?** For some codebases, it is desirable for functions of type result to return an error instead of crashing. Hence panicking macros should be avoided.
     ///
-    /// **Known problems:** None.
+    /// **Known problems:** Functions called from a function returning a `Result` may invoke a panicking macro. This is not checked.
     ///
     /// **Example:**
     ///
@@ -22,9 +20,15 @@ declare_clippy_lint! {
     ///     panic!("error");
     /// }
     /// ```
+    /// Use instead:
+    /// ```rust
+    /// fn result_without_panic() -> Result<bool, String> {
+    ///     Err(String::from("error"))
+    /// }
+    /// ```
     pub PANIC_IN_RESULT_FN,
     restriction,
-    "functions of type `Result<..>` that contain `panic!()`, `todo!()` or `unreachable()` or `unimplemented()` "
+    "functions of type `Result<..>` that contain `panic!()`, `todo!()`, `unreachable()`, `unimplemented()` or assertion"
 }
 
 declare_lint_pass!(PanicInResultFn  => [PANIC_IN_RESULT_FN]);
@@ -47,43 +51,33 @@ impl<'tcx> LateLintPass<'tcx> for PanicInResultFn {
     }
 }
 
-struct FindPanicUnimplementedUnreachable {
-    result: Vec<Span>,
-}
-
-impl<'tcx> Visitor<'tcx> for FindPanicUnimplementedUnreachable {
-    type Map = Map<'tcx>;
-
-    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
-        if ["unimplemented", "unreachable", "panic", "todo"]
-            .iter()
-            .any(|fun| is_expn_of(expr.span, fun).is_some())
-        {
-            self.result.push(expr.span);
-        }
-        // and check sub-expressions
-        intravisit::walk_expr(self, expr);
-    }
-
-    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
-        NestedVisitorMap::None
-    }
-}
-
 fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, body: &'tcx hir::Body<'tcx>) {
-    let mut panics = FindPanicUnimplementedUnreachable { result: Vec::new() };
-    panics.visit_expr(&body.value);
-    if !panics.result.is_empty() {
+    let panics = find_macro_calls(
+        &[
+            "unimplemented",
+            "unreachable",
+            "panic",
+            "todo",
+            "assert",
+            "assert_eq",
+            "assert_ne",
+            "debug_assert",
+            "debug_assert_eq",
+            "debug_assert_ne",
+        ],
+        body,
+    );
+    if !panics.is_empty() {
         span_lint_and_then(
             cx,
             PANIC_IN_RESULT_FN,
             impl_span,
-            "used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`",
+            "used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`",
             move |diag| {
                 diag.help(
-                    "`unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing",
+                    "`unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing",
                 );
-                diag.span_note(panics.result, "return Err() instead of panicking");
+                diag.span_note(panics, "return Err() instead of panicking");
             },
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
index f03facc235e..6a17d654ac9 100644
--- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
@@ -244,9 +244,10 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
 
         // Exclude non-inherent impls
         if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
-            if matches!(item.kind, ItemKind::Impl{ of_trait: Some(_), .. } |
-            ItemKind::Trait(..))
-            {
+            if matches!(
+                item.kind,
+                ItemKind::Impl { of_trait: Some(_), .. } | ItemKind::Trait(..)
+            ) {
                 return;
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs
index 4b514bbd42c..3e454eecd97 100644
--- a/src/tools/clippy/clippy_lints/src/ranges.rs
+++ b/src/tools/clippy/clippy_lints/src/ranges.rs
@@ -3,9 +3,10 @@ use if_chain::if_chain;
 use rustc_ast::ast::RangeLimits;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, QPath};
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_semver::RustcVersion;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::{Span, Spanned};
 use rustc_span::sym;
 use rustc_span::symbol::Ident;
@@ -13,8 +14,8 @@ use std::cmp::Ordering;
 
 use crate::utils::sugg::Sugg;
 use crate::utils::{
-    get_parent_expr, is_integer_const, single_segment_path, snippet, snippet_opt, snippet_with_applicability,
-    span_lint, span_lint_and_sugg, span_lint_and_then,
+    get_parent_expr, in_constant, is_integer_const, meets_msrv, single_segment_path, snippet, snippet_opt,
+    snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then,
 };
 use crate::utils::{higher, SpanlessEq};
 
@@ -160,7 +161,20 @@ declare_clippy_lint! {
     "manually reimplementing {`Range`, `RangeInclusive`}`::contains`"
 }
 
-declare_lint_pass!(Ranges => [
+const MANUAL_RANGE_CONTAINS_MSRV: RustcVersion = RustcVersion::new(1, 35, 0);
+
+pub struct Ranges {
+    msrv: Option<RustcVersion>,
+}
+
+impl Ranges {
+    #[must_use]
+    pub fn new(msrv: Option<RustcVersion>) -> Self {
+        Self { msrv }
+    }
+}
+
+impl_lint_pass!(Ranges => [
     RANGE_ZIP_WITH_LEN,
     RANGE_PLUS_ONE,
     RANGE_MINUS_ONE,
@@ -175,7 +189,9 @@ impl<'tcx> LateLintPass<'tcx> for Ranges {
                 check_range_zip_with_len(cx, path, args, expr.span);
             },
             ExprKind::Binary(ref op, ref l, ref r) => {
-                check_possible_range_contains(cx, op.node, l, r, expr.span);
+                if meets_msrv(self.msrv.as_ref(), &MANUAL_RANGE_CONTAINS_MSRV) {
+                    check_possible_range_contains(cx, op.node, l, r, expr);
+                }
             },
             _ => {},
         }
@@ -184,9 +200,15 @@ impl<'tcx> LateLintPass<'tcx> for Ranges {
         check_inclusive_range_minus_one(cx, expr);
         check_reversed_empty_range(cx, expr);
     }
+    extract_msrv_attr!(LateContext);
 }
 
-fn check_possible_range_contains(cx: &LateContext<'_>, op: BinOpKind, l: &Expr<'_>, r: &Expr<'_>, span: Span) {
+fn check_possible_range_contains(cx: &LateContext<'_>, op: BinOpKind, l: &Expr<'_>, r: &Expr<'_>, expr: &Expr<'_>) {
+    if in_constant(cx, expr.hir_id) {
+        return;
+    }
+
+    let span = expr.span;
     let combine_and = match op {
         BinOpKind::And | BinOpKind::BitAnd => true,
         BinOpKind::Or | BinOpKind::BitOr => false,
diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
index f0e507105a6..06adbb523d7 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
@@ -390,7 +390,10 @@ impl<'tcx> mir::visit::Visitor<'tcx> for LocalUseVisitor {
         let local = place.local;
 
         if local == self.used.0
-            && !matches!(ctx, PlaceContext::MutatingUse(MutatingUseContext::Drop) | PlaceContext::NonUse(_))
+            && !matches!(
+                ctx,
+                PlaceContext::MutatingUse(MutatingUseContext::Drop) | PlaceContext::NonUse(_)
+            )
         {
             self.used.1 = true;
         }
diff --git a/src/tools/clippy/clippy_lints/src/redundant_else.rs b/src/tools/clippy/clippy_lints/src/redundant_else.rs
new file mode 100644
index 00000000000..3d585cd27a3
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/redundant_else.rs
@@ -0,0 +1,135 @@
+use crate::utils::span_lint_and_help;
+use rustc_ast::ast::{Block, Expr, ExprKind, Stmt, StmtKind};
+use rustc_ast::visit::{walk_expr, Visitor};
+use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_middle::lint::in_external_macro;
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+declare_clippy_lint! {
+    /// **What it does:** Checks for `else` blocks that can be removed without changing semantics.
+    ///
+    /// **Why is this bad?** The `else` block adds unnecessary indentation and verbosity.
+    ///
+    /// **Known problems:** Some may prefer to keep the `else` block for clarity.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust
+    /// fn my_func(count: u32) {
+    ///     if count == 0 {
+    ///         print!("Nothing to do");
+    ///         return;
+    ///     } else {
+    ///         print!("Moving on...");
+    ///     }
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// fn my_func(count: u32) {
+    ///     if count == 0 {
+    ///         print!("Nothing to do");
+    ///         return;
+    ///     }
+    ///     print!("Moving on...");
+    /// }
+    /// ```
+    pub REDUNDANT_ELSE,
+    pedantic,
+    "`else` branch that can be removed without changing semantics"
+}
+
+declare_lint_pass!(RedundantElse => [REDUNDANT_ELSE]);
+
+impl EarlyLintPass for RedundantElse {
+    fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &Stmt) {
+        if in_external_macro(cx.sess, stmt.span) {
+            return;
+        }
+        // Only look at expressions that are a whole statement
+        let expr: &Expr = match &stmt.kind {
+            StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr,
+            _ => return,
+        };
+        // if else
+        let (mut then, mut els): (&Block, &Expr) = match &expr.kind {
+            ExprKind::If(_, then, Some(els)) => (then, els),
+            _ => return,
+        };
+        loop {
+            if !BreakVisitor::default().check_block(then) {
+                // then block does not always break
+                return;
+            }
+            match &els.kind {
+                // else if else
+                ExprKind::If(_, next_then, Some(next_els)) => {
+                    then = next_then;
+                    els = next_els;
+                    continue;
+                },
+                // else if without else
+                ExprKind::If(..) => return,
+                // done
+                _ => break,
+            }
+        }
+        span_lint_and_help(
+            cx,
+            REDUNDANT_ELSE,
+            els.span,
+            "redundant else block",
+            None,
+            "remove the `else` block and move the contents out",
+        );
+    }
+}
+
+/// Call `check` functions to check if an expression always breaks control flow
+#[derive(Default)]
+struct BreakVisitor {
+    is_break: bool,
+}
+
+impl<'ast> Visitor<'ast> for BreakVisitor {
+    fn visit_block(&mut self, block: &'ast Block) {
+        self.is_break = match block.stmts.as_slice() {
+            [.., last] => self.check_stmt(last),
+            _ => false,
+        };
+    }
+
+    fn visit_expr(&mut self, expr: &'ast Expr) {
+        self.is_break = match expr.kind {
+            ExprKind::Break(..) | ExprKind::Continue(..) | ExprKind::Ret(..) => true,
+            ExprKind::Match(_, ref arms) => arms.iter().all(|arm| self.check_expr(&arm.body)),
+            ExprKind::If(_, ref then, Some(ref els)) => self.check_block(then) && self.check_expr(els),
+            ExprKind::If(_, _, None)
+            // ignore loops for simplicity
+            | ExprKind::While(..) | ExprKind::ForLoop(..) | ExprKind::Loop(..) => false,
+            _ => {
+                walk_expr(self, expr);
+                return;
+            },
+        };
+    }
+}
+
+impl BreakVisitor {
+    fn check<T>(&mut self, item: T, visit: fn(&mut Self, T)) -> bool {
+        visit(self, item);
+        std::mem::replace(&mut self.is_break, false)
+    }
+
+    fn check_block(&mut self, block: &Block) -> bool {
+        self.check(block, Self::visit_block)
+    }
+
+    fn check_expr(&mut self, expr: &Expr) -> bool {
+        self.check(expr, Self::visit_expr)
+    }
+
+    fn check_stmt(&mut self, stmt: &Stmt) -> bool {
+        self.check(stmt, Self::visit_stmt)
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
index 2a81170e49e..38dcf7a192c 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
@@ -1,9 +1,12 @@
-use crate::utils::span_lint_and_sugg;
+use crate::utils::{meets_msrv, span_lint_and_sugg};
 use rustc_ast::ast::{Expr, ExprKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_middle::lint::in_external_macro;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_semver::RustcVersion;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+
+const REDUNDANT_FIELD_NAMES_MSRV: RustcVersion = RustcVersion::new(1, 17, 0);
 
 declare_clippy_lint! {
     /// **What it does:** Checks for fields in struct literals where shorthands
@@ -33,10 +36,25 @@ declare_clippy_lint! {
     "checks for fields in struct literals where shorthands could be used"
 }
 
-declare_lint_pass!(RedundantFieldNames => [REDUNDANT_FIELD_NAMES]);
+pub struct RedundantFieldNames {
+    msrv: Option<RustcVersion>,
+}
+
+impl RedundantFieldNames {
+    #[must_use]
+    pub fn new(msrv: Option<RustcVersion>) -> Self {
+        Self { msrv }
+    }
+}
+
+impl_lint_pass!(RedundantFieldNames => [REDUNDANT_FIELD_NAMES]);
 
 impl EarlyLintPass for RedundantFieldNames {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
+        if !meets_msrv(self.msrv.as_ref(), &REDUNDANT_FIELD_NAMES_MSRV) {
+            return;
+        }
+
         if in_external_macro(cx.sess, expr.span) {
             return;
         }
@@ -64,4 +82,5 @@ impl EarlyLintPass for RedundantFieldNames {
             }
         }
     }
+    extract_msrv_attr!(EarlyContext);
 }
diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
index 7bbcc67aa2d..fcfa3c12755 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
@@ -1,8 +1,11 @@
-use crate::utils::{snippet, span_lint_and_then};
+use crate::utils::{meets_msrv, snippet, span_lint_and_then};
 use rustc_ast::ast::{Item, ItemKind, Ty, TyKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_semver::RustcVersion;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+
+const REDUNDANT_STATIC_LIFETIMES_MSRV: RustcVersion = RustcVersion::new(1, 17, 0);
 
 declare_clippy_lint! {
     /// **What it does:** Checks for constants and statics with an explicit `'static` lifetime.
@@ -29,7 +32,18 @@ declare_clippy_lint! {
     "Using explicit `'static` lifetime for constants or statics when elision rules would allow omitting them."
 }
 
-declare_lint_pass!(RedundantStaticLifetimes => [REDUNDANT_STATIC_LIFETIMES]);
+pub struct RedundantStaticLifetimes {
+    msrv: Option<RustcVersion>,
+}
+
+impl RedundantStaticLifetimes {
+    #[must_use]
+    pub fn new(msrv: Option<RustcVersion>) -> Self {
+        Self { msrv }
+    }
+}
+
+impl_lint_pass!(RedundantStaticLifetimes => [REDUNDANT_STATIC_LIFETIMES]);
 
 impl RedundantStaticLifetimes {
     // Recursively visit types
@@ -84,6 +98,10 @@ impl RedundantStaticLifetimes {
 
 impl EarlyLintPass for RedundantStaticLifetimes {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
+        if !meets_msrv(self.msrv.as_ref(), &REDUNDANT_STATIC_LIFETIMES_MSRV) {
+            return;
+        }
+
         if !item.span.from_expansion() {
             if let ItemKind::Const(_, ref var_type, _) = item.kind {
                 self.visit_type(var_type, cx, "constants have by default a `'static` lifetime");
@@ -96,4 +114,6 @@ impl EarlyLintPass for RedundantStaticLifetimes {
             }
         }
     }
+
+    extract_msrv_attr!(EarlyContext);
 }
diff --git a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs
index a914a77d48b..803ebada54b 100644
--- a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs
@@ -2,6 +2,7 @@ use crate::utils::{last_path_segment, snippet, span_lint_and_sugg};
 use rustc_hir::{GenericArg, Mutability, Ty, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::symbol::sym;
 
 use if_chain::if_chain;
 use rustc_errors::Applicability;
@@ -41,7 +42,7 @@ impl<'tcx> LateLintPass<'tcx> for RefOptionRef {
             if let Some(res) = last.res;
             if let Some(def_id) = res.opt_def_id();
 
-            if cx.tcx.is_diagnostic_item(sym!(option_type), def_id);
+            if cx.tcx.is_diagnostic_item(sym::option_type, def_id);
             if let Some(ref params) = last_path_segment(qpath).args ;
             if !params.parenthesized;
             if let Some(inner_ty) = params.args.iter().find_map(|arg| match arg {
diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs
index 225fe58906f..f8396592678 100644
--- a/src/tools/clippy/clippy_lints/src/shadow.rs
+++ b/src/tools/clippy/clippy_lints/src/shadow.rs
@@ -342,6 +342,10 @@ fn check_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, bindings: &mut
                 if let Some(ref guard) = arm.guard {
                     match guard {
                         Guard::If(if_expr) => check_expr(cx, if_expr, bindings),
+                        Guard::IfLet(guard_pat, guard_expr) => {
+                            check_pat(cx, guard_pat, Some(*guard_expr), guard_pat.span, bindings);
+                            check_expr(cx, guard_expr, bindings);
+                        },
                     }
                 }
                 check_expr(cx, &arm.body, bindings);
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index 77e79073378..31dd5965473 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -372,7 +372,7 @@ impl LateLintPass<'_> for StringToString {
             if let ExprKind::MethodCall(path, _, args, _) = &expr.kind;
             if path.ident.name == sym!(to_string);
             let ty = cx.typeck_results().expr_ty(&args[0]);
-            if is_type_diagnostic_item(cx, ty, sym!(string_type));
+            if is_type_diagnostic_item(cx, ty, sym::string_type);
             then {
                 span_lint_and_help(
                     cx,
diff --git a/src/tools/clippy/clippy_lints/src/types.rs b/src/tools/clippy/clippy_lints/src/types.rs
index 74ba53e6a9a..fd74783335d 100644
--- a/src/tools/clippy/clippy_lints/src/types.rs
+++ b/src/tools/clippy/clippy_lints/src/types.rs
@@ -1104,7 +1104,9 @@ fn is_empty_block(expr: &Expr<'_>) -> bool {
         expr.kind,
         ExprKind::Block(
             Block {
-                stmts: &[], expr: None, ..
+                stmts: &[],
+                expr: None,
+                ..
             },
             _,
         )
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
index 5d801511a0b..5b9a80f92db 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
@@ -9,6 +9,7 @@ use rustc_hir::{Body, ExprKind, FnDecl, HirId, ItemKind, Node};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::symbol::sym;
 use rustc_span::Span;
 
 declare_clippy_lint! {
@@ -74,14 +75,17 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
         }
 
         if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
-            if matches!(item.kind, ItemKind::Impl{ of_trait: Some(_), ..} | ItemKind::Trait(..)) {
+            if matches!(
+                item.kind,
+                ItemKind::Impl { of_trait: Some(_), .. } | ItemKind::Trait(..)
+            ) {
                 return;
             }
         }
 
-        let (return_type, path) = if is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym!(option_type)) {
+        let (return_type, path) = if is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::option_type) {
             ("Option", &paths::OPTION_SOME)
-        } else if is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym!(result_type)) {
+        } else if is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::result_type) {
             ("Result", &paths::RESULT_OK)
         } else {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index 5ac4797680b..3b23f885e08 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -12,11 +12,12 @@ use rustc_middle::hir::map::Map;
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_middle::ty::{DefIdTree, Ty};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_semver::RustcVersion;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::kw;
 use rustc_typeck::hir_ty_to_ty;
 
-use crate::utils::{differing_macro_contexts, span_lint_and_sugg};
+use crate::utils::{differing_macro_contexts, meets_msrv, span_lint_and_sugg};
 
 declare_clippy_lint! {
     /// **What it does:** Checks for unnecessary repetition of structure name when a
@@ -53,7 +54,7 @@ declare_clippy_lint! {
     "unnecessary structure name repetition whereas `Self` is applicable"
 }
 
-declare_lint_pass!(UseSelf => [USE_SELF]);
+impl_lint_pass!(UseSelf => [USE_SELF]);
 
 const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element";
 
@@ -157,8 +158,25 @@ fn check_trait_method_impl_decl<'tcx>(
     }
 }
 
+const USE_SELF_MSRV: RustcVersion = RustcVersion::new(1, 37, 0);
+
+pub struct UseSelf {
+    msrv: Option<RustcVersion>,
+}
+
+impl UseSelf {
+    #[must_use]
+    pub fn new(msrv: Option<RustcVersion>) -> Self {
+        Self { msrv }
+    }
+}
+
 impl<'tcx> LateLintPass<'tcx> for UseSelf {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
+        if !meets_msrv(self.msrv.as_ref(), &USE_SELF_MSRV) {
+            return;
+        }
+
         if in_external_macro(cx.sess(), item.span) {
             return;
         }
@@ -204,6 +222,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
             }
         }
     }
+    extract_msrv_attr!(LateContext);
 }
 
 struct UseSelfVisitor<'a, 'tcx> {
diff --git a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs
index 31b4e25411b..f0267e4c792 100644
--- a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs
@@ -408,7 +408,10 @@ pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool {
 }
 
 pub fn eq_defaultness(l: Defaultness, r: Defaultness) -> bool {
-    matches!((l, r), (Defaultness::Final, Defaultness::Final) | (Defaultness::Default(_), Defaultness::Default(_)))
+    matches!(
+        (l, r),
+        (Defaultness::Final, Defaultness::Final) | (Defaultness::Default(_), Defaultness::Default(_))
+    )
 }
 
 pub fn eq_vis(l: &Visibility, r: &Visibility) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 7250de3a41c..4249dbb4e65 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -372,6 +372,18 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
                                 self.current = if_expr_pat;
                                 self.visit_expr(if_expr);
                             },
+                            hir::Guard::IfLet(ref if_let_pat, ref if_let_expr) => {
+                                let if_let_pat_pat = self.next("pat");
+                                let if_let_expr_pat = self.next("expr");
+                                println!(
+                                    "    if let Guard::IfLet(ref {}, ref {}) = {};",
+                                    if_let_pat_pat, if_let_expr_pat, guard_pat
+                                );
+                                self.current = if_let_expr_pat;
+                                self.visit_expr(if_let_expr);
+                                self.current = if_let_pat_pat;
+                                self.visit_pat(if_let_pat);
+                            },
                         }
                     }
                     self.current = format!("{}[{}].pat", arms_pat, i);
@@ -730,6 +742,7 @@ fn desugaring_name(des: hir::MatchSource) -> String {
             "MatchSource::IfLetDesugar {{ contains_else_clause: {} }}",
             contains_else_clause
         ),
+        hir::MatchSource::IfLetGuardDesugar => "MatchSource::IfLetGuardDesugar".to_string(),
         hir::MatchSource::IfDesugar { contains_else_clause } => format!(
             "MatchSource::IfDesugar {{ contains_else_clause: {} }}",
             contains_else_clause
diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs
index 6403ff6dad1..32d7840a451 100644
--- a/src/tools/clippy/clippy_lints/src/utils/conf.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs
@@ -106,7 +106,7 @@ macro_rules! define_Conf {
 
 pub use self::helpers::Conf;
 define_Conf! {
-    /// Lint: MANUAL_NON_EXHAUSTIVE, MANUAL_STRIP, OPTION_AS_REF_DEREF, MATCH_LIKE_MATCHES_MACRO. The minimum rust version that the project supports
+    /// Lint: REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN. The minimum rust version that the project supports
     (msrv, "msrv": Option<String>, None),
     /// Lint: BLACKLISTED_NAME. The list of blacklisted names to lint about. NB: `bar` is not here since it has legitimate uses
     (blacklisted_names, "blacklisted_names": Vec<String>, ["foo", "baz", "quux"].iter().map(ToString::to_string).collect()),
diff --git a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs
index d942d4e12b1..a8fbb2ffaf0 100644
--- a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs
@@ -169,6 +169,8 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> {
     fn eq_guard(&mut self, left: &Guard<'_>, right: &Guard<'_>) -> bool {
         match (left, right) {
             (Guard::If(l), Guard::If(r)) => self.eq_expr(l, r),
+            (Guard::IfLet(lp, le), Guard::IfLet(rp, re)) => self.eq_pat(lp, rp) && self.eq_expr(le, re),
+            _ => false,
         }
     }
 
@@ -669,7 +671,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
 
     pub fn hash_guard(&mut self, g: &Guard<'_>) {
         match g {
-            Guard::If(ref expr) => {
+            Guard::If(ref expr) | Guard::IfLet(_, ref expr) => {
                 self.hash_expr(expr);
             },
         }
diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs
index 323d8745538..5d946e4bd49 100644
--- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs
@@ -560,5 +560,10 @@ fn print_guard(cx: &LateContext<'_>, guard: &hir::Guard<'_>, indent: usize) {
             println!("{}If", ind);
             print_expr(cx, expr, indent + 1);
         },
+        hir::Guard::IfLet(pat, expr) => {
+            println!("{}IfLet", ind);
+            print_pat(cx, pat, indent + 1);
+            print_expr(cx, expr, indent + 1);
+        },
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
index 8b59a9541a7..9ba39f73ee8 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
@@ -15,6 +15,7 @@ use rustc_hir::intravisit::{NestedVisitorMap, Visitor};
 use rustc_hir::{Crate, Expr, ExprKind, HirId, Item, MutTy, Mutability, Node, Path, StmtKind, Ty, TyKind};
 use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
 use rustc_middle::hir::map::Map;
+use rustc_middle::mir::interpret::ConstValue;
 use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::{Span, Spanned};
@@ -247,6 +248,30 @@ declare_clippy_lint! {
     "invalid path"
 }
 
+declare_clippy_lint! {
+    /// **What it does:**
+    /// Checks for interning symbols that have already been pre-interned and defined as constants.
+    ///
+    /// **Why is this bad?**
+    /// It's faster and easier to use the symbol constant.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    /// Bad:
+    /// ```rust,ignore
+    /// let _ = sym!(f32);
+    /// ```
+    ///
+    /// Good:
+    /// ```rust,ignore
+    /// let _ = sym::f32;
+    /// ```
+    pub INTERNING_DEFINED_SYMBOL,
+    internal,
+    "interning a symbol that is pre-interned and defined as a constant"
+}
+
 declare_lint_pass!(ClippyLintsInternal => [CLIPPY_LINTS_INTERNAL]);
 
 impl EarlyLintPass for ClippyLintsInternal {
@@ -840,3 +865,56 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths {
         }
     }
 }
+
+#[derive(Default)]
+pub struct InterningDefinedSymbol {
+    // Maps the symbol value to the constant name.
+    symbol_map: FxHashMap<u32, String>,
+}
+
+impl_lint_pass!(InterningDefinedSymbol => [INTERNING_DEFINED_SYMBOL]);
+
+impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
+    fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
+        if !self.symbol_map.is_empty() {
+            return;
+        }
+
+        if let Some(Res::Def(_, def_id)) = path_to_res(cx, &paths::SYM_MODULE) {
+            for item in cx.tcx.item_children(def_id).iter() {
+                if_chain! {
+                    if let Res::Def(DefKind::Const, item_def_id) = item.res;
+                    let ty = cx.tcx.type_of(item_def_id);
+                    if match_type(cx, ty, &paths::SYMBOL);
+                    if let Ok(ConstValue::Scalar(value)) = cx.tcx.const_eval_poly(item_def_id);
+                    if let Ok(value) = value.to_u32();
+                    then {
+                        self.symbol_map.insert(value, item.ident.to_string());
+                    }
+                }
+            }
+        }
+    }
+
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        if_chain! {
+            if let ExprKind::Call(func, [arg]) = &expr.kind;
+            if let ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(func).kind();
+            if match_def_path(cx, *def_id, &paths::SYMBOL_INTERN);
+            if let Some(Constant::Str(arg)) = constant_simple(cx, cx.typeck_results(), arg);
+            let value = Symbol::intern(&arg).as_u32();
+            if let Some(symbol_const) = self.symbol_map.get(&value);
+            then {
+                span_lint_and_sugg(
+                    cx,
+                    INTERNING_DEFINED_SYMBOL,
+                    is_expn_of(expr.span, "sym").unwrap_or(expr.span),
+                    "interning a defined symbol",
+                    "try",
+                    format!("rustc_span::symbol::sym::{}", symbol_const),
+                    Applicability::MachineApplicable,
+                );
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs
index 3a6b64c90e8..424856090f2 100644
--- a/src/tools/clippy/clippy_lints/src/utils/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs
@@ -41,7 +41,7 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
-use rustc_hir::intravisit::{NestedVisitorMap, Visitor};
+use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::Node;
 use rustc_hir::{
     def, Arm, Block, Body, Constness, Crate, Expr, ExprKind, FnDecl, HirId, ImplItem, ImplItemKind, Item, ItemKind,
@@ -603,6 +603,37 @@ pub fn contains_return(expr: &hir::Expr<'_>) -> bool {
     visitor.found
 }
 
+struct FindMacroCalls<'a, 'b> {
+    names: &'a [&'b str],
+    result: Vec<Span>,
+}
+
+impl<'a, 'b, 'tcx> Visitor<'tcx> for FindMacroCalls<'a, 'b> {
+    type Map = Map<'tcx>;
+
+    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
+        if self.names.iter().any(|fun| is_expn_of(expr.span, fun).is_some()) {
+            self.result.push(expr.span);
+        }
+        // and check sub-expressions
+        intravisit::walk_expr(self, expr);
+    }
+
+    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
+        NestedVisitorMap::None
+    }
+}
+
+/// Finds calls of the specified macros in a function body.
+pub fn find_macro_calls(names: &[&str], body: &Body<'_>) -> Vec<Span> {
+    let mut fmc = FindMacroCalls {
+        names,
+        result: Vec::new(),
+    };
+    fmc.visit_expr(&body.value);
+    fmc.result
+}
+
 /// Converts a span to a code snippet if available, otherwise use default.
 ///
 /// This is useful if you want to provide suggestions for your lint or more generally, if you want
@@ -1449,8 +1480,8 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
             false
         },
         ty::Dynamic(binder, _) => {
-            for predicate in binder.skip_binder().iter() {
-                if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate {
+            for predicate in binder.iter() {
+                if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
                     if must_use_attr(&cx.tcx.get_attrs(trait_ref.def_id)).is_some() {
                         return true;
                     }
@@ -1500,7 +1531,7 @@ pub fn is_no_std_crate(krate: &Crate<'_>) -> bool {
 /// ```
 pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool {
     if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
-        matches!(item.kind, ItemKind::Impl{ of_trait: Some(_), .. })
+        matches!(item.kind, ItemKind::Impl { of_trait: Some(_), .. })
     } else {
         false
     }
diff --git a/src/tools/clippy/clippy_lints/src/utils/paths.rs b/src/tools/clippy/clippy_lints/src/utils/paths.rs
index 6fdc7b4587f..2080a49a11c 100644
--- a/src/tools/clippy/clippy_lints/src/utils/paths.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/paths.rs
@@ -146,6 +146,12 @@ pub const STR_FROM_UTF8: [&str; 4] = ["core", "str", "converts", "from_utf8"];
 pub const STR_LEN: [&str; 4] = ["core", "str", "<impl str>", "len"];
 pub const STR_STARTS_WITH: [&str; 4] = ["core", "str", "<impl str>", "starts_with"];
 #[cfg(feature = "internal-lints")]
+pub const SYMBOL: [&str; 3] = ["rustc_span", "symbol", "Symbol"];
+#[cfg(feature = "internal-lints")]
+pub const SYMBOL_INTERN: [&str; 4] = ["rustc_span", "symbol", "Symbol", "intern"];
+#[cfg(feature = "internal-lints")]
+pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"];
+#[cfg(feature = "internal-lints")]
 pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
 pub const TO_OWNED: [&str; 3] = ["alloc", "borrow", "ToOwned"];
 pub const TO_OWNED_METHOD: [&str; 4] = ["alloc", "borrow", "ToOwned", "to_owned"];
diff --git a/src/tools/clippy/clippy_lints/src/utils/usage.rs b/src/tools/clippy/clippy_lints/src/utils/usage.rs
index a7d0ea6ccfb..fc0db7f64ec 100644
--- a/src/tools/clippy/clippy_lints/src/utils/usage.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/usage.rs
@@ -116,20 +116,27 @@ pub struct ParamBindingIdCollector {
 }
 impl<'tcx> ParamBindingIdCollector {
     fn collect_binding_hir_ids(body: &'tcx hir::Body<'tcx>) -> Vec<hir::HirId> {
-        let mut finder = ParamBindingIdCollector {
-            binding_hir_ids: Vec::new(),
-        };
-        finder.visit_body(body);
-        finder.binding_hir_ids
+        let mut hir_ids: Vec<hir::HirId> = Vec::new();
+        for param in body.params.iter() {
+            let mut finder = ParamBindingIdCollector {
+                binding_hir_ids: Vec::new(),
+            };
+            finder.visit_param(param);
+            for hir_id in &finder.binding_hir_ids {
+                hir_ids.push(*hir_id);
+            }
+        }
+        hir_ids
     }
 }
 impl<'tcx> intravisit::Visitor<'tcx> for ParamBindingIdCollector {
     type Map = Map<'tcx>;
 
-    fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
-        if let hir::PatKind::Binding(_, hir_id, ..) = param.pat.kind {
+    fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
+        if let hir::PatKind::Binding(_, hir_id, ..) = pat.kind {
             self.binding_hir_ids.push(hir_id);
         }
+        intravisit::walk_pat(self, pat);
     }
 
     fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index ff414f748ef..337f7a229b9 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -76,6 +76,24 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
+    /// **What it does:** Checks for printing on *stderr*. The purpose of this lint
+    /// is to catch debugging remnants.
+    ///
+    /// **Why is this bad?** People often print on *stderr* while debugging an
+    /// application and might forget to remove those prints afterward.
+    ///
+    /// **Known problems:** Only catches `eprint!` and `eprintln!` calls.
+    ///
+    /// **Example:**
+    /// ```rust
+    /// eprintln!("Hello world!");
+    /// ```
+    pub PRINT_STDERR,
+    restriction,
+    "printing on stderr"
+}
+
+declare_clippy_lint! {
     /// **What it does:** Checks for use of `Debug` formatting. The purpose of this
     /// lint is to catch debugging remnants.
     ///
@@ -201,6 +219,7 @@ impl_lint_pass!(Write => [
     PRINT_WITH_NEWLINE,
     PRINTLN_EMPTY_STRING,
     PRINT_STDOUT,
+    PRINT_STDERR,
     USE_DEBUG,
     PRINT_LITERAL,
     WRITE_WITH_NEWLINE,
@@ -243,47 +262,22 @@ impl EarlyLintPass for Write {
                 .map_or(false, |crate_name| crate_name == "build_script_build")
         }
 
-        if mac.path == sym!(println) {
-            if !is_build_script(cx) {
-                span_lint(cx, PRINT_STDOUT, mac.span(), "use of `println!`");
-            }
-            if let (Some(fmt_str), _) = self.check_tts(cx, mac.args.inner_tokens(), false) {
-                if fmt_str.symbol == Symbol::intern("") {
-                    span_lint_and_sugg(
-                        cx,
-                        PRINTLN_EMPTY_STRING,
-                        mac.span(),
-                        "using `println!(\"\")`",
-                        "replace it with",
-                        "println!()".to_string(),
-                        Applicability::MachineApplicable,
-                    );
-                }
-            }
-        } else if mac.path == sym!(print) {
+        if mac.path == sym!(print) {
             if !is_build_script(cx) {
                 span_lint(cx, PRINT_STDOUT, mac.span(), "use of `print!`");
             }
-            if let (Some(fmt_str), _) = self.check_tts(cx, mac.args.inner_tokens(), false) {
-                if check_newlines(&fmt_str) {
-                    span_lint_and_then(
-                        cx,
-                        PRINT_WITH_NEWLINE,
-                        mac.span(),
-                        "using `print!()` with a format string that ends in a single newline",
-                        |err| {
-                            err.multipart_suggestion(
-                                "use `println!` instead",
-                                vec![
-                                    (mac.path.span, String::from("println")),
-                                    (newline_span(&fmt_str), String::new()),
-                                ],
-                                Applicability::MachineApplicable,
-                            );
-                        },
-                    );
-                }
+            self.lint_print_with_newline(cx, mac);
+        } else if mac.path == sym!(println) {
+            if !is_build_script(cx) {
+                span_lint(cx, PRINT_STDOUT, mac.span(), "use of `println!`");
             }
+            self.lint_println_empty_string(cx, mac);
+        } else if mac.path == sym!(eprint) {
+            span_lint(cx, PRINT_STDERR, mac.span(), "use of `eprint!`");
+            self.lint_print_with_newline(cx, mac);
+        } else if mac.path == sym!(eprintln) {
+            span_lint(cx, PRINT_STDERR, mac.span(), "use of `eprintln!`");
+            self.lint_println_empty_string(cx, mac);
         } else if mac.path == sym!(write) {
             if let (Some(fmt_str), _) = self.check_tts(cx, mac.args.inner_tokens(), true) {
                 if check_newlines(&fmt_str) {
@@ -487,6 +481,45 @@ impl Write {
             }
         }
     }
+
+    fn lint_println_empty_string(&self, cx: &EarlyContext<'_>, mac: &MacCall) {
+        if let (Some(fmt_str), _) = self.check_tts(cx, mac.args.inner_tokens(), false) {
+            if fmt_str.symbol == Symbol::intern("") {
+                let name = mac.path.segments[0].ident.name;
+                span_lint_and_sugg(
+                    cx,
+                    PRINTLN_EMPTY_STRING,
+                    mac.span(),
+                    &format!("using `{}!(\"\")`", name),
+                    "replace it with",
+                    format!("{}!()", name),
+                    Applicability::MachineApplicable,
+                );
+            }
+        }
+    }
+
+    fn lint_print_with_newline(&self, cx: &EarlyContext<'_>, mac: &MacCall) {
+        if let (Some(fmt_str), _) = self.check_tts(cx, mac.args.inner_tokens(), false) {
+            if check_newlines(&fmt_str) {
+                let name = mac.path.segments[0].ident.name;
+                let suggested = format!("{}ln", name);
+                span_lint_and_then(
+                    cx,
+                    PRINT_WITH_NEWLINE,
+                    mac.span(),
+                    &format!("using `{}!()` with a format string that ends in a single newline", name),
+                    |err| {
+                        err.multipart_suggestion(
+                            &format!("use `{}!` instead", suggested),
+                            vec![(mac.path.span, suggested), (newline_span(&fmt_str), String::new())],
+                            Applicability::MachineApplicable,
+                        );
+                    },
+                );
+            }
+        }
+    }
 }
 
 /// Checks if the format string contains a single newline that terminates it.
diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs
new file mode 100644
index 00000000000..1d5fa8d06a9
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs
@@ -0,0 +1,82 @@
+use if_chain::if_chain;
+use rustc_hir::{self as hir, HirId, ItemKind, Node};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::{Adt, Ty};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_target::abi::LayoutOf as _;
+use rustc_typeck::hir_ty_to_ty;
+
+use crate::utils::{is_type_diagnostic_item, match_type, paths, span_lint_and_help};
+
+declare_clippy_lint! {
+    /// **What it does:** Checks for maps with zero-sized value types anywhere in the code.
+    ///
+    /// **Why is this bad?** Since there is only a single value for a zero-sized type, a map
+    /// containing zero sized values is effectively a set. Using a set in that case improves
+    /// readability and communicates intent more clearly.
+    ///
+    /// **Known problems:**
+    /// * A zero-sized type cannot be recovered later if it contains private fields.
+    /// * This lints the signature of public items
+    ///
+    /// **Example:**
+    ///
+    /// ```rust
+    /// # use std::collections::HashMap;
+    /// fn unique_words(text: &str) -> HashMap<&str, ()> {
+    ///     todo!();
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// # use std::collections::HashSet;
+    /// fn unique_words(text: &str) -> HashSet<&str> {
+    ///     todo!();
+    /// }
+    /// ```
+    pub ZERO_SIZED_MAP_VALUES,
+    pedantic,
+    "usage of map with zero-sized value type"
+}
+
+declare_lint_pass!(ZeroSizedMapValues => [ZERO_SIZED_MAP_VALUES]);
+
+impl LateLintPass<'_> for ZeroSizedMapValues {
+    fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) {
+        if_chain! {
+            if !hir_ty.span.from_expansion();
+            if !in_trait_impl(cx, hir_ty.hir_id);
+            let ty = ty_from_hir_ty(cx, hir_ty);
+            if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) || match_type(cx, ty, &paths::BTREEMAP);
+            if let Adt(_, ref substs) = ty.kind();
+            let ty = substs.type_at(1);
+            if let Ok(layout) = cx.layout_of(ty);
+            if layout.is_zst();
+            then {
+                span_lint_and_help(cx, ZERO_SIZED_MAP_VALUES, hir_ty.span, "map with zero-sized value type", None, "consider using a set instead");
+            }
+        }
+    }
+}
+
+fn in_trait_impl(cx: &LateContext<'_>, hir_id: HirId) -> bool {
+    let parent_id = cx.tcx.hir().get_parent_item(hir_id);
+    if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_item(parent_id)) {
+        if let ItemKind::Impl { of_trait: Some(_), .. } = item.kind {
+            return true;
+        }
+    }
+    false
+}
+
+fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> {
+    cx.maybe_typeck_results()
+        .and_then(|results| {
+            if results.hir_owner == hir_ty.hir_id.owner {
+                results.node_type_opt(hir_ty.hir_id)
+            } else {
+                None
+            }
+        })
+        .unwrap_or_else(|| hir_ty_to_ty(cx.tcx, hir_ty))
+}
diff --git a/src/tools/clippy/clippy_workspace_tests/path_dep/Cargo.toml b/src/tools/clippy/clippy_workspace_tests/path_dep/Cargo.toml
new file mode 100644
index 00000000000..85a91cd2dec
--- /dev/null
+++ b/src/tools/clippy/clippy_workspace_tests/path_dep/Cargo.toml
@@ -0,0 +1,3 @@
+[package]
+name = "path_dep"
+version = "0.1.0"
diff --git a/src/tools/clippy/clippy_workspace_tests/path_dep/src/lib.rs b/src/tools/clippy/clippy_workspace_tests/path_dep/src/lib.rs
new file mode 100644
index 00000000000..35ce524f2b1
--- /dev/null
+++ b/src/tools/clippy/clippy_workspace_tests/path_dep/src/lib.rs
@@ -0,0 +1,6 @@
+#![deny(clippy::empty_loop)]
+
+#[cfg(feature = "primary_package_test")]
+pub fn lint_me() {
+    loop {}
+}
diff --git a/src/tools/clippy/clippy_workspace_tests/subcrate/Cargo.toml b/src/tools/clippy/clippy_workspace_tests/subcrate/Cargo.toml
index 83ea5868160..45362c11b85 100644
--- a/src/tools/clippy/clippy_workspace_tests/subcrate/Cargo.toml
+++ b/src/tools/clippy/clippy_workspace_tests/subcrate/Cargo.toml
@@ -1,3 +1,6 @@
 [package]
 name = "subcrate"
 version = "0.1.0"
+
+[dependencies]
+path_dep = { path = "../path_dep" }
diff --git a/src/tools/clippy/doc/adding_lints.md b/src/tools/clippy/doc/adding_lints.md
index b1dacfc9c6d..60dfdb76650 100644
--- a/src/tools/clippy/doc/adding_lints.md
+++ b/src/tools/clippy/doc/adding_lints.md
@@ -98,12 +98,12 @@ While we are working on implementing our lint, we can keep running the UI
 test. That allows us to check if the output is turning into what we want.
 
 Once we are satisfied with the output, we need to run
-`tests/ui/update-all-references.sh` to update the `.stderr` file for our lint.
+`cargo dev bless` to update the `.stderr` file for our lint.
 Please note that, we should run `TESTNAME=foo_functions cargo uitest`
-every time before running `tests/ui/update-all-references.sh`.
+every time before running `cargo dev bless`.
 Running `TESTNAME=foo_functions cargo uitest` should pass then. When we commit
 our lint, we need to commit the generated `.stderr` files, too. In general, you
-should only commit files changed by `tests/ui/update-all-references.sh` for the
+should only commit files changed by `cargo dev bless` for the
 specific lint you are creating/editing. Note that if the generated files are
 empty, they should be removed.
 
@@ -122,8 +122,7 @@ we will find by default two new crates, each with its manifest file:
 If you need more cases, you can copy one of those crates (under `foo_categories`) and rename it.
 
 The process of generating the `.stderr` file is the same, and prepending the `TESTNAME`
-variable to `cargo uitest` works too, but the script to update the references
-is in another path: `tests/ui-cargo/update-all-references.sh`.
+variable to `cargo uitest` works too.
 
 ## Rustfix tests
 
@@ -133,7 +132,7 @@ additionally run [rustfix] for that test. Rustfix will apply the suggestions
 from the lint to the code of the test file and compare that to the contents of
 a `.fixed` file.
 
-Use `tests/ui/update-all-references.sh` to automatically generate the
+Use `cargo dev bless` to automatically generate the
 `.fixed` file after running the tests.
 
 [rustfix]: https://github.com/rust-lang/rustfix
@@ -226,13 +225,13 @@ store.register_early_pass(|| box foo_functions::FooFunctions);
 ```
 
 As one may expect, there is a corresponding `register_late_pass` method
-available as well. Without a call to one of `register_early_pass` or 
+available as well. Without a call to one of `register_early_pass` or
 `register_late_pass`, the lint pass in question will not be run.
 
-One reason that `cargo dev` does not automate this step is that multiple lints 
+One reason that `cargo dev` does not automate this step is that multiple lints
 can use the same lint pass, so registering the lint pass may already be done
 when adding a new lint. Another reason that this step is not automated is that
-the order that the passes are registered determines the order the passes 
+the order that the passes are registered determines the order the passes
 actually run, which in turn affects the order that any emitted lints are output
 in.
 
@@ -368,7 +367,7 @@ fn is_foo_fn(fn_kind: FnKind<'_>) -> bool {
 
 Now we should also run the full test suite with `cargo test`. At this point
 running `cargo test` should produce the expected output. Remember to run
-`tests/ui/update-all-references.sh` to update the `.stderr` file.
+`cargo dev bless` to update the `.stderr` file.
 
 `cargo test` (as opposed to `cargo uitest`) will also ensure that our lint
 implementation is not violating any Clippy lints itself.
@@ -380,6 +379,57 @@ pass.
 [`FnKind::Fn`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/visit/enum.FnKind.html#variant.Fn
 [ident]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Ident.html
 
+## Specifying the lint's minimum supported Rust version (msrv)
+
+Projects supporting older versions of Rust would need to disable a lint if it targets features
+present in later versions. Support for this can be added by specifying an msrv in your lint like so,
+
+```rust
+const MANUAL_STRIP_MSRV: RustcVersion = RustcVersion::new(1, 45, 0);
+```
+
+The project's msrv will also have to be an attribute in the lint so you'll have to add a struct
+and constructor for your lint. The project's msrv needs to be passed when the lint is registered
+in `lib.rs`
+
+```rust
+pub struct ManualStrip {
+    msrv: Option<RustcVersion>,
+}
+
+impl ManualStrip {
+    #[must_use]
+    pub fn new(msrv: Option<RustcVersion>) -> Self {
+        Self { msrv }
+    }
+}
+```
+
+The project's msrv can then be matched against the lint's msrv in the LintPass using the `meets_msrv` utility
+function.
+
+``` rust
+if !meets_msrv(self.msrv.as_ref(), &MANUAL_STRIP_MSRV) {
+    return;
+}
+```
+
+The project's msrv can also be specified as an inner attribute, which overrides the value from
+`clippy.toml`. This can be accounted for using the `extract_msrv_attr!(LintContext)` macro and passing
+LateContext/EarlyContext.
+
+```rust
+impl<'tcx> LateLintPass<'tcx> for ManualStrip {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        ...
+    }
+    extract_msrv_attr!(LateContext);
+}
+```
+
+Once the msrv is added to the lint, a relevant test case should be added to `tests/ui/min_rust_version_attr.rs`
+which verifies that the lint isn't emitted if the project's msrv is lower.
+
 ## Author lint
 
 If you have trouble implementing your lint, there is also the internal `author`
diff --git a/src/tools/clippy/doc/basics.md b/src/tools/clippy/doc/basics.md
index f25edb793e2..954474a17aa 100644
--- a/src/tools/clippy/doc/basics.md
+++ b/src/tools/clippy/doc/basics.md
@@ -1,16 +1,14 @@
 # Basics for hacking on Clippy
 
 This document explains the basics for hacking on Clippy. Besides others, this
-includes how to set-up the development environment, how to build and how to test
-Clippy. For a more in depth description on the codebase take a look at [Adding
-Lints] or [Common Tools].
+includes how to build and test Clippy. For a more in depth description on
+the codebase take a look at [Adding Lints] or [Common Tools].
 
 [Adding Lints]: https://github.com/rust-lang/rust-clippy/blob/master/doc/adding_lints.md
 [Common Tools]: https://github.com/rust-lang/rust-clippy/blob/master/doc/common_tools_writing_lints.md
 
 - [Basics for hacking on Clippy](#basics-for-hacking-on-clippy)
-  - [Get the code](#get-the-code)
-  - [Setup](#setup)
+  - [Get the Code](#get-the-code)
   - [Building and Testing](#building-and-testing)
   - [`cargo dev`](#cargo-dev)
   - [PR](#pr)
@@ -38,29 +36,9 @@ git rebase upstream/master
 git push
 ```
 
-## Setup
-
-Next we need to setup the toolchain to compile Clippy. Since Clippy heavily
-relies on compiler internals it is build with the latest rustc master. To get
-this toolchain, you can just use the `setup-toolchain.sh` script or use
-`rustup-toolchain-install-master`:
-
-```bash
-bash setup-toolchain.sh
-# OR
-cargo install rustup-toolchain-install-master
-# For better IDE integration also add `-c rustfmt -c rust-src` (optional)
-rustup-toolchain-install-master -f -n master -c rustc-dev -c llvm-tools
-rustup override set master
-```
-
-_Note:_ Sometimes you may get compiler errors when building Clippy, even if you
-didn't change anything. Normally those will be fixed by a maintainer in a few hours. 
-
 ## Building and Testing
 
-Once the `master` toolchain is installed, you can build and test Clippy like
-every other Rust project:
+You can build and test Clippy like every other Rust project:
 
 ```bash
 cargo build  # builds Clippy
@@ -83,7 +61,7 @@ If the output of a [UI test] differs from the expected output, you can update th
 reference file with:
 
 ```bash
-sh tests/ui/update-all-references.sh
+cargo dev bless
 ```
 
 For example, this is necessary, if you fix a typo in an error message of a lint
@@ -109,7 +87,7 @@ cargo dev update_lints
 # create a new lint and register it
 cargo dev new_lint
 # (experimental) Setup Clippy to work with rust-analyzer
-cargo dev ra-setup
+cargo dev ra_setup
 ```
 
 ## PR
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index bf867e0ae5b..d2e84132f4e 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1 +1,3 @@
-nightly
+[toolchain]
+channel = "nightly-2020-12-20"
+components = ["llvm-tools-preview", "rustc-dev", "rust-src", "rustfmt"]
diff --git a/src/tools/clippy/setup-toolchain.sh b/src/tools/clippy/setup-toolchain.sh
deleted file mode 100755
index 191ea4315a6..00000000000
--- a/src/tools/clippy/setup-toolchain.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env bash
-# Set up the appropriate rustc toolchain
-
-set -e
-
-cd "$(dirname "$0")"
-
-RTIM_PATH=$(command -v rustup-toolchain-install-master) || INSTALLED=false
-CARGO_HOME=${CARGO_HOME:-$HOME/.cargo}
-
-# Check if RTIM is not installed or installed in other locations not in ~/.cargo/bin
-if [[ "$INSTALLED" == false || "$RTIM_PATH" == $CARGO_HOME/bin/rustup-toolchain-install-master ]]; then
-    cargo +nightly install rustup-toolchain-install-master
-else
-    VERSION=$(rustup-toolchain-install-master -V | grep -o "[0-9.]*")
-    REMOTE=$(cargo +nightly search rustup-toolchain-install-master | grep -o "[0-9.]*")
-    echo "info: skipping updating rustup-toolchain-install-master at $RTIM_PATH"
-    echo "      current version : $VERSION"
-    echo "      remote version  : $REMOTE"
-fi
-
-RUST_COMMIT=$(git ls-remote https://github.com/rust-lang/rust master | awk '{print $1}')
-
-if rustc +master -Vv 2>/dev/null | grep -q "$RUST_COMMIT"; then
-    echo "info: master toolchain is up-to-date"
-    exit 0
-fi
-
-if [[ -n "$HOST_TOOLCHAIN" ]]; then
-    TOOLCHAIN=('--host' "$HOST_TOOLCHAIN")
-else
-    TOOLCHAIN=()
-fi
-
-rustup-toolchain-install-master -f -n master "${TOOLCHAIN[@]}" -c rustc-dev -c llvm-tools -- "$RUST_COMMIT"
-rustup override set master
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index ef31c72481a..e490ee54c0b 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -182,6 +182,7 @@ fn toolchain_path(home: Option<String>, toolchain: Option<String>) -> Option<Pat
     })
 }
 
+#[allow(clippy::too_many_lines)]
 pub fn main() {
     rustc_driver::init_rustc_env_logger();
     SyncLazy::force(&ICE_HOOK);
@@ -277,27 +278,40 @@ pub fn main() {
             args.extend(vec!["--sysroot".into(), sys_root]);
         };
 
-        // this check ensures that dependencies are built but not linted and the final
-        // crate is linted but not built
-        let clippy_enabled = env::var("CLIPPY_TESTS").map_or(false, |val| val == "true")
-            || arg_value(&orig_args, "--cap-lints", |val| val == "allow").is_none();
-
+        let mut no_deps = false;
+        let clippy_args = env::var("CLIPPY_ARGS")
+            .unwrap_or_default()
+            .split("__CLIPPY_HACKERY__")
+            .filter_map(|s| match s {
+                "" => None,
+                "--no-deps" => {
+                    no_deps = true;
+                    None
+                },
+                _ => Some(s.to_string()),
+            })
+            .chain(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()])
+            .collect::<Vec<String>>();
+
+        // We enable Clippy if one of the following conditions is met
+        // - IF Clippy is run on its test suite OR
+        // - IF Clippy is run on the main crate, not on deps (`!cap_lints_allow`) THEN
+        //    - IF `--no-deps` is not set (`!no_deps`) OR
+        //    - IF `--no-deps` is set and Clippy is run on the specified primary package
+        let clippy_tests_set = env::var("CLIPPY_TESTS").map_or(false, |val| val == "true");
+        let cap_lints_allow = arg_value(&orig_args, "--cap-lints", |val| val == "allow").is_some();
+        let in_primary_package = env::var("CARGO_PRIMARY_PACKAGE").is_ok();
+
+        let clippy_enabled = clippy_tests_set || (!cap_lints_allow && (!no_deps || in_primary_package));
         if clippy_enabled {
-            args.extend(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()]);
-            if let Ok(extra_args) = env::var("CLIPPY_ARGS") {
-                args.extend(extra_args.split("__CLIPPY_HACKERY__").filter_map(|s| {
-                    if s.is_empty() {
-                        None
-                    } else {
-                        Some(s.to_string())
-                    }
-                }));
-            }
+            args.extend(clippy_args);
         }
+
         let mut clippy = ClippyCallbacks;
         let mut default = DefaultCallbacks;
         let callbacks: &mut (dyn rustc_driver::Callbacks + Send) =
             if clippy_enabled { &mut clippy } else { &mut default };
+
         rustc_driver::RunCompiler::new(&args, callbacks).run()
     }))
 }
diff --git a/src/tools/clippy/src/main.rs b/src/tools/clippy/src/main.rs
index 6739a4cf224..ea06743394d 100644
--- a/src/tools/clippy/src/main.rs
+++ b/src/tools/clippy/src/main.rs
@@ -62,7 +62,7 @@ struct ClippyCmd {
     unstable_options: bool,
     cargo_subcommand: &'static str,
     args: Vec<String>,
-    clippy_args: String,
+    clippy_args: Vec<String>,
 }
 
 impl ClippyCmd {
@@ -99,7 +99,10 @@ impl ClippyCmd {
             args.insert(0, "+nightly".to_string());
         }
 
-        let clippy_args: String = old_args.map(|arg| format!("{}__CLIPPY_HACKERY__", arg)).collect();
+        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());
+        }
 
         ClippyCmd {
             unstable_options,
@@ -147,10 +150,15 @@ impl ClippyCmd {
 
     fn into_std_cmd(self) -> Command {
         let mut cmd = Command::new("cargo");
+        let clippy_args: String = self
+            .clippy_args
+            .iter()
+            .map(|arg| format!("{}__CLIPPY_HACKERY__", arg))
+            .collect();
 
         cmd.env(self.path_env(), Self::path())
             .envs(ClippyCmd::target_dir())
-            .env("CLIPPY_ARGS", self.clippy_args)
+            .env("CLIPPY_ARGS", clippy_args)
             .arg(self.cargo_subcommand)
             .args(&self.args);
 
@@ -202,6 +210,24 @@ mod tests {
     }
 
     #[test]
+    fn fix_implies_no_deps() {
+        let args = "cargo clippy --fix -Zunstable-options"
+            .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"
+            .split_whitespace()
+            .map(ToString::to_string);
+        let cmd = ClippyCmd::new(args);
+        assert_eq!(cmd.clippy_args.iter().filter(|arg| *arg == "--no-deps").count(), 1);
+    }
+
+    #[test]
     fn check() {
         let args = "cargo clippy".split_whitespace().map(ToString::to_string);
         let cmd = ClippyCmd::new(args);
diff --git a/src/tools/clippy/tests/dogfood.rs b/src/tools/clippy/tests/dogfood.rs
index a6163a83d76..052223d6d6f 100644
--- a/src/tools/clippy/tests/dogfood.rs
+++ b/src/tools/clippy/tests/dogfood.rs
@@ -3,7 +3,7 @@
 #![feature(once_cell)]
 
 use std::lazy::SyncLazy;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use std::process::Command;
 
 mod cargo;
@@ -47,12 +47,77 @@ fn dogfood_clippy() {
 
 #[test]
 fn dogfood_subprojects() {
+    fn test_no_deps_ignores_path_deps_in_workspaces() {
+        fn clean(cwd: &Path, target_dir: &Path) {
+            Command::new("cargo")
+                .current_dir(cwd)
+                .env("CARGO_TARGET_DIR", target_dir)
+                .arg("clean")
+                .args(&["-p", "subcrate"])
+                .args(&["-p", "path_dep"])
+                .output()
+                .unwrap();
+        }
+
+        if cargo::is_rustc_test_suite() {
+            return;
+        }
+        let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
+        let target_dir = root.join("target").join("dogfood");
+        let cwd = root.join("clippy_workspace_tests");
+
+        // Make sure we start with a clean state
+        clean(&cwd, &target_dir);
+
+        // `path_dep` is a path dependency of `subcrate` that would trigger a denied lint.
+        // Make sure that with the `--no-deps` argument Clippy does not run on `path_dep`.
+        let output = Command::new(&*CLIPPY_PATH)
+            .current_dir(&cwd)
+            .env("CLIPPY_DOGFOOD", "1")
+            .env("CARGO_INCREMENTAL", "0")
+            .arg("clippy")
+            .args(&["-p", "subcrate"])
+            .arg("--")
+            .arg("--no-deps")
+            .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir
+            .args(&["--cfg", r#"feature="primary_package_test""#])
+            .output()
+            .unwrap();
+        println!("status: {}", output.status);
+        println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
+        println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
+
+        assert!(output.status.success());
+
+        // Make sure we start with a clean state
+        clean(&cwd, &target_dir);
+
+        // Test that without the `--no-deps` argument, `path_dep` is linted.
+        let output = Command::new(&*CLIPPY_PATH)
+            .current_dir(&cwd)
+            .env("CLIPPY_DOGFOOD", "1")
+            .env("CARGO_INCREMENTAL", "0")
+            .arg("clippy")
+            .args(&["-p", "subcrate"])
+            .arg("--")
+            .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir
+            .args(&["--cfg", r#"feature="primary_package_test""#])
+            .output()
+            .unwrap();
+        println!("status: {}", output.status);
+        println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
+        println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
+
+        assert!(!output.status.success());
+    }
+
     // run clippy on remaining subprojects and fail the test if lint warnings are reported
     if cargo::is_rustc_test_suite() {
         return;
     }
     let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
 
+    // NOTE: `path_dep` crate is omitted on purpose here
     for d in &[
         "clippy_workspace_tests",
         "clippy_workspace_tests/src",
@@ -78,4 +143,8 @@ fn dogfood_subprojects() {
 
         assert!(output.status.success());
     }
+
+    // NOTE: Since tests run in parallel we can't run cargo commands on the same workspace at the
+    // same time, so we test this immediately after the dogfood for workspaces.
+    test_no_deps_ignores_path_deps_in_workspaces();
 }
diff --git a/src/tools/clippy/tests/integration.rs b/src/tools/clippy/tests/integration.rs
index a78273ce0da..1718089e8bd 100644
--- a/src/tools/clippy/tests/integration.rs
+++ b/src/tools/clippy/tests/integration.rs
@@ -72,6 +72,8 @@ fn integration_test() {
         panic!("incompatible crate versions");
     } else if stderr.contains("failed to run `rustc` to learn about target-specific information") {
         panic!("couldn't find librustc_driver, consider setting `LD_LIBRARY_PATH`");
+    } else if stderr.contains("toolchain") && stderr.contains("is not installed") {
+        panic!("missing required toolchain");
     }
 
     match output.status.code() {
diff --git a/src/tools/clippy/tests/ui-cargo/update-all-references.sh b/src/tools/clippy/tests/ui-cargo/update-all-references.sh
index 7028b251ea0..4391499a1e1 100755
--- a/src/tools/clippy/tests/ui-cargo/update-all-references.sh
+++ b/src/tools/clippy/tests/ui-cargo/update-all-references.sh
@@ -1,18 +1,3 @@
 #!/bin/bash
-#
-# A script to update the references for all tests. The idea is that
-# you do a run, which will generate files in the build directory
-# containing the (normalized) actual output of the compiler. You then
-# run this script, which will copy those files over. If you find
-# yourself manually editing a foo.stderr file, you're doing it wrong.
-#
-# See all `update-references.sh`, if you just want to update a single test.
 
-if [[ "$1" == "--help" || "$1" == "-h" ]]; then
-    echo "usage: $0"
-fi
-
-BUILD_DIR=$PWD/target/debug/test_build_base
-MY_DIR=$(dirname "$0")
-cd "$MY_DIR" || exit
-find . -name '*.rs' -exec ./update-references.sh "$BUILD_DIR" {} +
+echo "Please use 'cargo dev bless' instead."
diff --git a/src/tools/clippy/tests/ui-cargo/update-references.sh b/src/tools/clippy/tests/ui-cargo/update-references.sh
deleted file mode 100755
index 2ab51168bca..00000000000
--- a/src/tools/clippy/tests/ui-cargo/update-references.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-
-# A script to update the references for particular tests. The idea is
-# that you do a run, which will generate files in the build directory
-# containing the (normalized) actual output of the compiler. This
-# script will then copy that output and replace the "expected output"
-# files. You can then commit the changes.
-#
-# If you find yourself manually editing a foo.stderr file, you're
-# doing it wrong.
-
-if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" == "" ]]; then
-    echo "usage: $0 <build-directory> <relative-path-to-rs-files>"
-    echo ""
-    echo "For example:"
-    echo "   $0 ../../../build/x86_64-apple-darwin/test/ui *.rs */*.rs"
-fi
-
-MYDIR=$(dirname "$0")
-
-BUILD_DIR="$1"
-shift
-
-while [[ "$1" != "" ]]; do
-    STDERR_NAME="${1/%.rs/.stderr}"
-    STDOUT_NAME="${1/%.rs/.stdout}"
-    shift
-    if [[ -f "$BUILD_DIR"/"$STDOUT_NAME" ]] && \
-           ! (cmp -s -- "$BUILD_DIR"/"$STDOUT_NAME" "$MYDIR"/"$STDOUT_NAME"); then
-        echo updating "$MYDIR"/"$STDOUT_NAME"
-        cp "$BUILD_DIR"/"$STDOUT_NAME" "$MYDIR"/"$STDOUT_NAME"
-        if [[ ! -s "$MYDIR"/"$STDOUT_NAME" ]]; then
-            echo removing "$MYDIR"/"$STDOUT_NAME"
-            rm "$MYDIR"/"$STDOUT_NAME"
-        fi
-    fi
-    if [[ -f "$BUILD_DIR"/"$STDERR_NAME" ]] && \
-           ! (cmp -s -- "$BUILD_DIR"/"$STDERR_NAME" "$MYDIR"/"$STDERR_NAME"); then
-        echo updating "$MYDIR"/"$STDERR_NAME"
-        cp "$BUILD_DIR"/"$STDERR_NAME" "$MYDIR"/"$STDERR_NAME"
-        if [[ ! -s "$MYDIR"/"$STDERR_NAME" ]]; then
-            echo removing "$MYDIR"/"$STDERR_NAME"
-            rm "$MYDIR"/"$STDERR_NAME"
-        fi
-    fi
-done
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
new file mode 100644
index 00000000000..c6b84d2ef65
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
@@ -0,0 +1,33 @@
+// run-rustfix
+#![deny(clippy::internal)]
+#![feature(rustc_private)]
+
+extern crate rustc_span;
+
+use rustc_span::symbol::Symbol;
+
+macro_rules! sym {
+    ($tt:tt) => {
+        rustc_span::symbol::Symbol::intern(stringify!($tt))
+    };
+}
+
+fn main() {
+    // Direct use of Symbol::intern
+    let _ = rustc_span::symbol::sym::f32;
+
+    // Using a sym macro
+    let _ = rustc_span::symbol::sym::f32;
+
+    // Correct suggestion when symbol isn't stringified constant name
+    let _ = rustc_span::symbol::sym::proc_dash_macro;
+
+    // Interning a symbol that is not defined
+    let _ = Symbol::intern("xyz123");
+    let _ = sym!(xyz123);
+
+    // Using a different `intern` function
+    let _ = intern("f32");
+}
+
+fn intern(_: &str) {}
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
new file mode 100644
index 00000000000..9ec82d4ad0b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
@@ -0,0 +1,33 @@
+// run-rustfix
+#![deny(clippy::internal)]
+#![feature(rustc_private)]
+
+extern crate rustc_span;
+
+use rustc_span::symbol::Symbol;
+
+macro_rules! sym {
+    ($tt:tt) => {
+        rustc_span::symbol::Symbol::intern(stringify!($tt))
+    };
+}
+
+fn main() {
+    // Direct use of Symbol::intern
+    let _ = Symbol::intern("f32");
+
+    // Using a sym macro
+    let _ = sym!(f32);
+
+    // Correct suggestion when symbol isn't stringified constant name
+    let _ = Symbol::intern("proc-macro");
+
+    // Interning a symbol that is not defined
+    let _ = Symbol::intern("xyz123");
+    let _ = sym!(xyz123);
+
+    // Using a different `intern` function
+    let _ = intern("f32");
+}
+
+fn intern(_: &str) {}
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr
new file mode 100644
index 00000000000..74b906c8a57
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr
@@ -0,0 +1,27 @@
+error: interning a defined symbol
+  --> $DIR/interning_defined_symbol.rs:17:13
+   |
+LL |     let _ = Symbol::intern("f32");
+   |             ^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::symbol::sym::f32`
+   |
+note: the lint level is defined here
+  --> $DIR/interning_defined_symbol.rs:2:9
+   |
+LL | #![deny(clippy::internal)]
+   |         ^^^^^^^^^^^^^^^^
+   = note: `#[deny(clippy::interning_defined_symbol)]` implied by `#[deny(clippy::internal)]`
+
+error: interning a defined symbol
+  --> $DIR/interning_defined_symbol.rs:20:13
+   |
+LL |     let _ = sym!(f32);
+   |             ^^^^^^^^^ help: try: `rustc_span::symbol::sym::f32`
+
+error: interning a defined symbol
+  --> $DIR/interning_defined_symbol.rs:23:13
+   |
+LL |     let _ = Symbol::intern("proc-macro");
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::symbol::sym::proc_dash_macro`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/update-all-references.sh b/src/tools/clippy/tests/ui-toml/update-all-references.sh
index 7028b251ea0..4391499a1e1 100755
--- a/src/tools/clippy/tests/ui-toml/update-all-references.sh
+++ b/src/tools/clippy/tests/ui-toml/update-all-references.sh
@@ -1,18 +1,3 @@
 #!/bin/bash
-#
-# A script to update the references for all tests. The idea is that
-# you do a run, which will generate files in the build directory
-# containing the (normalized) actual output of the compiler. You then
-# run this script, which will copy those files over. If you find
-# yourself manually editing a foo.stderr file, you're doing it wrong.
-#
-# See all `update-references.sh`, if you just want to update a single test.
 
-if [[ "$1" == "--help" || "$1" == "-h" ]]; then
-    echo "usage: $0"
-fi
-
-BUILD_DIR=$PWD/target/debug/test_build_base
-MY_DIR=$(dirname "$0")
-cd "$MY_DIR" || exit
-find . -name '*.rs' -exec ./update-references.sh "$BUILD_DIR" {} +
+echo "Please use 'cargo dev bless' instead."
diff --git a/src/tools/clippy/tests/ui-toml/update-references.sh b/src/tools/clippy/tests/ui-toml/update-references.sh
deleted file mode 100755
index 2ab51168bca..00000000000
--- a/src/tools/clippy/tests/ui-toml/update-references.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-
-# A script to update the references for particular tests. The idea is
-# that you do a run, which will generate files in the build directory
-# containing the (normalized) actual output of the compiler. This
-# script will then copy that output and replace the "expected output"
-# files. You can then commit the changes.
-#
-# If you find yourself manually editing a foo.stderr file, you're
-# doing it wrong.
-
-if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" == "" ]]; then
-    echo "usage: $0 <build-directory> <relative-path-to-rs-files>"
-    echo ""
-    echo "For example:"
-    echo "   $0 ../../../build/x86_64-apple-darwin/test/ui *.rs */*.rs"
-fi
-
-MYDIR=$(dirname "$0")
-
-BUILD_DIR="$1"
-shift
-
-while [[ "$1" != "" ]]; do
-    STDERR_NAME="${1/%.rs/.stderr}"
-    STDOUT_NAME="${1/%.rs/.stdout}"
-    shift
-    if [[ -f "$BUILD_DIR"/"$STDOUT_NAME" ]] && \
-           ! (cmp -s -- "$BUILD_DIR"/"$STDOUT_NAME" "$MYDIR"/"$STDOUT_NAME"); then
-        echo updating "$MYDIR"/"$STDOUT_NAME"
-        cp "$BUILD_DIR"/"$STDOUT_NAME" "$MYDIR"/"$STDOUT_NAME"
-        if [[ ! -s "$MYDIR"/"$STDOUT_NAME" ]]; then
-            echo removing "$MYDIR"/"$STDOUT_NAME"
-            rm "$MYDIR"/"$STDOUT_NAME"
-        fi
-    fi
-    if [[ -f "$BUILD_DIR"/"$STDERR_NAME" ]] && \
-           ! (cmp -s -- "$BUILD_DIR"/"$STDERR_NAME" "$MYDIR"/"$STDERR_NAME"); then
-        echo updating "$MYDIR"/"$STDERR_NAME"
-        cp "$BUILD_DIR"/"$STDERR_NAME" "$MYDIR"/"$STDERR_NAME"
-        if [[ ! -s "$MYDIR"/"$STDERR_NAME" ]]; then
-            echo removing "$MYDIR"/"$STDERR_NAME"
-            rm "$MYDIR"/"$STDERR_NAME"
-        fi
-    fi
-done
diff --git a/src/tools/clippy/tests/ui/clone_on_copy.stderr b/src/tools/clippy/tests/ui/clone_on_copy.stderr
index ec2faf4ab40..14a700886a7 100644
--- a/src/tools/clippy/tests/ui/clone_on_copy.stderr
+++ b/src/tools/clippy/tests/ui/clone_on_copy.stderr
@@ -1,4 +1,4 @@
-error: using `clone` on a `Copy` type
+error: using `clone` on type `i32` which implements the `Copy` trait
   --> $DIR/clone_on_copy.rs:22:5
    |
 LL |     42.clone();
@@ -6,25 +6,25 @@ LL |     42.clone();
    |
    = note: `-D clippy::clone-on-copy` implied by `-D warnings`
 
-error: using `clone` on a `Copy` type
+error: using `clone` on type `i32` which implements the `Copy` trait
   --> $DIR/clone_on_copy.rs:26:5
    |
 LL |     (&42).clone();
    |     ^^^^^^^^^^^^^ help: try dereferencing it: `*(&42)`
 
-error: using `clone` on a `Copy` type
+error: using `clone` on type `i32` which implements the `Copy` trait
   --> $DIR/clone_on_copy.rs:29:5
    |
 LL |     rc.borrow().clone();
    |     ^^^^^^^^^^^^^^^^^^^ help: try dereferencing it: `*rc.borrow()`
 
-error: using `clone` on a `Copy` type
+error: using `clone` on type `char` which implements the `Copy` trait
   --> $DIR/clone_on_copy.rs:35:14
    |
 LL |     is_ascii('z'.clone());
    |              ^^^^^^^^^^^ help: try removing the `clone` call: `'z'`
 
-error: using `clone` on a `Copy` type
+error: using `clone` on type `i32` which implements the `Copy` trait
   --> $DIR/clone_on_copy.rs:39:14
    |
 LL |     vec.push(42.clone());
diff --git a/src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs b/src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs
index 6d2124c12fe..c57a45dc7aa 100644
--- a/src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs
+++ b/src/tools/clippy/tests/ui/crashes/used_underscore_binding_macro.rs
@@ -1,7 +1,6 @@
-#![allow(clippy::useless_attribute)] //issue #2910
+// edition:2018
 
-#[macro_use]
-extern crate serde_derive;
+use serde::Deserialize;
 
 /// Tests that we do not lint for unused underscores in a `MacroAttribute`
 /// expansion
diff --git a/src/tools/clippy/tests/ui/eprint_with_newline.rs b/src/tools/clippy/tests/ui/eprint_with_newline.rs
new file mode 100644
index 00000000000..8df32649ad9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/eprint_with_newline.rs
@@ -0,0 +1,49 @@
+#![allow(clippy::print_literal)]
+#![warn(clippy::print_with_newline)]
+
+fn main() {
+    eprint!("Hello\n");
+    eprint!("Hello {}\n", "world");
+    eprint!("Hello {} {}\n", "world", "#2");
+    eprint!("{}\n", 1265);
+    eprint!("\n");
+
+    // these are all fine
+    eprint!("");
+    eprint!("Hello");
+    eprintln!("Hello");
+    eprintln!("Hello\n");
+    eprintln!("Hello {}\n", "world");
+    eprint!("Issue\n{}", 1265);
+    eprint!("{}", 1265);
+    eprint!("\n{}", 1275);
+    eprint!("\n\n");
+    eprint!("like eof\n\n");
+    eprint!("Hello {} {}\n\n", "world", "#2");
+    eprintln!("\ndon't\nwarn\nfor\nmultiple\nnewlines\n"); // #3126
+    eprintln!("\nbla\n\n"); // #3126
+
+    // Escaping
+    eprint!("\\n"); // #3514
+    eprint!("\\\n"); // should fail
+    eprint!("\\\\n");
+
+    // Raw strings
+    eprint!(r"\n"); // #3778
+
+    // Literal newlines should also fail
+    eprint!(
+        "
+"
+    );
+    eprint!(
+        r"
+"
+    );
+
+    // Don't warn on CRLF (#4208)
+    eprint!("\r\n");
+    eprint!("foo\r\n");
+    eprint!("\\r\n"); //~ ERROR
+    eprint!("foo\rbar\n") // ~ ERROR
+}
diff --git a/src/tools/clippy/tests/ui/eprint_with_newline.stderr b/src/tools/clippy/tests/ui/eprint_with_newline.stderr
new file mode 100644
index 00000000000..31811d1d92a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/eprint_with_newline.stderr
@@ -0,0 +1,121 @@
+error: using `eprint!()` with a format string that ends in a single newline
+  --> $DIR/eprint_with_newline.rs:5:5
+   |
+LL |     eprint!("Hello/n");
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::print-with-newline` implied by `-D warnings`
+help: use `eprintln!` instead
+   |
+LL |     eprintln!("Hello");
+   |     ^^^^^^^^       --
+
+error: using `eprint!()` with a format string that ends in a single newline
+  --> $DIR/eprint_with_newline.rs:6:5
+   |
+LL |     eprint!("Hello {}/n", "world");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `eprintln!` instead
+   |
+LL |     eprintln!("Hello {}", "world");
+   |     ^^^^^^^^          --
+
+error: using `eprint!()` with a format string that ends in a single newline
+  --> $DIR/eprint_with_newline.rs:7:5
+   |
+LL |     eprint!("Hello {} {}/n", "world", "#2");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `eprintln!` instead
+   |
+LL |     eprintln!("Hello {} {}", "world", "#2");
+   |     ^^^^^^^^             --
+
+error: using `eprint!()` with a format string that ends in a single newline
+  --> $DIR/eprint_with_newline.rs:8:5
+   |
+LL |     eprint!("{}/n", 1265);
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `eprintln!` instead
+   |
+LL |     eprintln!("{}", 1265);
+   |     ^^^^^^^^    --
+
+error: using `eprint!()` with a format string that ends in a single newline
+  --> $DIR/eprint_with_newline.rs:9:5
+   |
+LL |     eprint!("/n");
+   |     ^^^^^^^^^^^^^
+   |
+help: use `eprintln!` instead
+   |
+LL |     eprintln!();
+   |     ^^^^^^^^ --
+
+error: using `eprint!()` with a format string that ends in a single newline
+  --> $DIR/eprint_with_newline.rs:28:5
+   |
+LL |     eprint!("//n"); // should fail
+   |     ^^^^^^^^^^^^^^^
+   |
+help: use `eprintln!` instead
+   |
+LL |     eprintln!("/"); // should fail
+   |     ^^^^^^^^    --
+
+error: using `eprint!()` with a format string that ends in a single newline
+  --> $DIR/eprint_with_newline.rs:35:5
+   |
+LL | /     eprint!(
+LL | |         "
+LL | | "
+LL | |     );
+   | |_____^
+   |
+help: use `eprintln!` instead
+   |
+LL |     eprintln!(
+LL |         ""
+   |
+
+error: using `eprint!()` with a format string that ends in a single newline
+  --> $DIR/eprint_with_newline.rs:39:5
+   |
+LL | /     eprint!(
+LL | |         r"
+LL | | "
+LL | |     );
+   | |_____^
+   |
+help: use `eprintln!` instead
+   |
+LL |     eprintln!(
+LL |         r""
+   |
+
+error: using `eprint!()` with a format string that ends in a single newline
+  --> $DIR/eprint_with_newline.rs:47:5
+   |
+LL |     eprint!("/r/n"); //~ ERROR
+   |     ^^^^^^^^^^^^^^^^
+   |
+help: use `eprintln!` instead
+   |
+LL |     eprintln!("/r"); //~ ERROR
+   |     ^^^^^^^^     --
+
+error: using `eprint!()` with a format string that ends in a single newline
+  --> $DIR/eprint_with_newline.rs:48:5
+   |
+LL |     eprint!("foo/rbar/n") // ~ ERROR
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `eprintln!` instead
+   |
+LL |     eprintln!("foo/rbar") // ~ ERROR
+   |     ^^^^^^^^          --
+
+error: aborting due to 10 previous errors
+
diff --git a/src/tools/clippy/tests/ui/eta.stderr b/src/tools/clippy/tests/ui/eta.stderr
index c4713ca8083..16aa1b07733 100644
--- a/src/tools/clippy/tests/ui/eta.stderr
+++ b/src/tools/clippy/tests/ui/eta.stderr
@@ -12,7 +12,7 @@ error: redundant closure found
 LL |     meta(|a| foo(a));
    |          ^^^^^^^^^^ help: remove closure as shown: `foo`
 
-error: this expression borrows a reference that is immediately dereferenced by the compiler
+error: this expression borrows a reference (`&u8`) that is immediately dereferenced by the compiler
   --> $DIR/eta.rs:24:21
    |
 LL |     all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
diff --git a/src/tools/clippy/tests/ui/formatting.rs b/src/tools/clippy/tests/ui/formatting.rs
index f54b3f2bfe2..0d14807ff1c 100644
--- a/src/tools/clippy/tests/ui/formatting.rs
+++ b/src/tools/clippy/tests/ui/formatting.rs
@@ -10,91 +10,6 @@ fn foo() -> bool {
 
 #[rustfmt::skip]
 fn main() {
-    // weird `else` formatting:
-    if foo() {
-    } {
-    }
-
-    if foo() {
-    } if foo() {
-    }
-
-    let _ = { // if as the last expression
-        let _ = 0;
-
-        if foo() {
-        } if foo() {
-        }
-        else {
-        }
-    };
-
-    let _ = { // if in the middle of a block
-        if foo() {
-        } if foo() {
-        }
-        else {
-        }
-
-        let _ = 0;
-    };
-
-    if foo() {
-    } else
-    {
-    }
-
-    if foo() {
-    }
-    else
-    {
-    }
-
-    if foo() {
-    } else
-    if foo() { // the span of the above error should continue here
-    }
-
-    if foo() {
-    }
-    else
-    if foo() { // the span of the above error should continue here
-    }
-
-    // those are ok:
-    if foo() {
-    }
-    {
-    }
-
-    if foo() {
-    } else {
-    }
-
-    if foo() {
-    }
-    else {
-    }
-
-    if foo() {
-    }
-    if foo() {
-    }
-
-    if foo() {
-    } else if foo() {
-    }
-
-    if foo() {
-    }
-    else if foo() {
-    }
-
-    if foo() {
-    }
-    else if
-    foo() {}
-
     // weird op_eq formatting:
     let mut a = 42;
     a =- 35;
@@ -146,7 +61,7 @@ fn main() {
 
     // don't lint if the indentation suggests not to
     let _ = &[
-        1 + 2, 3 
+        1 + 2, 3
                 - 4, 5
     ];
     // lint if it doesn't
diff --git a/src/tools/clippy/tests/ui/formatting.stderr b/src/tools/clippy/tests/ui/formatting.stderr
index e2095cc125b..bde434c7e2e 100644
--- a/src/tools/clippy/tests/ui/formatting.stderr
+++ b/src/tools/clippy/tests/ui/formatting.stderr
@@ -1,80 +1,5 @@
-error: this looks like an `else {..}` but the `else` is missing
-  --> $DIR/formatting.rs:15:6
-   |
-LL |     } {
-   |      ^
-   |
-   = note: `-D clippy::suspicious-else-formatting` implied by `-D warnings`
-   = note: to remove this lint, add the missing `else` or add a new line before the next block
-
-error: this looks like an `else if` but the `else` is missing
-  --> $DIR/formatting.rs:19:6
-   |
-LL |     } if foo() {
-   |      ^
-   |
-   = note: to remove this lint, add the missing `else` or add a new line before the second `if`
-
-error: this looks like an `else if` but the `else` is missing
-  --> $DIR/formatting.rs:26:10
-   |
-LL |         } if foo() {
-   |          ^
-   |
-   = note: to remove this lint, add the missing `else` or add a new line before the second `if`
-
-error: this looks like an `else if` but the `else` is missing
-  --> $DIR/formatting.rs:34:10
-   |
-LL |         } if foo() {
-   |          ^
-   |
-   = note: to remove this lint, add the missing `else` or add a new line before the second `if`
-
-error: this is an `else {..}` but the formatting might hide it
-  --> $DIR/formatting.rs:43:6
-   |
-LL |       } else
-   |  ______^
-LL | |     {
-   | |____^
-   |
-   = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}`
-
-error: this is an `else {..}` but the formatting might hide it
-  --> $DIR/formatting.rs:48:6
-   |
-LL |       }
-   |  ______^
-LL | |     else
-LL | |     {
-   | |____^
-   |
-   = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}`
-
-error: this is an `else if` but the formatting might hide it
-  --> $DIR/formatting.rs:54:6
-   |
-LL |       } else
-   |  ______^
-LL | |     if foo() { // the span of the above error should continue here
-   | |____^
-   |
-   = note: to remove this lint, remove the `else` or remove the new line between `else` and `if`
-
-error: this is an `else if` but the formatting might hide it
-  --> $DIR/formatting.rs:59:6
-   |
-LL |       }
-   |  ______^
-LL | |     else
-LL | |     if foo() { // the span of the above error should continue here
-   | |____^
-   |
-   = note: to remove this lint, remove the `else` or remove the new line between `else` and `if`
-
 error: this looks like you are trying to use `.. -= ..`, but you really are doing `.. = (- ..)`
-  --> $DIR/formatting.rs:100:6
+  --> $DIR/formatting.rs:15:6
    |
 LL |     a =- 35;
    |      ^^^^
@@ -83,7 +8,7 @@ LL |     a =- 35;
    = note: to remove this lint, use either `-=` or `= -`
 
 error: this looks like you are trying to use `.. *= ..`, but you really are doing `.. = (* ..)`
-  --> $DIR/formatting.rs:101:6
+  --> $DIR/formatting.rs:16:6
    |
 LL |     a =* &191;
    |      ^^^^
@@ -91,7 +16,7 @@ LL |     a =* &191;
    = note: to remove this lint, use either `*=` or `= *`
 
 error: this looks like you are trying to use `.. != ..`, but you really are doing `.. = (! ..)`
-  --> $DIR/formatting.rs:104:6
+  --> $DIR/formatting.rs:19:6
    |
 LL |     b =! false;
    |      ^^^^
@@ -99,7 +24,7 @@ LL |     b =! false;
    = note: to remove this lint, use either `!=` or `= !`
 
 error: possibly missing a comma here
-  --> $DIR/formatting.rs:113:19
+  --> $DIR/formatting.rs:28:19
    |
 LL |         -1, -2, -3 // <= no comma here
    |                   ^
@@ -108,7 +33,7 @@ LL |         -1, -2, -3 // <= no comma here
    = note: to remove this lint, add a comma or write the expr in a single line
 
 error: possibly missing a comma here
-  --> $DIR/formatting.rs:117:19
+  --> $DIR/formatting.rs:32:19
    |
 LL |         -1, -2, -3 // <= no comma here
    |                   ^
@@ -116,12 +41,12 @@ LL |         -1, -2, -3 // <= no comma here
    = note: to remove this lint, add a comma or write the expr in a single line
 
 error: possibly missing a comma here
-  --> $DIR/formatting.rs:154:11
+  --> $DIR/formatting.rs:69:11
    |
 LL |         -1
    |           ^
    |
    = note: to remove this lint, add a comma or write the expr in a single line
 
-error: aborting due to 14 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed
index 7f4ebf56673..84981a52597 100644
--- a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed
+++ b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed
@@ -39,7 +39,7 @@ fn main() {
         B(i32),
         C,
         D,
-    };
+    }
     let x = E::A(2);
     {
         // lint
diff --git a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs
index aee56dd4a5e..94c7c3cadac 100644
--- a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs
+++ b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs
@@ -51,7 +51,7 @@ fn main() {
         B(i32),
         C,
         D,
-    };
+    }
     let x = E::A(2);
     {
         // lint
diff --git a/src/tools/clippy/tests/ui/match_single_binding.fixed b/src/tools/clippy/tests/ui/match_single_binding.fixed
index f3627902eec..526e94b10bd 100644
--- a/src/tools/clippy/tests/ui/match_single_binding.fixed
+++ b/src/tools/clippy/tests/ui/match_single_binding.fixed
@@ -87,4 +87,32 @@ fn main() {
             unwrapped
         })
         .collect::<Vec<u8>>();
+    // Ok
+    let x = 1;
+    match x {
+        #[cfg(disabled_feature)]
+        0 => println!("Disabled branch"),
+        _ => println!("Enabled branch"),
+    }
+    // Lint
+    let x = 1;
+    let y = 1;
+    println!("Single branch");
+    // Ok
+    let x = 1;
+    let y = 1;
+    match match y {
+        0 => 1,
+        _ => 2,
+    } {
+        #[cfg(disabled_feature)]
+        0 => println!("Array index start"),
+        _ => println!("Not an array index start"),
+    }
+    // False negative
+    let x = 1;
+    match x {
+        // =>
+        _ => println!("Not an array index start"),
+    }
 }
diff --git a/src/tools/clippy/tests/ui/match_single_binding.rs b/src/tools/clippy/tests/ui/match_single_binding.rs
index 8c182148ae1..6a2ca7c5e93 100644
--- a/src/tools/clippy/tests/ui/match_single_binding.rs
+++ b/src/tools/clippy/tests/ui/match_single_binding.rs
@@ -99,4 +99,37 @@ fn main() {
             unwrapped => unwrapped,
         })
         .collect::<Vec<u8>>();
+    // Ok
+    let x = 1;
+    match x {
+        #[cfg(disabled_feature)]
+        0 => println!("Disabled branch"),
+        _ => println!("Enabled branch"),
+    }
+    // Lint
+    let x = 1;
+    let y = 1;
+    match match y {
+        0 => 1,
+        _ => 2,
+    } {
+        _ => println!("Single branch"),
+    }
+    // Ok
+    let x = 1;
+    let y = 1;
+    match match y {
+        0 => 1,
+        _ => 2,
+    } {
+        #[cfg(disabled_feature)]
+        0 => println!("Array index start"),
+        _ => println!("Not an array index start"),
+    }
+    // False negative
+    let x = 1;
+    match x {
+        // =>
+        _ => println!("Not an array index start"),
+    }
 }
diff --git a/src/tools/clippy/tests/ui/match_single_binding.stderr b/src/tools/clippy/tests/ui/match_single_binding.stderr
index 795c8c3e24d..cbbf5d29c02 100644
--- a/src/tools/clippy/tests/ui/match_single_binding.stderr
+++ b/src/tools/clippy/tests/ui/match_single_binding.stderr
@@ -167,5 +167,16 @@ LL |             unwrapped
 LL |         })
    |
 
-error: aborting due to 11 previous errors
+error: this match could be replaced by its body itself
+  --> $DIR/match_single_binding.rs:112:5
+   |
+LL | /     match match y {
+LL | |         0 => 1,
+LL | |         _ => 2,
+LL | |     } {
+LL | |         _ => println!("Single branch"),
+LL | |     }
+   | |_____^ help: consider using the match body instead: `println!("Single branch");`
+
+error: aborting due to 12 previous errors
 
diff --git a/src/tools/clippy/tests/ui/min_rust_version_attr.rs b/src/tools/clippy/tests/ui/min_rust_version_attr.rs
index 1026cc40d3b..3848bca3207 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_attr.rs
+++ b/src/tools/clippy/tests/ui/min_rust_version_attr.rs
@@ -2,7 +2,7 @@
 #![feature(custom_inner_attributes)]
 #![clippy::msrv = "1.0.0"]
 
-use std::ops::Deref;
+use std::ops::{Deref, RangeFrom};
 
 fn option_as_ref_deref() {
     let mut opt = Some(String::from("123"));
@@ -42,12 +42,94 @@ pub fn manual_strip_msrv() {
     }
 }
 
+pub fn redundant_fieldnames() {
+    let start = 0;
+    let _ = RangeFrom { start: start };
+}
+
+pub fn redundant_static_lifetime() {
+    const VAR_ONE: &'static str = "Test constant #1";
+}
+
+pub fn checked_conversion() {
+    let value: i64 = 42;
+    let _ = value <= (u32::max_value() as i64) && value >= 0;
+    let _ = value <= (u32::MAX as i64) && value >= 0;
+}
+
+pub fn filter_map_next() {
+    let a = ["1", "lol", "3", "NaN", "5"];
+
+    #[rustfmt::skip]
+    let _: Option<u32> = vec![1, 2, 3, 4, 5, 6]
+        .into_iter()
+        .filter_map(|x| {
+            if x == 2 {
+                Some(x * 2)
+            } else {
+                None
+            }
+        })
+        .next();
+}
+
+#[allow(clippy::no_effect)]
+#[allow(clippy::short_circuit_statement)]
+#[allow(clippy::unnecessary_operation)]
+pub fn manual_range_contains() {
+    let x = 5;
+    x >= 8 && x < 12;
+}
+
+pub fn use_self() {
+    struct Foo {}
+
+    impl Foo {
+        fn new() -> Foo {
+            Foo {}
+        }
+        fn test() -> Foo {
+            Foo::new()
+        }
+    }
+}
+
+fn replace_with_default() {
+    let mut s = String::from("foo");
+    let _ = std::mem::replace(&mut s, String::default());
+}
+
+fn map_unwrap_or() {
+    let opt = Some(1);
+
+    // Check for `option.map(_).unwrap_or(_)` use.
+    // Single line case.
+    let _ = opt
+        .map(|x| x + 1)
+        // Should lint even though this call is on a separate line.
+        .unwrap_or(0);
+}
+
+// Could be const
+fn missing_const_for_fn() -> i32 {
+    1
+}
+
 fn main() {
+    filter_map_next();
+    checked_conversion();
+    redundant_fieldnames();
+    redundant_static_lifetime();
     option_as_ref_deref();
     match_like_matches();
     match_same_arms();
     match_same_arms2();
     manual_strip_msrv();
+    manual_range_contains();
+    use_self();
+    replace_with_default();
+    map_unwrap_or();
+    missing_const_for_fn();
 }
 
 mod meets_msrv {
diff --git a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
index 3e1af046e7a..34805263104 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
+++ b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
@@ -1,12 +1,12 @@
 error: stripping a prefix manually
-  --> $DIR/min_rust_version_attr.rs:60:24
+  --> $DIR/min_rust_version_attr.rs:142:24
    |
 LL |             assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
    |                        ^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::manual-strip` implied by `-D warnings`
 note: the prefix was tested here
-  --> $DIR/min_rust_version_attr.rs:59:9
+  --> $DIR/min_rust_version_attr.rs:141:9
    |
 LL |         if s.starts_with("hello, ") {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,13 +17,13 @@ LL |             assert_eq!(<stripped>.to_uppercase(), "WORLD!");
    |
 
 error: stripping a prefix manually
-  --> $DIR/min_rust_version_attr.rs:72:24
+  --> $DIR/min_rust_version_attr.rs:154:24
    |
 LL |             assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
    |                        ^^^^^^^^^^^^^^^^^^^^
    |
 note: the prefix was tested here
-  --> $DIR/min_rust_version_attr.rs:71:9
+  --> $DIR/min_rust_version_attr.rs:153:9
    |
 LL |         if s.starts_with("hello, ") {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/missing-doc-crate-missing.stderr b/src/tools/clippy/tests/ui/missing-doc-crate-missing.stderr
index da46f988636..d56c5cc4c3a 100644
--- a/src/tools/clippy/tests/ui/missing-doc-crate-missing.stderr
+++ b/src/tools/clippy/tests/ui/missing-doc-crate-missing.stderr
@@ -1,4 +1,4 @@
-error: missing documentation for crate
+error: missing documentation for the crate
   --> $DIR/missing-doc-crate-missing.rs:1:1
    |
 LL | / #![warn(clippy::missing_docs_in_private_items)]
diff --git a/src/tools/clippy/tests/ui/missing-doc-impl.stderr b/src/tools/clippy/tests/ui/missing-doc-impl.stderr
index 9656a39abce..7e10404ca00 100644
--- a/src/tools/clippy/tests/ui/missing-doc-impl.stderr
+++ b/src/tools/clippy/tests/ui/missing-doc-impl.stderr
@@ -51,13 +51,13 @@ LL | |     fn foo_with_impl(&self) {}
 LL | | }
    | |_^
 
-error: missing documentation for a trait method
+error: missing documentation for an associated function
   --> $DIR/missing-doc-impl.rs:39:5
    |
 LL |     fn foo(&self);
    |     ^^^^^^^^^^^^^^
 
-error: missing documentation for a trait method
+error: missing documentation for an associated function
   --> $DIR/missing-doc-impl.rs:40:5
    |
 LL |     fn foo_with_impl(&self) {}
@@ -75,25 +75,25 @@ error: missing documentation for an associated type
 LL |     type AssociatedTypeDef = Self;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: missing documentation for a method
+error: missing documentation for an associated function
   --> $DIR/missing-doc-impl.rs:62:5
    |
 LL |     pub fn foo() {}
    |     ^^^^^^^^^^^^^^^
 
-error: missing documentation for a method
+error: missing documentation for an associated function
   --> $DIR/missing-doc-impl.rs:63:5
    |
 LL |     fn bar() {}
    |     ^^^^^^^^^^^
 
-error: missing documentation for a method
+error: missing documentation for an associated function
   --> $DIR/missing-doc-impl.rs:67:5
    |
 LL |     pub fn foo() {}
    |     ^^^^^^^^^^^^^^^
 
-error: missing documentation for a method
+error: missing documentation for an associated function
   --> $DIR/missing-doc-impl.rs:70:5
    |
 LL |     fn foo2() {}
diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr
index 0bfeda7914d..bea4b41b803 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow.stderr
@@ -1,4 +1,4 @@
-error: this expression borrows a reference that is immediately dereferenced by the compiler
+error: this expression borrows a reference (`&i32`) that is immediately dereferenced by the compiler
   --> $DIR/needless_borrow.rs:14:15
    |
 LL |     let c = x(&&a);
@@ -12,7 +12,7 @@ error: this pattern creates a reference to a reference
 LL |     if let Some(ref cake) = Some(&5) {}
    |                 ^^^^^^^^ help: change this to: `cake`
 
-error: this expression borrows a reference that is immediately dereferenced by the compiler
+error: this expression borrows a reference (`&i32`) that is immediately dereferenced by the compiler
   --> $DIR/needless_borrow.rs:28:15
    |
 LL |         46 => &&a,
diff --git a/src/tools/clippy/tests/ui/needless_doc_main.rs b/src/tools/clippy/tests/ui/needless_doc_main.rs
index 883683e08a2..83e9bbaa3af 100644
--- a/src/tools/clippy/tests/ui/needless_doc_main.rs
+++ b/src/tools/clippy/tests/ui/needless_doc_main.rs
@@ -10,7 +10,7 @@
 /// ```
 ///
 /// With an explicit return type it should lint too
-/// ```
+/// ```edition2015
 /// fn main() -> () {
 ///     unimplemented!();
 /// }
@@ -39,7 +39,7 @@ fn bad_doctests() {}
 /// ```
 ///
 /// This shouldn't lint either, because main is async:
-/// ```
+/// ```edition2018
 /// async fn main() {
 ///     assert_eq!(42, ANSWER);
 /// }
@@ -128,6 +128,12 @@ fn bad_doctests() {}
 /// ```
 fn no_false_positives() {}
 
+/// Yields a parse error when interpreted as rust code:
+/// ```
+/// r#"hi"
+/// ```
+fn issue_6022() {}
+
 fn main() {
     bad_doctests();
     no_false_positives();
diff --git a/src/tools/clippy/tests/ui/needless_update.rs b/src/tools/clippy/tests/ui/needless_update.rs
index bfa005a19f9..b93ff048a62 100644
--- a/src/tools/clippy/tests/ui/needless_update.rs
+++ b/src/tools/clippy/tests/ui/needless_update.rs
@@ -6,9 +6,20 @@ struct S {
     pub b: i32,
 }
 
+#[non_exhaustive]
+struct T {
+    pub x: i32,
+    pub y: i32,
+}
+
 fn main() {
     let base = S { a: 0, b: 0 };
     S { ..base }; // no error
     S { a: 1, ..base }; // no error
     S { a: 1, b: 1, ..base };
+
+    let base = T { x: 0, y: 0 };
+    T { ..base }; // no error
+    T { x: 1, ..base }; // no error
+    T { x: 1, y: 1, ..base }; // no error
 }
diff --git a/src/tools/clippy/tests/ui/needless_update.stderr b/src/tools/clippy/tests/ui/needless_update.stderr
index 133c834880d..b154b3b306d 100644
--- a/src/tools/clippy/tests/ui/needless_update.stderr
+++ b/src/tools/clippy/tests/ui/needless_update.stderr
@@ -1,5 +1,5 @@
 error: struct update has no effect, all the fields in the struct have already been specified
-  --> $DIR/needless_update.rs:13:23
+  --> $DIR/needless_update.rs:19:23
    |
 LL |     S { a: 1, b: 1, ..base };
    |                       ^^^^
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn.stderr b/src/tools/clippy/tests/ui/panic_in_result_fn.stderr
index ca73ac5a411..eb744b0c198 100644
--- a/src/tools/clippy/tests/ui/panic_in_result_fn.stderr
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn.stderr
@@ -1,4 +1,4 @@
-error: used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`
+error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
   --> $DIR/panic_in_result_fn.rs:7:5
    |
 LL | /     fn result_with_panic() -> Result<bool, String> // should emit lint
@@ -8,7 +8,7 @@ LL | |     }
    | |_____^
    |
    = note: `-D clippy::panic-in-result-fn` implied by `-D warnings`
-   = help: `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
   --> $DIR/panic_in_result_fn.rs:9:9
    |
@@ -16,7 +16,7 @@ LL |         panic!("error");
    |         ^^^^^^^^^^^^^^^^
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`
+error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
   --> $DIR/panic_in_result_fn.rs:12:5
    |
 LL | /     fn result_with_unimplemented() -> Result<bool, String> // should emit lint
@@ -25,7 +25,7 @@ LL | |         unimplemented!();
 LL | |     }
    | |_____^
    |
-   = help: `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
   --> $DIR/panic_in_result_fn.rs:14:9
    |
@@ -33,7 +33,7 @@ LL |         unimplemented!();
    |         ^^^^^^^^^^^^^^^^^
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`
+error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
   --> $DIR/panic_in_result_fn.rs:17:5
    |
 LL | /     fn result_with_unreachable() -> Result<bool, String> // should emit lint
@@ -42,7 +42,7 @@ LL | |         unreachable!();
 LL | |     }
    | |_____^
    |
-   = help: `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
   --> $DIR/panic_in_result_fn.rs:19:9
    |
@@ -50,7 +50,7 @@ LL |         unreachable!();
    |         ^^^^^^^^^^^^^^^
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`
+error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
   --> $DIR/panic_in_result_fn.rs:22:5
    |
 LL | /     fn result_with_todo() -> Result<bool, String> // should emit lint
@@ -59,7 +59,7 @@ LL | |         todo!("Finish this");
 LL | |     }
    | |_____^
    |
-   = help: `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
   --> $DIR/panic_in_result_fn.rs:24:9
    |
@@ -67,7 +67,7 @@ LL |         todo!("Finish this");
    |         ^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`
+error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
   --> $DIR/panic_in_result_fn.rs:53:1
    |
 LL | / fn function_result_with_panic() -> Result<bool, String> // should emit lint
@@ -76,7 +76,7 @@ LL | |     panic!("error");
 LL | | }
    | |_^
    |
-   = help: `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
   --> $DIR/panic_in_result_fn.rs:55:5
    |
@@ -84,7 +84,7 @@ LL |     panic!("error");
    |     ^^^^^^^^^^^^^^^^
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: used `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` in a function that returns `Result`
+error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
   --> $DIR/panic_in_result_fn.rs:68:1
    |
 LL | / fn main() -> Result<(), String> {
@@ -93,7 +93,7 @@ LL | |     Ok(())
 LL | | }
    | |_^
    |
-   = help: `unimplemented!()`, `unreachable!()`, `todo!()` or `panic!()` should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
 note: return Err() instead of panicking
   --> $DIR/panic_in_result_fn.rs:69:5
    |
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.rs b/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.rs
new file mode 100644
index 00000000000..ffdf8288adc
--- /dev/null
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.rs
@@ -0,0 +1,48 @@
+#![warn(clippy::panic_in_result_fn)]
+#![allow(clippy::unnecessary_wraps)]
+
+struct A;
+
+impl A {
+    fn result_with_assert_with_message(x: i32) -> Result<bool, String> // should emit lint
+    {
+        assert!(x == 5, "wrong argument");
+        Ok(true)
+    }
+
+    fn result_with_assert_eq(x: i32) -> Result<bool, String> // should emit lint
+    {
+        assert_eq!(x, 5);
+        Ok(true)
+    }
+
+    fn result_with_assert_ne(x: i32) -> Result<bool, String> // should emit lint
+    {
+        assert_ne!(x, 1);
+        Ok(true)
+    }
+
+    fn other_with_assert_with_message(x: i32) // should not emit lint
+    {
+        assert!(x == 5, "wrong argument");
+    }
+
+    fn other_with_assert_eq(x: i32) // should not emit lint
+    {
+        assert_eq!(x, 5);
+    }
+
+    fn other_with_assert_ne(x: i32) // should not emit lint
+    {
+        assert_ne!(x, 1);
+    }
+
+    fn result_without_banned_functions() -> Result<bool, String> // should not emit lint
+    {
+        let assert = "assert!";
+        println!("No {}", assert);
+        Ok(true)
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr b/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr
new file mode 100644
index 00000000000..86f61ad718a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr
@@ -0,0 +1,57 @@
+error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
+  --> $DIR/panic_in_result_fn_assertions.rs:7:5
+   |
+LL | /     fn result_with_assert_with_message(x: i32) -> Result<bool, String> // should emit lint
+LL | |     {
+LL | |         assert!(x == 5, "wrong argument");
+LL | |         Ok(true)
+LL | |     }
+   | |_____^
+   |
+   = note: `-D clippy::panic-in-result-fn` implied by `-D warnings`
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+note: return Err() instead of panicking
+  --> $DIR/panic_in_result_fn_assertions.rs:9:9
+   |
+LL |         assert!(x == 5, "wrong argument");
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
+  --> $DIR/panic_in_result_fn_assertions.rs:13:5
+   |
+LL | /     fn result_with_assert_eq(x: i32) -> Result<bool, String> // should emit lint
+LL | |     {
+LL | |         assert_eq!(x, 5);
+LL | |         Ok(true)
+LL | |     }
+   | |_____^
+   |
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+note: return Err() instead of panicking
+  --> $DIR/panic_in_result_fn_assertions.rs:15:9
+   |
+LL |         assert_eq!(x, 5);
+   |         ^^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
+  --> $DIR/panic_in_result_fn_assertions.rs:19:5
+   |
+LL | /     fn result_with_assert_ne(x: i32) -> Result<bool, String> // should emit lint
+LL | |     {
+LL | |         assert_ne!(x, 1);
+LL | |         Ok(true)
+LL | |     }
+   | |_____^
+   |
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+note: return Err() instead of panicking
+  --> $DIR/panic_in_result_fn_assertions.rs:21:9
+   |
+LL |         assert_ne!(x, 1);
+   |         ^^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn_debug_assertions.rs b/src/tools/clippy/tests/ui/panic_in_result_fn_debug_assertions.rs
new file mode 100644
index 00000000000..b60c79f97c8
--- /dev/null
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn_debug_assertions.rs
@@ -0,0 +1,48 @@
+#![warn(clippy::panic_in_result_fn)]
+#![allow(clippy::unnecessary_wraps)]
+
+struct A;
+
+impl A {
+    fn result_with_debug_assert_with_message(x: i32) -> Result<bool, String> // should emit lint
+    {
+        debug_assert!(x == 5, "wrong argument");
+        Ok(true)
+    }
+
+    fn result_with_debug_assert_eq(x: i32) -> Result<bool, String> // should emit lint
+    {
+        debug_assert_eq!(x, 5);
+        Ok(true)
+    }
+
+    fn result_with_debug_assert_ne(x: i32) -> Result<bool, String> // should emit lint
+    {
+        debug_assert_ne!(x, 1);
+        Ok(true)
+    }
+
+    fn other_with_debug_assert_with_message(x: i32) // should not emit lint
+    {
+        debug_assert!(x == 5, "wrong argument");
+    }
+
+    fn other_with_debug_assert_eq(x: i32) // should not emit lint
+    {
+        debug_assert_eq!(x, 5);
+    }
+
+    fn other_with_debug_assert_ne(x: i32) // should not emit lint
+    {
+        debug_assert_ne!(x, 1);
+    }
+
+    fn result_without_banned_functions() -> Result<bool, String> // should not emit lint
+    {
+        let debug_assert = "debug_assert!";
+        println!("No {}", debug_assert);
+        Ok(true)
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn_debug_assertions.stderr b/src/tools/clippy/tests/ui/panic_in_result_fn_debug_assertions.stderr
new file mode 100644
index 00000000000..ec18e89698c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn_debug_assertions.stderr
@@ -0,0 +1,57 @@
+error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
+  --> $DIR/panic_in_result_fn_debug_assertions.rs:7:5
+   |
+LL | /     fn result_with_debug_assert_with_message(x: i32) -> Result<bool, String> // should emit lint
+LL | |     {
+LL | |         debug_assert!(x == 5, "wrong argument");
+LL | |         Ok(true)
+LL | |     }
+   | |_____^
+   |
+   = note: `-D clippy::panic-in-result-fn` implied by `-D warnings`
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+note: return Err() instead of panicking
+  --> $DIR/panic_in_result_fn_debug_assertions.rs:9:9
+   |
+LL |         debug_assert!(x == 5, "wrong argument");
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
+  --> $DIR/panic_in_result_fn_debug_assertions.rs:13:5
+   |
+LL | /     fn result_with_debug_assert_eq(x: i32) -> Result<bool, String> // should emit lint
+LL | |     {
+LL | |         debug_assert_eq!(x, 5);
+LL | |         Ok(true)
+LL | |     }
+   | |_____^
+   |
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+note: return Err() instead of panicking
+  --> $DIR/panic_in_result_fn_debug_assertions.rs:15:9
+   |
+LL |         debug_assert_eq!(x, 5);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result`
+  --> $DIR/panic_in_result_fn_debug_assertions.rs:19:5
+   |
+LL | /     fn result_with_debug_assert_ne(x: i32) -> Result<bool, String> // should emit lint
+LL | |     {
+LL | |         debug_assert_ne!(x, 1);
+LL | |         Ok(true)
+LL | |     }
+   | |_____^
+   |
+   = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
+note: return Err() instead of panicking
+  --> $DIR/panic_in_result_fn_debug_assertions.rs:21:9
+   |
+LL |         debug_assert_ne!(x, 1);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/print_stderr.rs b/src/tools/clippy/tests/ui/print_stderr.rs
new file mode 100644
index 00000000000..fa07e74a7be
--- /dev/null
+++ b/src/tools/clippy/tests/ui/print_stderr.rs
@@ -0,0 +1,8 @@
+#![warn(clippy::print_stderr)]
+
+fn main() {
+    eprintln!("Hello");
+    println!("This should not do anything");
+    eprint!("World");
+    print!("Nor should this");
+}
diff --git a/src/tools/clippy/tests/ui/print_stderr.stderr b/src/tools/clippy/tests/ui/print_stderr.stderr
new file mode 100644
index 00000000000..5af735af657
--- /dev/null
+++ b/src/tools/clippy/tests/ui/print_stderr.stderr
@@ -0,0 +1,16 @@
+error: use of `eprintln!`
+  --> $DIR/print_stderr.rs:4:5
+   |
+LL |     eprintln!("Hello");
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::print-stderr` implied by `-D warnings`
+
+error: use of `eprint!`
+  --> $DIR/print_stderr.rs:6:5
+   |
+LL |     eprint!("World");
+   |     ^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/println_empty_string.fixed b/src/tools/clippy/tests/ui/println_empty_string.fixed
index 2b889b62ea9..9760680927a 100644
--- a/src/tools/clippy/tests/ui/println_empty_string.fixed
+++ b/src/tools/clippy/tests/ui/println_empty_string.fixed
@@ -8,4 +8,11 @@ fn main() {
     match "a" {
         _ => println!(),
     }
+
+    eprintln!();
+    eprintln!();
+
+    match "a" {
+        _ => eprintln!(),
+    }
 }
diff --git a/src/tools/clippy/tests/ui/println_empty_string.rs b/src/tools/clippy/tests/ui/println_empty_string.rs
index 890f5f68476..80fdb3e6e21 100644
--- a/src/tools/clippy/tests/ui/println_empty_string.rs
+++ b/src/tools/clippy/tests/ui/println_empty_string.rs
@@ -8,4 +8,11 @@ fn main() {
     match "a" {
         _ => println!(""),
     }
+
+    eprintln!();
+    eprintln!("");
+
+    match "a" {
+        _ => eprintln!(""),
+    }
 }
diff --git a/src/tools/clippy/tests/ui/println_empty_string.stderr b/src/tools/clippy/tests/ui/println_empty_string.stderr
index 23112b88168..17fe4ea7479 100644
--- a/src/tools/clippy/tests/ui/println_empty_string.stderr
+++ b/src/tools/clippy/tests/ui/println_empty_string.stderr
@@ -12,5 +12,17 @@ error: using `println!("")`
 LL |         _ => println!(""),
    |              ^^^^^^^^^^^^ help: replace it with: `println!()`
 
-error: aborting due to 2 previous errors
+error: using `eprintln!("")`
+  --> $DIR/println_empty_string.rs:13:5
+   |
+LL |     eprintln!("");
+   |     ^^^^^^^^^^^^^ help: replace it with: `eprintln!()`
+
+error: using `eprintln!("")`
+  --> $DIR/println_empty_string.rs:16:14
+   |
+LL |         _ => eprintln!(""),
+   |              ^^^^^^^^^^^^^ help: replace it with: `eprintln!()`
+
+error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/range_contains.fixed b/src/tools/clippy/tests/ui/range_contains.fixed
index 048874a7f82..47c974e614b 100644
--- a/src/tools/clippy/tests/ui/range_contains.fixed
+++ b/src/tools/clippy/tests/ui/range_contains.fixed
@@ -44,3 +44,8 @@ fn main() {
     (0. ..1.).contains(&y);
     !(0. ..=1.).contains(&y);
 }
+
+// Fix #6373
+pub const fn in_range(a: i32) -> bool {
+    3 <= a && a <= 20
+}
diff --git a/src/tools/clippy/tests/ui/range_contains.rs b/src/tools/clippy/tests/ui/range_contains.rs
index 60ad259f404..835deced5e4 100644
--- a/src/tools/clippy/tests/ui/range_contains.rs
+++ b/src/tools/clippy/tests/ui/range_contains.rs
@@ -44,3 +44,8 @@ fn main() {
     y >= 0. && y < 1.;
     y < 0. || y > 1.;
 }
+
+// Fix #6373
+pub const fn in_range(a: i32) -> bool {
+    3 <= a && a <= 20
+}
diff --git a/src/tools/clippy/tests/ui/redundant_else.rs b/src/tools/clippy/tests/ui/redundant_else.rs
new file mode 100644
index 00000000000..737c8a9f8db
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_else.rs
@@ -0,0 +1,154 @@
+#![warn(clippy::redundant_else)]
+#![allow(clippy::needless_return)]
+
+fn main() {
+    loop {
+        // break
+        if foo() {
+            println!("Love your neighbor;");
+            break;
+        } else {
+            println!("yet don't pull down your hedge.");
+        }
+        // continue
+        if foo() {
+            println!("He that lies down with Dogs,");
+            continue;
+        } else {
+            println!("shall rise up with fleas.");
+        }
+        // match block
+        if foo() {
+            match foo() {
+                1 => break,
+                _ => return,
+            }
+        } else {
+            println!("You may delay, but time will not.");
+        }
+    }
+    // else if
+    if foo() {
+        return;
+    } else if foo() {
+        return;
+    } else {
+        println!("A fat kitchen makes a lean will.");
+    }
+    // let binding outside of block
+    let _ = {
+        if foo() {
+            return;
+        } else {
+            1
+        }
+    };
+    // else if with let binding outside of block
+    let _ = {
+        if foo() {
+            return;
+        } else if foo() {
+            return;
+        } else {
+            2
+        }
+    };
+    // inside if let
+    let _ = if let Some(1) = foo() {
+        let _ = 1;
+        if foo() {
+            return;
+        } else {
+            1
+        }
+    } else {
+        1
+    };
+
+    //
+    // non-lint cases
+    //
+
+    // sanity check
+    if foo() {
+        let _ = 1;
+    } else {
+        println!("Who is wise? He that learns from every one.");
+    }
+    // else if without else
+    if foo() {
+        return;
+    } else if foo() {
+        foo()
+    };
+    // nested if return
+    if foo() {
+        if foo() {
+            return;
+        }
+    } else {
+        foo()
+    };
+    // match with non-breaking branch
+    if foo() {
+        match foo() {
+            1 => foo(),
+            _ => return,
+        }
+    } else {
+        println!("Three may keep a secret, if two of them are dead.");
+    }
+    // let binding
+    let _ = if foo() {
+        return;
+    } else {
+        1
+    };
+    // assign
+    let a;
+    a = if foo() {
+        return;
+    } else {
+        1
+    };
+    // assign-op
+    a += if foo() {
+        return;
+    } else {
+        1
+    };
+    // if return else if else
+    if foo() {
+        return;
+    } else if foo() {
+        1
+    } else {
+        2
+    };
+    // if else if return else
+    if foo() {
+        1
+    } else if foo() {
+        return;
+    } else {
+        2
+    };
+    // else if with let binding
+    let _ = if foo() {
+        return;
+    } else if foo() {
+        return;
+    } else {
+        2
+    };
+    // inside function call
+    Box::new(if foo() {
+        return;
+    } else {
+        1
+    });
+}
+
+fn foo<T>() -> T {
+    unimplemented!("I'm not Santa Claus")
+}
diff --git a/src/tools/clippy/tests/ui/redundant_else.stderr b/src/tools/clippy/tests/ui/redundant_else.stderr
new file mode 100644
index 00000000000..9000cdc814b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_else.stderr
@@ -0,0 +1,80 @@
+error: redundant else block
+  --> $DIR/redundant_else.rs:10:16
+   |
+LL |           } else {
+   |  ________________^
+LL | |             println!("yet don't pull down your hedge.");
+LL | |         }
+   | |_________^
+   |
+   = note: `-D clippy::redundant-else` implied by `-D warnings`
+   = help: remove the `else` block and move the contents out
+
+error: redundant else block
+  --> $DIR/redundant_else.rs:17:16
+   |
+LL |           } else {
+   |  ________________^
+LL | |             println!("shall rise up with fleas.");
+LL | |         }
+   | |_________^
+   |
+   = help: remove the `else` block and move the contents out
+
+error: redundant else block
+  --> $DIR/redundant_else.rs:26:16
+   |
+LL |           } else {
+   |  ________________^
+LL | |             println!("You may delay, but time will not.");
+LL | |         }
+   | |_________^
+   |
+   = help: remove the `else` block and move the contents out
+
+error: redundant else block
+  --> $DIR/redundant_else.rs:35:12
+   |
+LL |       } else {
+   |  ____________^
+LL | |         println!("A fat kitchen makes a lean will.");
+LL | |     }
+   | |_____^
+   |
+   = help: remove the `else` block and move the contents out
+
+error: redundant else block
+  --> $DIR/redundant_else.rs:42:16
+   |
+LL |           } else {
+   |  ________________^
+LL | |             1
+LL | |         }
+   | |_________^
+   |
+   = help: remove the `else` block and move the contents out
+
+error: redundant else block
+  --> $DIR/redundant_else.rs:52:16
+   |
+LL |           } else {
+   |  ________________^
+LL | |             2
+LL | |         }
+   | |_________^
+   |
+   = help: remove the `else` block and move the contents out
+
+error: redundant else block
+  --> $DIR/redundant_else.rs:61:16
+   |
+LL |           } else {
+   |  ________________^
+LL | |             1
+LL | |         }
+   | |_________^
+   |
+   = help: remove the `else` block and move the contents out
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/suspicious_else_formatting.rs b/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
new file mode 100644
index 00000000000..226010ec6df
--- /dev/null
+++ b/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
@@ -0,0 +1,79 @@
+#![warn(clippy::suspicious_else_formatting)]
+
+fn foo() -> bool {
+    true
+}
+
+#[rustfmt::skip]
+fn main() {
+    // weird `else` formatting:
+    if foo() {
+    } {
+    }
+
+    if foo() {
+    } if foo() {
+    }
+
+    let _ = { // if as the last expression
+        let _ = 0;
+
+        if foo() {
+        } if foo() {
+        }
+        else {
+        }
+    };
+
+    let _ = { // if in the middle of a block
+        if foo() {
+        } if foo() {
+        }
+        else {
+        }
+
+        let _ = 0;
+    };
+
+    if foo() {
+    } else
+    {
+    }
+
+    if foo() {
+    }
+    else
+    {
+    }
+
+    if foo() {
+    } else
+    if foo() { // the span of the above error should continue here
+    }
+
+    if foo() {
+    }
+    else
+    if foo() { // the span of the above error should continue here
+    }
+
+    // those are ok:
+    if foo() {
+    }
+    {
+    }
+
+    if foo() {
+    } else {
+    }
+
+    if foo() {
+    }
+    else {
+    }
+
+    if foo() {
+    }
+    if foo() {
+    }
+}
diff --git a/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr b/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr
new file mode 100644
index 00000000000..bbc036d376f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr
@@ -0,0 +1,77 @@
+error: this looks like an `else {..}` but the `else` is missing
+  --> $DIR/suspicious_else_formatting.rs:11:6
+   |
+LL |     } {
+   |      ^
+   |
+   = note: `-D clippy::suspicious-else-formatting` implied by `-D warnings`
+   = note: to remove this lint, add the missing `else` or add a new line before the next block
+
+error: this looks like an `else if` but the `else` is missing
+  --> $DIR/suspicious_else_formatting.rs:15:6
+   |
+LL |     } if foo() {
+   |      ^
+   |
+   = note: to remove this lint, add the missing `else` or add a new line before the second `if`
+
+error: this looks like an `else if` but the `else` is missing
+  --> $DIR/suspicious_else_formatting.rs:22:10
+   |
+LL |         } if foo() {
+   |          ^
+   |
+   = note: to remove this lint, add the missing `else` or add a new line before the second `if`
+
+error: this looks like an `else if` but the `else` is missing
+  --> $DIR/suspicious_else_formatting.rs:30:10
+   |
+LL |         } if foo() {
+   |          ^
+   |
+   = note: to remove this lint, add the missing `else` or add a new line before the second `if`
+
+error: this is an `else {..}` but the formatting might hide it
+  --> $DIR/suspicious_else_formatting.rs:39:6
+   |
+LL |       } else
+   |  ______^
+LL | |     {
+   | |____^
+   |
+   = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}`
+
+error: this is an `else {..}` but the formatting might hide it
+  --> $DIR/suspicious_else_formatting.rs:44:6
+   |
+LL |       }
+   |  ______^
+LL | |     else
+LL | |     {
+   | |____^
+   |
+   = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}`
+
+error: this is an `else if` but the formatting might hide it
+  --> $DIR/suspicious_else_formatting.rs:50:6
+   |
+LL |       } else
+   |  ______^
+LL | |     if foo() { // the span of the above error should continue here
+   | |____^
+   |
+   = note: to remove this lint, remove the `else` or remove the new line between `else` and `if`
+
+error: this is an `else if` but the formatting might hide it
+  --> $DIR/suspicious_else_formatting.rs:55:6
+   |
+LL |       }
+   |  ______^
+LL | |     else
+LL | |     if foo() { // the span of the above error should continue here
+   | |____^
+   |
+   = note: to remove this lint, remove the `else` or remove the new line between `else` and `if`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_clone.stderr b/src/tools/clippy/tests/ui/unnecessary_clone.stderr
index 5ffa6c4fd06..9df1ae56867 100644
--- a/src/tools/clippy/tests/ui/unnecessary_clone.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_clone.stderr
@@ -30,7 +30,7 @@ error: using `.clone()` on a ref-counted pointer
 LL |     let _: Arc<dyn SomeTrait> = x.clone();
    |                                 ^^^^^^^^^ help: try this: `Arc::<SomeImpl>::clone(&x)`
 
-error: using `clone` on a `Copy` type
+error: using `clone` on type `T` which implements the `Copy` trait
   --> $DIR/unnecessary_clone.rs:40:5
    |
 LL |     t.clone();
@@ -38,13 +38,13 @@ LL |     t.clone();
    |
    = note: `-D clippy::clone-on-copy` implied by `-D warnings`
 
-error: using `clone` on a `Copy` type
+error: using `clone` on type `std::option::Option<T>` which implements the `Copy` trait
   --> $DIR/unnecessary_clone.rs:42:5
    |
 LL |     Some(t).clone();
    |     ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)`
 
-error: using `clone` on a double-reference; this will copy the reference instead of cloning the inner type
+error: using `clone` on a double-reference; this will copy the reference of type `&std::vec::Vec<i32>` instead of cloning the inner type
   --> $DIR/unnecessary_clone.rs:48:22
    |
 LL |     let z: &Vec<_> = y.clone();
@@ -60,13 +60,13 @@ help: or try being explicit if you are sure, that you want to clone a reference
 LL |     let z: &Vec<_> = <&std::vec::Vec<i32>>::clone(y);
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: using `clone` on a `Copy` type
+error: using `clone` on type `many_derefs::E` which implements the `Copy` trait
   --> $DIR/unnecessary_clone.rs:84:20
    |
 LL |         let _: E = a.clone();
    |                    ^^^^^^^^^ help: try dereferencing it: `*****a`
 
-error: using `clone` on a double-reference; this will copy the reference instead of cloning the inner type
+error: using `clone` on a double-reference; this will copy the reference of type `&[u8]` instead of cloning the inner type
   --> $DIR/unnecessary_clone.rs:89:22
    |
 LL |         let _ = &mut encoded.clone();
@@ -81,7 +81,7 @@ help: or try being explicit if you are sure, that you want to clone a reference
 LL |         let _ = &mut <&[u8]>::clone(encoded);
    |                      ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: using `clone` on a double-reference; this will copy the reference instead of cloning the inner type
+error: using `clone` on a double-reference; this will copy the reference of type `&[u8]` instead of cloning the inner type
   --> $DIR/unnecessary_clone.rs:90:18
    |
 LL |         let _ = &encoded.clone();
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs
index 2e923bc97a2..b05dd143bfd 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.rs
@@ -15,4 +15,8 @@ fn main() {
     }
     let _ = Ok(1).unwrap_or_else(|e::E| 2);
     let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2);
+
+    // Fix #6343
+    let arr = [(Some(1),)];
+    Some(&0).and_then(|&i| arr[i].0);
 }
diff --git a/src/tools/clippy/tests/ui/update-all-references.sh b/src/tools/clippy/tests/ui/update-all-references.sh
index 30ba9188db4..4391499a1e1 100755
--- a/src/tools/clippy/tests/ui/update-all-references.sh
+++ b/src/tools/clippy/tests/ui/update-all-references.sh
@@ -1,21 +1,3 @@
 #!/bin/bash
 
-# A script to update the references for all tests. The idea is that
-# you do a run, which will generate files in the build directory
-# containing the (normalized) actual output of the compiler. You then
-# run this script, which will copy those files over. If you find
-# yourself manually editing a foo.stderr file, you're doing it wrong.
-#
-# See all `update-references.sh`, if you just want to update a single test.
-
-if [[ "$1" == "--help" || "$1" == "-h" ]]; then
-    echo "usage: $0"
-fi
-
-CARGO_TARGET_DIR=${CARGO_TARGET_DIR:-$PWD/target}
-PROFILE=${PROFILE:-debug}
-BUILD_DIR=${CARGO_TARGET_DIR}/${PROFILE}/test_build_base
-
-MY_DIR=$(dirname "$0")
-cd "$MY_DIR" || exit
-find . -name '*.rs' -exec ./update-references.sh "$BUILD_DIR" {} +
+echo "Please use 'cargo dev bless' instead."
diff --git a/src/tools/clippy/tests/ui/update-references.sh b/src/tools/clippy/tests/ui/update-references.sh
deleted file mode 100755
index e16ed600ef8..00000000000
--- a/src/tools/clippy/tests/ui/update-references.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-
-# A script to update the references for particular tests. The idea is
-# that you do a run, which will generate files in the build directory
-# containing the (normalized) actual output of the compiler. This
-# script will then copy that output and replace the "expected output"
-# files. You can then commit the changes.
-#
-# If you find yourself manually editing a `foo.stderr` file, you're
-# doing it wrong.
-
-if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" == "" ]]; then
-    echo "usage: $0 <build-directory> <relative-path-to-rs-files>"
-    echo ""
-    echo "For example:"
-    echo "   $0 ../../../build/x86_64-apple-darwin/test/ui *.rs */*.rs"
-fi
-
-MYDIR=$(dirname "$0")
-
-BUILD_DIR="$1"
-shift
-
-while [[ "$1" != "" ]]; do
-    STDERR_NAME="${1/%.rs/.stderr}"
-    STDOUT_NAME="${1/%.rs/.stdout}"
-    FIXED_NAME="${1/%.rs/.fixed}"
-    shift
-    if [[ -f "$BUILD_DIR"/"$STDOUT_NAME" ]] && \
-           ! (cmp -s -- "$BUILD_DIR"/"$STDOUT_NAME" "$MYDIR"/"$STDOUT_NAME"); then
-        echo updating "$MYDIR"/"$STDOUT_NAME"
-        cp "$BUILD_DIR"/"$STDOUT_NAME" "$MYDIR"/"$STDOUT_NAME"
-        if [[ ! -s "$MYDIR"/"$STDOUT_NAME" ]]; then
-            echo removing "$MYDIR"/"$STDOUT_NAME"
-            rm "$MYDIR"/"$STDOUT_NAME"
-        fi
-    fi
-    if [[ -f "$BUILD_DIR"/"$STDERR_NAME" ]] && \
-           ! (cmp -s -- "$BUILD_DIR"/"$STDERR_NAME" "$MYDIR"/"$STDERR_NAME"); then
-        echo updating "$MYDIR"/"$STDERR_NAME"
-        cp "$BUILD_DIR"/"$STDERR_NAME" "$MYDIR"/"$STDERR_NAME"
-        if [[ ! -s "$MYDIR"/"$STDERR_NAME" ]]; then
-            echo removing "$MYDIR"/"$STDERR_NAME"
-            rm "$MYDIR"/"$STDERR_NAME"
-        fi
-    fi
-    if [[ -f "$BUILD_DIR"/"$FIXED_NAME" ]] && \
-           ! (cmp -s -- "$BUILD_DIR"/"$FIXED_NAME" "$MYDIR"/"$FIXED_NAME"); then
-        echo updating "$MYDIR"/"$FIXED_NAME"
-        cp "$BUILD_DIR"/"$FIXED_NAME" "$MYDIR"/"$FIXED_NAME"
-        if [[ ! -s "$MYDIR"/"$FIXED_NAME" ]]; then
-            echo removing "$MYDIR"/"$FIXED_NAME"
-            rm "$MYDIR"/"$FIXED_NAME"
-        fi
-    fi
-done
diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed
index ebb3aa28daf..d6a890014e6 100644
--- a/src/tools/clippy/tests/ui/use_self.fixed
+++ b/src/tools/clippy/tests/ui/use_self.fixed
@@ -71,6 +71,7 @@ mod lifetimes {
 
 mod issue2894 {
     trait IntoBytes {
+        #[allow(clippy::wrong_self_convention)]
         fn into_bytes(&self) -> Vec<u8>;
     }
 
diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs
index 8a182192ab3..b04d9ce75b2 100644
--- a/src/tools/clippy/tests/ui/use_self.rs
+++ b/src/tools/clippy/tests/ui/use_self.rs
@@ -71,6 +71,7 @@ mod lifetimes {
 
 mod issue2894 {
     trait IntoBytes {
+        #[allow(clippy::wrong_self_convention)]
         fn into_bytes(&self) -> Vec<u8>;
     }
 
diff --git a/src/tools/clippy/tests/ui/use_self.stderr b/src/tools/clippy/tests/ui/use_self.stderr
index b33928597c1..80e1bfc75e8 100644
--- a/src/tools/clippy/tests/ui/use_self.stderr
+++ b/src/tools/clippy/tests/ui/use_self.stderr
@@ -37,19 +37,19 @@ LL |             Foo::new()
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:89:56
+  --> $DIR/use_self.rs:90:56
    |
 LL |         fn bad(foos: &[Self]) -> impl Iterator<Item = &Foo> {
    |                                                        ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:104:13
+  --> $DIR/use_self.rs:105:13
    |
 LL |             TS(0)
    |             ^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:112:25
+  --> $DIR/use_self.rs:113:25
    |
 LL |             fn new() -> Foo {
    |                         ^^^ help: use the applicable keyword: `Self`
@@ -60,7 +60,7 @@ LL |         use_self_expand!(); // Should lint in local macros
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:113:17
+  --> $DIR/use_self.rs:114:17
    |
 LL |                 Foo {}
    |                 ^^^ help: use the applicable keyword: `Self`
@@ -71,91 +71,91 @@ LL |         use_self_expand!(); // Should lint in local macros
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:148:21
+  --> $DIR/use_self.rs:149:21
    |
 LL |         fn baz() -> Foo {
    |                     ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:149:13
+  --> $DIR/use_self.rs:150:13
    |
 LL |             Foo {}
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:136:29
+  --> $DIR/use_self.rs:137:29
    |
 LL |                 fn bar() -> Bar {
    |                             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:137:21
+  --> $DIR/use_self.rs:138:21
    |
 LL |                     Bar { foo: Foo {} }
    |                     ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:166:21
+  --> $DIR/use_self.rs:167:21
    |
 LL |             let _ = Enum::B(42);
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:167:21
+  --> $DIR/use_self.rs:168:21
    |
 LL |             let _ = Enum::C { field: true };
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:168:21
+  --> $DIR/use_self.rs:169:21
    |
 LL |             let _ = Enum::A;
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:199:13
+  --> $DIR/use_self.rs:200:13
    |
 LL |             nested::A::fun_1();
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:200:13
+  --> $DIR/use_self.rs:201:13
    |
 LL |             nested::A::A;
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:202:13
+  --> $DIR/use_self.rs:203:13
    |
 LL |             nested::A {};
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:221:13
+  --> $DIR/use_self.rs:222:13
    |
 LL |             TestStruct::from_something()
    |             ^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:235:25
+  --> $DIR/use_self.rs:236:25
    |
 LL |         async fn g() -> S {
    |                         ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:236:13
+  --> $DIR/use_self.rs:237:13
    |
 LL |             S {}
    |             ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:240:16
+  --> $DIR/use_self.rs:241:16
    |
 LL |             &p[S::A..S::B]
    |                ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> $DIR/use_self.rs:240:22
+  --> $DIR/use_self.rs:241:22
    |
 LL |             &p[S::A..S::B]
    |                      ^ help: use the applicable keyword: `Self`
diff --git a/src/tools/clippy/tests/ui/wrong_self_convention.rs b/src/tools/clippy/tests/ui/wrong_self_convention.rs
index f44305d7e48..5282eba74fd 100644
--- a/src/tools/clippy/tests/ui/wrong_self_convention.rs
+++ b/src/tools/clippy/tests/ui/wrong_self_convention.rs
@@ -88,3 +88,52 @@ mod issue4037 {
         }
     }
 }
+
+// Lint also in trait definition (see #6307)
+mod issue6307 {
+    trait T: Sized {
+        fn as_i32(self) {}
+        fn as_u32(&self) {}
+        fn into_i32(&self) {}
+        fn into_u32(self) {}
+        fn is_i32(self) {}
+        fn is_u32(&self) {}
+        fn to_i32(self) {}
+        fn to_u32(&self) {}
+        fn from_i32(self) {}
+        // check whether the lint can be allowed at the function level
+        #[allow(clippy::wrong_self_convention)]
+        fn from_cake(self) {}
+
+        // test for false positives
+        fn as_(self) {}
+        fn into_(&self) {}
+        fn is_(self) {}
+        fn to_(self) {}
+        fn from_(self) {}
+        fn to_mut(&mut self) {}
+    }
+
+    trait U {
+        fn as_i32(self);
+        fn as_u32(&self);
+        fn into_i32(&self);
+        fn into_u32(self);
+        fn is_i32(self);
+        fn is_u32(&self);
+        fn to_i32(self);
+        fn to_u32(&self);
+        fn from_i32(self);
+        // check whether the lint can be allowed at the function level
+        #[allow(clippy::wrong_self_convention)]
+        fn from_cake(self);
+
+        // test for false positives
+        fn as_(self);
+        fn into_(&self);
+        fn is_(self);
+        fn to_(self);
+        fn from_(self);
+        fn to_mut(&mut self);
+    }
+}
diff --git a/src/tools/clippy/tests/ui/wrong_self_convention.stderr b/src/tools/clippy/tests/ui/wrong_self_convention.stderr
index ef3ad73ebc7..86467eb0fc7 100644
--- a/src/tools/clippy/tests/ui/wrong_self_convention.stderr
+++ b/src/tools/clippy/tests/ui/wrong_self_convention.stderr
@@ -72,5 +72,65 @@ error: methods called `from_*` usually take no self; consider choosing a less am
 LL |     pub fn from_i64(self) {}
    |                     ^^^^
 
-error: aborting due to 12 previous errors
+error: methods called `as_*` usually take self by reference or self by mutable reference; consider choosing a less ambiguous name
+  --> $DIR/wrong_self_convention.rs:95:19
+   |
+LL |         fn as_i32(self) {}
+   |                   ^^^^
+
+error: methods called `into_*` usually take self by value; consider choosing a less ambiguous name
+  --> $DIR/wrong_self_convention.rs:97:21
+   |
+LL |         fn into_i32(&self) {}
+   |                     ^^^^^
+
+error: methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name
+  --> $DIR/wrong_self_convention.rs:99:19
+   |
+LL |         fn is_i32(self) {}
+   |                   ^^^^
+
+error: methods called `to_*` usually take self by reference; consider choosing a less ambiguous name
+  --> $DIR/wrong_self_convention.rs:101:19
+   |
+LL |         fn to_i32(self) {}
+   |                   ^^^^
+
+error: methods called `from_*` usually take no self; consider choosing a less ambiguous name
+  --> $DIR/wrong_self_convention.rs:103:21
+   |
+LL |         fn from_i32(self) {}
+   |                     ^^^^
+
+error: methods called `as_*` usually take self by reference or self by mutable reference; consider choosing a less ambiguous name
+  --> $DIR/wrong_self_convention.rs:118:19
+   |
+LL |         fn as_i32(self);
+   |                   ^^^^
+
+error: methods called `into_*` usually take self by value; consider choosing a less ambiguous name
+  --> $DIR/wrong_self_convention.rs:120:21
+   |
+LL |         fn into_i32(&self);
+   |                     ^^^^^
+
+error: methods called `is_*` usually take self by reference or no self; consider choosing a less ambiguous name
+  --> $DIR/wrong_self_convention.rs:122:19
+   |
+LL |         fn is_i32(self);
+   |                   ^^^^
+
+error: methods called `to_*` usually take self by reference; consider choosing a less ambiguous name
+  --> $DIR/wrong_self_convention.rs:124:19
+   |
+LL |         fn to_i32(self);
+   |                   ^^^^
+
+error: methods called `from_*` usually take no self; consider choosing a less ambiguous name
+  --> $DIR/wrong_self_convention.rs:126:21
+   |
+LL |         fn from_i32(self);
+   |                     ^^^^
+
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/zero_sized_btreemap_values.rs b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.rs
new file mode 100644
index 00000000000..5cd254787d8
--- /dev/null
+++ b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.rs
@@ -0,0 +1,68 @@
+#![warn(clippy::zero_sized_map_values)]
+use std::collections::BTreeMap;
+
+const CONST_OK: Option<BTreeMap<String, usize>> = None;
+const CONST_NOT_OK: Option<BTreeMap<String, ()>> = None;
+
+static STATIC_OK: Option<BTreeMap<String, usize>> = None;
+static STATIC_NOT_OK: Option<BTreeMap<String, ()>> = None;
+
+type OkMap = BTreeMap<String, usize>;
+type NotOkMap = BTreeMap<String, ()>;
+
+enum TestEnum {
+    Ok(BTreeMap<String, usize>),
+    NotOk(BTreeMap<String, ()>),
+}
+
+struct Test {
+    ok: BTreeMap<String, usize>,
+    not_ok: BTreeMap<String, ()>,
+
+    also_not_ok: Vec<BTreeMap<usize, ()>>,
+}
+
+trait TestTrait {
+    type Output;
+
+    fn produce_output() -> Self::Output;
+
+    fn weird_map(&self, map: BTreeMap<usize, ()>);
+}
+
+impl Test {
+    fn ok(&self) -> BTreeMap<String, usize> {
+        todo!()
+    }
+
+    fn not_ok(&self) -> BTreeMap<String, ()> {
+        todo!()
+    }
+}
+
+impl TestTrait for Test {
+    type Output = BTreeMap<String, ()>;
+
+    fn produce_output() -> Self::Output {
+        todo!();
+    }
+
+    fn weird_map(&self, map: BTreeMap<usize, ()>) {
+        todo!();
+    }
+}
+
+fn test(map: BTreeMap<String, ()>, key: &str) -> BTreeMap<String, ()> {
+    todo!();
+}
+
+fn test2(map: BTreeMap<String, usize>, key: &str) -> BTreeMap<String, usize> {
+    todo!();
+}
+
+fn main() {
+    let _: BTreeMap<String, ()> = BTreeMap::new();
+    let _: BTreeMap<String, usize> = BTreeMap::new();
+
+    let _: BTreeMap<_, _> = std::iter::empty::<(String, ())>().collect();
+}
diff --git a/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr
new file mode 100644
index 00000000000..334d921a9af
--- /dev/null
+++ b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr
@@ -0,0 +1,107 @@
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:5:28
+   |
+LL | const CONST_NOT_OK: Option<BTreeMap<String, ()>> = None;
+   |                            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::zero-sized-map-values` implied by `-D warnings`
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:8:30
+   |
+LL | static STATIC_NOT_OK: Option<BTreeMap<String, ()>> = None;
+   |                              ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:11:17
+   |
+LL | type NotOkMap = BTreeMap<String, ()>;
+   |                 ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:15:11
+   |
+LL |     NotOk(BTreeMap<String, ()>),
+   |           ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:20:13
+   |
+LL |     not_ok: BTreeMap<String, ()>,
+   |             ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:22:22
+   |
+LL |     also_not_ok: Vec<BTreeMap<usize, ()>>,
+   |                      ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:30:30
+   |
+LL |     fn weird_map(&self, map: BTreeMap<usize, ()>);
+   |                              ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:38:25
+   |
+LL |     fn not_ok(&self) -> BTreeMap<String, ()> {
+   |                         ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:55:14
+   |
+LL | fn test(map: BTreeMap<String, ()>, key: &str) -> BTreeMap<String, ()> {
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:55:50
+   |
+LL | fn test(map: BTreeMap<String, ()>, key: &str) -> BTreeMap<String, ()> {
+   |                                                  ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:64:35
+   |
+LL |     let _: BTreeMap<String, ()> = BTreeMap::new();
+   |                                   ^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:64:12
+   |
+LL |     let _: BTreeMap<String, ()> = BTreeMap::new();
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_btreemap_values.rs:67:12
+   |
+LL |     let _: BTreeMap<_, _> = std::iter::empty::<(String, ())>().collect();
+   |            ^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: aborting due to 13 previous errors
+
diff --git a/src/tools/clippy/tests/ui/zero_sized_hashmap_values.rs b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.rs
new file mode 100644
index 00000000000..a1608d863fb
--- /dev/null
+++ b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.rs
@@ -0,0 +1,68 @@
+#![warn(clippy::zero_sized_map_values)]
+use std::collections::HashMap;
+
+const CONST_OK: Option<HashMap<String, usize>> = None;
+const CONST_NOT_OK: Option<HashMap<String, ()>> = None;
+
+static STATIC_OK: Option<HashMap<String, usize>> = None;
+static STATIC_NOT_OK: Option<HashMap<String, ()>> = None;
+
+type OkMap = HashMap<String, usize>;
+type NotOkMap = HashMap<String, ()>;
+
+enum TestEnum {
+    Ok(HashMap<String, usize>),
+    NotOk(HashMap<String, ()>),
+}
+
+struct Test {
+    ok: HashMap<String, usize>,
+    not_ok: HashMap<String, ()>,
+
+    also_not_ok: Vec<HashMap<usize, ()>>,
+}
+
+trait TestTrait {
+    type Output;
+
+    fn produce_output() -> Self::Output;
+
+    fn weird_map(&self, map: HashMap<usize, ()>);
+}
+
+impl Test {
+    fn ok(&self) -> HashMap<String, usize> {
+        todo!()
+    }
+
+    fn not_ok(&self) -> HashMap<String, ()> {
+        todo!()
+    }
+}
+
+impl TestTrait for Test {
+    type Output = HashMap<String, ()>;
+
+    fn produce_output() -> Self::Output {
+        todo!();
+    }
+
+    fn weird_map(&self, map: HashMap<usize, ()>) {
+        todo!();
+    }
+}
+
+fn test(map: HashMap<String, ()>, key: &str) -> HashMap<String, ()> {
+    todo!();
+}
+
+fn test2(map: HashMap<String, usize>, key: &str) -> HashMap<String, usize> {
+    todo!();
+}
+
+fn main() {
+    let _: HashMap<String, ()> = HashMap::new();
+    let _: HashMap<String, usize> = HashMap::new();
+
+    let _: HashMap<_, _> = std::iter::empty::<(String, ())>().collect();
+}
diff --git a/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr
new file mode 100644
index 00000000000..43987b3d01d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr
@@ -0,0 +1,107 @@
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:5:28
+   |
+LL | const CONST_NOT_OK: Option<HashMap<String, ()>> = None;
+   |                            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::zero-sized-map-values` implied by `-D warnings`
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:8:30
+   |
+LL | static STATIC_NOT_OK: Option<HashMap<String, ()>> = None;
+   |                              ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:11:17
+   |
+LL | type NotOkMap = HashMap<String, ()>;
+   |                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:15:11
+   |
+LL |     NotOk(HashMap<String, ()>),
+   |           ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:20:13
+   |
+LL |     not_ok: HashMap<String, ()>,
+   |             ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:22:22
+   |
+LL |     also_not_ok: Vec<HashMap<usize, ()>>,
+   |                      ^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:30:30
+   |
+LL |     fn weird_map(&self, map: HashMap<usize, ()>);
+   |                              ^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:38:25
+   |
+LL |     fn not_ok(&self) -> HashMap<String, ()> {
+   |                         ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:55:14
+   |
+LL | fn test(map: HashMap<String, ()>, key: &str) -> HashMap<String, ()> {
+   |              ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:55:49
+   |
+LL | fn test(map: HashMap<String, ()>, key: &str) -> HashMap<String, ()> {
+   |                                                 ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:64:34
+   |
+LL |     let _: HashMap<String, ()> = HashMap::new();
+   |                                  ^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:64:12
+   |
+LL |     let _: HashMap<String, ()> = HashMap::new();
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: map with zero-sized value type
+  --> $DIR/zero_sized_hashmap_values.rs:67:12
+   |
+LL |     let _: HashMap<_, _> = std::iter::empty::<(String, ())>().collect();
+   |            ^^^^^^^^^^^^^
+   |
+   = help: consider using a set instead
+
+error: aborting due to 13 previous errors
+
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index b7b20b40e68..b9549be3a8b 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -1,7 +1,7 @@
 [relabel]
 allow-unauthenticated = [
     "A-*", "C-*", "E-*", "L-*", "M-*", "O-*", "P-*", "S-*", "T-*",
-    "good first issue"
+    "good-first-issue"
 ]
 
 [assign]
diff --git a/src/tools/clippy/util/gh-pages/index.html b/src/tools/clippy/util/gh-pages/index.html
index e11f2eeba3b..428708136cb 100644
--- a/src/tools/clippy/util/gh-pages/index.html
+++ b/src/tools/clippy/util/gh-pages/index.html
@@ -89,7 +89,7 @@
             </div>
 
             <article class="panel panel-default" id="{{lint.id}}"
-                ng-repeat="lint in data | filter:byLevels | filter:byGroups | filter:search | orderBy:'id' track by lint.id" on-finish-render="ngRepeatFinished">
+                ng-repeat="lint in data | filter:byLevels | filter:byGroups | filter:bySearch | orderBy:'id' track by lint.id">
                 <header class="panel-heading" ng-click="open[lint.id] = !open[lint.id]">
                     <h2 class="panel-title">
                         <div class="panel-title-name">
@@ -215,6 +215,46 @@
                 return $scope.groups[lint.group];
             };
 
+            $scope.bySearch = function (lint, index, array) {
+                let search_str = $scope.search;
+                // It can be `null` I haven't missed this value 
+                if (search_str == null || search_str.length == 0) {
+                    return true;
+                }
+                search_str = search_str.toLowerCase();
+
+                // Search by id
+                let id_search = search_str.trim().replace(/(\-| )/g, "_");
+                if (lint.id.includes(id_search)) {
+                    return true;
+                }
+
+                // Search the description
+                // The use of `for`-loops instead of `foreach` enables us to return early 
+                let search_lint = (lint, therm) => {
+                    for (const field in lint.docs) {
+                        // Continue if it's not a property
+                        if (!lint.docs.hasOwnProperty(field)) {
+                            continue;
+                        }
+
+                        // Return if not found
+                        if (lint.docs[field].toLowerCase().includes(therm)) {
+                            return true;
+                        }
+                    }
+                    return false;
+                };
+                let therms = search_str.split(" ");
+                for (index = 0; index < therms.length; index++) {
+                    if (!search_lint(lint, therms[index])) {
+                        return false;
+                    }
+                }
+
+                return true;
+            }
+
             // Get data
             $scope.open = {};
             $scope.loading = true;
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index eba02333c8c..43dbaeb4655 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -10,8 +10,6 @@ use test::ColorConfig;
 
 #[derive(Clone, Copy, PartialEq, Debug)]
 pub enum Mode {
-    CompileFail,
-    RunFail,
     RunPassValgrind,
     Pretty,
     DebugInfo,
@@ -42,8 +40,6 @@ impl FromStr for Mode {
     type Err = ();
     fn from_str(s: &str) -> Result<Mode, ()> {
         match s {
-            "compile-fail" => Ok(CompileFail),
-            "run-fail" => Ok(RunFail),
             "run-pass-valgrind" => Ok(RunPassValgrind),
             "pretty" => Ok(Pretty),
             "debuginfo" => Ok(DebugInfo),
@@ -65,8 +61,6 @@ impl FromStr for Mode {
 impl fmt::Display for Mode {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let s = match *self {
-            CompileFail => "compile-fail",
-            RunFail => "run-fail",
             RunPassValgrind => "run-pass-valgrind",
             Pretty => "pretty",
             DebugInfo => "debuginfo",
@@ -127,6 +121,8 @@ pub enum CompareMode {
     Nll,
     Polonius,
     Chalk,
+    SplitDwarf,
+    SplitDwarfSingle,
 }
 
 impl CompareMode {
@@ -135,6 +131,8 @@ impl CompareMode {
             CompareMode::Nll => "nll",
             CompareMode::Polonius => "polonius",
             CompareMode::Chalk => "chalk",
+            CompareMode::SplitDwarf => "split-dwarf",
+            CompareMode::SplitDwarfSingle => "split-dwarf-single",
         }
     }
 
@@ -143,6 +141,8 @@ impl CompareMode {
             "nll" => CompareMode::Nll,
             "polonius" => CompareMode::Polonius,
             "chalk" => CompareMode::Chalk,
+            "split-dwarf" => CompareMode::SplitDwarf,
+            "split-dwarf-single" => CompareMode::SplitDwarfSingle,
             x => panic!("unknown --compare-mode option: {}", x),
         }
     }
@@ -224,7 +224,7 @@ pub struct Config {
     /// The name of the stage being built (stage1, etc)
     pub stage_id: String,
 
-    /// The test mode, compile-fail, run-fail, ui
+    /// The test mode, e.g. ui or debuginfo.
     pub mode: Mode,
 
     /// The test suite (essentially which directory is running, but without the
@@ -327,6 +327,9 @@ pub struct Config {
     /// created in `/<build_base>/rustfix_missing_coverage.txt`
     pub rustfix_coverage: bool,
 
+    /// whether to run `tidy` when a rustdoc test fails
+    pub has_tidy: bool,
+
     // Configuration for various run-make tests frobbing things like C compilers
     // or querying about various LLVM component information.
     pub cc: String,
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 59f64e7df0f..2eba91fd1f4 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -542,10 +542,7 @@ impl TestProps {
         }
 
         if self.failure_status == -1 {
-            self.failure_status = match config.mode {
-                Mode::RunFail => 101,
-                _ => 1,
-            };
+            self.failure_status = 1;
         }
         if self.should_ice {
             self.failure_status = 101;
@@ -852,6 +849,8 @@ impl Config {
                 Some(CompareMode::Nll) => name == "compare-mode-nll",
                 Some(CompareMode::Polonius) => name == "compare-mode-polonius",
                 Some(CompareMode::Chalk) => name == "compare-mode-chalk",
+                Some(CompareMode::SplitDwarf) => name == "compare-mode-split-dwarf",
+                Some(CompareMode::SplitDwarfSingle) => name == "compare-mode-split-dwarf-single",
                 None => false,
             } ||
             (cfg!(debug_assertions) && name == "debug") ||
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 5177dae8a66..aefcfe222e5 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -14,7 +14,7 @@ use std::ffi::OsString;
 use std::fs;
 use std::io::{self, ErrorKind};
 use std::path::{Path, PathBuf};
-use std::process::Command;
+use std::process::{Command, Stdio};
 use std::time::SystemTime;
 use test::ColorConfig;
 use tracing::*;
@@ -43,6 +43,10 @@ fn main() {
         panic!("Can't find Valgrind to run Valgrind tests");
     }
 
+    if !config.has_tidy && config.mode == Mode::Rustdoc {
+        eprintln!("warning: `tidy` is not installed; generated diffs will be harder to read");
+    }
+
     log_config(&config);
     run_tests(config);
 }
@@ -67,7 +71,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
             "",
             "mode",
             "which sort of compile tests to run",
-            "compile-fail | run-fail | run-pass-valgrind | pretty | debug-info | codegen | rustdoc \
+            "run-pass-valgrind | pretty | debug-info | codegen | rustdoc \
             | rustdoc-json | codegen-units | incremental | run-make | ui | js-doc-test | mir-opt | assembly",
         )
         .reqopt(
@@ -189,6 +193,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
 
     let src_base = opt_path(matches, "src-base");
     let run_ignored = matches.opt_present("ignored");
+    let has_tidy = Command::new("tidy")
+        .arg("--version")
+        .stdout(Stdio::null())
+        .status()
+        .map_or(false, |status| status.success());
     Config {
         bless: matches.opt_present("bless"),
         compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")),
@@ -244,6 +253,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         remote_test_client: matches.opt_str("remote-test-client").map(PathBuf::from),
         compare_mode: matches.opt_str("compare-mode").map(CompareMode::parse),
         rustfix_coverage: matches.opt_present("rustfix-coverage"),
+        has_tidy,
 
         cc: matches.opt_str("cc").unwrap(),
         cxx: matches.opt_str("cxx").unwrap(),
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index e9089b4b15b..9f31b3ae1b1 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -5,8 +5,8 @@ use crate::common::{output_base_dir, output_base_name, output_testname_unique};
 use crate::common::{Assembly, Incremental, JsDocTest, MirOpt, RunMake, RustdocJson, Ui};
 use crate::common::{Codegen, CodegenUnits, DebugInfo, Debugger, Rustdoc};
 use crate::common::{CompareMode, FailMode, PassMode};
-use crate::common::{CompileFail, Pretty, RunFail, RunPassValgrind};
 use crate::common::{Config, TestPaths};
+use crate::common::{Pretty, RunPassValgrind};
 use crate::common::{UI_RUN_STDERR, UI_RUN_STDOUT};
 use crate::errors::{self, Error, ErrorKind};
 use crate::header::TestProps;
@@ -330,13 +330,11 @@ impl<'test> TestCx<'test> {
     /// revisions, exactly once, with revision == None).
     fn run_revision(&self) {
         if self.props.should_ice {
-            if self.config.mode != CompileFail && self.config.mode != Incremental {
+            if self.config.mode != Incremental {
                 self.fatal("cannot use should-ice in a test that is not cfail");
             }
         }
         match self.config.mode {
-            CompileFail => self.run_cfail_test(),
-            RunFail => self.run_rfail_test(),
             RunPassValgrind => self.run_valgrind_test(),
             Pretty => self.run_pretty_test(),
             DebugInfo => self.run_debuginfo_test(),
@@ -377,7 +375,6 @@ impl<'test> TestCx<'test> {
 
     fn should_compile_successfully(&self, pm: Option<PassMode>) -> bool {
         match self.config.mode {
-            CompileFail => false,
             JsDocTest => true,
             Ui => pm.is_some() || self.props.fail_mode > Some(FailMode::Build),
             Incremental => {
@@ -1537,8 +1534,8 @@ impl<'test> TestCx<'test> {
         };
 
         let allow_unused = match self.config.mode {
-            CompileFail | Ui => {
-                // compile-fail and ui tests tend to have tons of unused code as
+            Ui => {
+                // UI tests tend to have tons of unused code as
                 // it's just testing various pieces of the compile, but we don't
                 // want to actually assert warnings about all this code. Instead
                 // let's just ignore unused code warnings by defaults and tests
@@ -1940,7 +1937,7 @@ impl<'test> TestCx<'test> {
         }
 
         match self.config.mode {
-            CompileFail | Incremental => {
+            Incremental => {
                 // If we are extracting and matching errors in the new
                 // fashion, then you want JSON mode. Old-skool error
                 // patterns still match the raw compiler output.
@@ -1975,8 +1972,8 @@ impl<'test> TestCx<'test> {
 
                 rustc.arg(dir_opt);
             }
-            RunFail | RunPassValgrind | Pretty | DebugInfo | Codegen | Rustdoc | RustdocJson
-            | RunMake | CodegenUnits | JsDocTest | Assembly => {
+            RunPassValgrind | Pretty | DebugInfo | Codegen | Rustdoc | RustdocJson | RunMake
+            | CodegenUnits | JsDocTest | Assembly => {
                 // do not use JSON output
             }
         }
@@ -2017,6 +2014,12 @@ impl<'test> TestCx<'test> {
             Some(CompareMode::Chalk) => {
                 rustc.args(&["-Zchalk"]);
             }
+            Some(CompareMode::SplitDwarf) => {
+                rustc.args(&["-Zsplit-dwarf=split"]);
+            }
+            Some(CompareMode::SplitDwarfSingle) => {
+                rustc.args(&["-Zsplit-dwarf=single"]);
+            }
             None => {}
         }
 
@@ -2394,7 +2397,8 @@ impl<'test> TestCx<'test> {
 
         let proc_res = new_rustdoc.document(&compare_dir);
         if !proc_res.status.success() {
-            proc_res.fatal(Some("failed to run nightly rustdoc"), || ());
+            eprintln!("failed to run nightly rustdoc");
+            return;
         }
 
         #[rustfmt::skip]
@@ -2408,28 +2412,22 @@ impl<'test> TestCx<'test> {
             "-modify",
         ];
         let tidy_dir = |dir| {
-            let tidy = |file: &_| {
-                Command::new("tidy")
-                    .args(&tidy_args)
-                    .arg(file)
-                    .spawn()
-                    .unwrap_or_else(|err| {
-                        self.fatal(&format!("failed to run tidy - is it installed? - {}", err))
-                    })
-                    .wait()
-                    .unwrap()
-            };
             for entry in walkdir::WalkDir::new(dir) {
                 let entry = entry.expect("failed to read file");
                 if entry.file_type().is_file()
                     && entry.path().extension().and_then(|p| p.to_str()) == Some("html".into())
                 {
-                    tidy(entry.path());
+                    let status =
+                        Command::new("tidy").args(&tidy_args).arg(entry.path()).status().unwrap();
+                    // `tidy` returns 1 if it modified the file.
+                    assert!(status.success() || status.code() == Some(1));
                 }
             }
         };
-        tidy_dir(out_dir);
-        tidy_dir(&compare_dir);
+        if self.config.has_tidy {
+            tidy_dir(out_dir);
+            tidy_dir(&compare_dir);
+        }
 
         let pager = {
             let output = Command::new("git").args(&["config", "--get", "core.pager"]).output().ok();
@@ -2442,7 +2440,8 @@ impl<'test> TestCx<'test> {
             })
         };
         let mut diff = Command::new("diff");
-        diff.args(&["-u", "-r"]).args(&[out_dir, &compare_dir]);
+        // diff recursively, showing context, and excluding .css files
+        diff.args(&["-u", "-r", "-x", "*.css"]).args(&[&compare_dir, out_dir]);
 
         let output = if let Some(pager) = pager {
             let diff_pid = diff.stdout(Stdio::piped()).spawn().expect("failed to run `diff`");
diff --git a/src/tools/expand-yaml-anchors/src/main.rs b/src/tools/expand-yaml-anchors/src/main.rs
index f7ff64036a1..f8cf18a9309 100644
--- a/src/tools/expand-yaml-anchors/src/main.rs
+++ b/src/tools/expand-yaml-anchors/src/main.rs
@@ -87,7 +87,8 @@ impl App {
         let content = std::fs::read_to_string(source)
             .with_context(|| format!("failed to read {}", self.path(source)))?;
 
-        let mut buf = HEADER_MESSAGE.replace("{source}", &self.path(source).to_string());
+        let mut buf =
+            HEADER_MESSAGE.replace("{source}", &self.path(source).to_string().replace("\\", "/"));
 
         let documents = YamlLoader::load_from_str(&content)
             .with_context(|| format!("failed to parse {}", self.path(source)))?;
diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs
index f213944e0ab..dcfe1bb803f 100644
--- a/src/tools/linkchecker/main.rs
+++ b/src/tools/linkchecker/main.rs
@@ -14,6 +14,8 @@
 //! A few exceptions are allowed as there's known bugs in rustdoc, but this
 //! should catch the majority of "broken link" cases.
 
+#![feature(str_split_once)]
+
 use std::collections::hash_map::Entry;
 use std::collections::{HashMap, HashSet};
 use std::env;
@@ -232,11 +234,12 @@ fn check(cache: &mut Cache, root: &Path, file: &Path, errors: &mut bool) -> Opti
         {
             return;
         }
-        let mut parts = url.splitn(2, '#');
-        let url = parts.next().unwrap();
-        let fragment = parts.next();
-        let mut parts = url.splitn(2, '?');
-        let url = parts.next().unwrap();
+        let (url, fragment) = match url.split_once('#') {
+            None => (url, None),
+            Some((url, fragment)) => (url, Some(fragment)),
+        };
+        // NB: the `splitn` always succeeds, even if the delimiter is not present.
+        let url = url.splitn(2, '?').next().unwrap();
 
         // Once we've plucked out the URL, parse it using our base url and
         // then try to extract a file path.
diff --git a/src/tools/lint-docs/src/groups.rs b/src/tools/lint-docs/src/groups.rs
index 0a69b18a332..e8fd19a6381 100644
--- a/src/tools/lint-docs/src/groups.rs
+++ b/src/tools/lint-docs/src/groups.rs
@@ -116,13 +116,23 @@ impl<'a> LintExtractor<'a> {
         result.push('\n');
         result.push_str("[warn-by-default]: listing/warn-by-default.md\n");
         for lint_name in to_link {
-            let lint_def =
-                lints.iter().find(|l| l.name == lint_name.replace("-", "_")).ok_or_else(|| {
-                    format!(
-                        "`rustc -W help` defined lint `{}` but that lint does not appear to exist",
+            let lint_def = match lints.iter().find(|l| l.name == lint_name.replace("-", "_")) {
+                Some(def) => def,
+                None => {
+                    let msg = format!(
+                        "`rustc -W help` defined lint `{}` but that lint does not \
+                        appear to exist\n\
+                        Check that the lint definition includes the appropriate doc comments.",
                         lint_name
-                    )
-                })?;
+                    );
+                    if self.validate {
+                        return Err(msg.into());
+                    } else {
+                        eprintln!("warning: {}", msg);
+                        continue;
+                    }
+                }
+            };
             write!(
                 result,
                 "[{}]: listing/{}#{}\n",
diff --git a/src/tools/miri b/src/tools/miri
-Subproject e54c5db4f0edbe51db42d2c3e63e9821537ed4f
+Subproject 2065b52dfef3cd5a5216e65c21a056a69574bdd
diff --git a/src/tools/rust-installer b/src/tools/rust-installer
-Subproject d66f476b4d5e7fdf1ec215c9ac16c923dc29232
+Subproject 5254dbfd25d5284728ab624dca1969d61427a0d
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index 11b175f9e80..1cde0e25ced 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -65,6 +65,8 @@ byteorder = { version = "1", features = ['default', 'std'] }
 curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true }
 crossbeam-utils = { version = "0.7.2", features = ["nightly"] }
 libc = { version = "0.2.79", features = ["align"] }
+# Ensure default features of libz-sys, which are disabled in some scenarios.
+libz-sys = { version = "1.1.2" }
 proc-macro2 = { version = "1", features = ["default"] }
 quote = { version = "1", features = ["default"] }
 serde = { version = "1.0.82", features = ['derive'] }
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
-Subproject 70ce18255f429caf0d75ecfed8c1464535ee779
+Subproject acd94866fd0ff5eacb7e184ae21c19e5440fc5f
diff --git a/src/tools/tidy/src/cargo.rs b/src/tools/tidy/src/cargo.rs
index 7bdd78a91e7..e06616a59f3 100644
--- a/src/tools/tidy/src/cargo.rs
+++ b/src/tools/tidy/src/cargo.rs
@@ -59,11 +59,10 @@ fn verify(tomlfile: &Path, libfile: &Path, bad: &mut bool) {
             break;
         }
 
-        let mut parts = line.splitn(2, '=');
-        let krate = parts.next().unwrap().trim();
-        if parts.next().is_none() {
-            continue;
-        }
+        let krate = match line.split_once('=') {
+            None => continue,
+            Some((krate, _)) => krate.trim(),
+        };
 
         // Don't worry about depending on core/std while not writing `extern crate
         // core/std` -- that's intentional.
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 057b0884e28..4b521985ca1 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -104,6 +104,7 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
     "getopts",
     "getrandom",
     "gimli",
+    "gsgdt",
     "hashbrown",
     "hermit-abi",
     "humantime",
@@ -214,12 +215,12 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) {
     for (name, license) in EXCEPTIONS {
         // Check that the package actually exists.
         if !metadata.packages.iter().any(|p| p.name == *name) {
-            println!(
+            tidy_error!(
+                bad,
                 "could not find exception package `{}`\n\
                 Remove from EXCEPTIONS list if it is no longer used.",
                 name
             );
-            *bad = true;
         }
         // Check that the license hasn't changed.
         for pkg in metadata.packages.iter().filter(|p| p.name == *name) {
@@ -232,11 +233,11 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) {
             }
             match &pkg.license {
                 None => {
-                    println!(
+                    tidy_error!(
+                        bad,
                         "dependency exception `{}` does not declare a license expression",
                         pkg.id
                     );
-                    *bad = true;
                 }
                 Some(pkg_license) => {
                     if pkg_license.as_str() != *license {
@@ -273,8 +274,7 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) {
         let license = match &pkg.license {
             Some(license) => license,
             None => {
-                println!("dependency `{}` does not define a license expression", pkg.id,);
-                *bad = true;
+                tidy_error!(bad, "dependency `{}` does not define a license expression", pkg.id);
                 continue;
             }
         };
@@ -286,8 +286,7 @@ fn check_exceptions(metadata: &Metadata, bad: &mut bool) {
                 // general, these should never be added.
                 continue;
             }
-            println!("invalid license `{}` in `{}`", license, pkg.id);
-            *bad = true;
+            tidy_error!(bad, "invalid license `{}` in `{}`", license, pkg.id);
         }
     }
 }
@@ -300,12 +299,12 @@ fn check_dependencies(metadata: &Metadata, bad: &mut bool) {
     // Check that the PERMITTED_DEPENDENCIES does not have unused entries.
     for name in PERMITTED_DEPENDENCIES {
         if !metadata.packages.iter().any(|p| p.name == *name) {
-            println!(
+            tidy_error!(
+                bad,
                 "could not find allowed package `{}`\n\
                 Remove from PERMITTED_DEPENDENCIES list if it is no longer used.",
                 name
             );
-            *bad = true;
         }
     }
     // Get the list in a convenient form.
@@ -322,11 +321,10 @@ fn check_dependencies(metadata: &Metadata, bad: &mut bool) {
     }
 
     if !unapproved.is_empty() {
-        println!("Dependencies not explicitly permitted:");
+        tidy_error!(bad, "Dependencies not explicitly permitted:");
         for dep in unapproved {
             println!("* {}", dep);
         }
-        *bad = true;
     }
 }
 
@@ -381,16 +379,17 @@ fn check_crate_duplicate(metadata: &Metadata, bad: &mut bool) {
         let matches: Vec<_> = metadata.packages.iter().filter(|pkg| pkg.name == name).collect();
         match matches.len() {
             0 => {
-                println!(
+                tidy_error!(
+                    bad,
                     "crate `{}` is missing, update `check_crate_duplicate` \
                     if it is no longer used",
                     name
                 );
-                *bad = true;
             }
             1 => {}
             _ => {
-                println!(
+                tidy_error!(
+                    bad,
                     "crate `{}` is duplicated in `Cargo.lock`, \
                     it is too expensive to build multiple times, \
                     so make sure only one version appears across all dependencies",
@@ -399,7 +398,6 @@ fn check_crate_duplicate(metadata: &Metadata, bad: &mut bool) {
                 for pkg in matches {
                     println!("  * {}", pkg.id);
                 }
-                *bad = true;
             }
         }
     }
diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs
index 82a5234ac5b..a7199fdfce6 100644
--- a/src/tools/tidy/src/error_codes_check.rs
+++ b/src/tools/tidy/src/error_codes_check.rs
@@ -85,47 +85,61 @@ fn extract_error_codes(
     for line in f.lines() {
         let s = line.trim();
         if !reached_no_explanation && s.starts_with('E') && s.contains("include_str!(\"") {
-            if let Some(err_code) = s.splitn(2, ':').next() {
-                let err_code = err_code.to_owned();
-                if !error_codes.contains_key(&err_code) {
-                    error_codes.insert(err_code.clone(), false);
-                }
-                // Now we extract the tests from the markdown file!
-                let md = some_or_continue!(s.splitn(2, "include_str!(\"").nth(1));
-                let md_file_name = some_or_continue!(md.splitn(2, "\")").next());
-                let path = some_or_continue!(path.parent())
-                    .join(md_file_name)
-                    .canonicalize()
-                    .expect("failed to canonicalize error explanation file path");
-                match read_to_string(&path) {
-                    Ok(content) => {
-                        if !IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str())
-                            && !check_if_error_code_is_test_in_explanation(&content, &err_code)
-                        {
-                            errors.push(format!(
-                                "`{}` doesn't use its own error code in compile_fail example",
-                                path.display(),
-                            ));
-                        }
-                        if check_error_code_explanation(&content, error_codes, err_code) {
-                            errors.push(format!(
-                                "`{}` uses invalid tag `compile-fail` instead of `compile_fail`",
-                                path.display(),
-                            ));
-                        }
+            let err_code = s
+                .split_once(':')
+                .expect(
+                    format!(
+                        "Expected a line with the format `E0xxx: include_str!(\"..\")`, but got {} without a `:` delimiter",
+                        s,
+                    ).as_str()
+                )
+                .0
+                .to_owned();
+            if !error_codes.contains_key(&err_code) {
+                error_codes.insert(err_code.clone(), false);
+            }
+            // Now we extract the tests from the markdown file!
+            let md_file_name = match s.split_once("include_str!(\"") {
+                None => continue,
+                Some((_, md)) => match md.split_once("\")") {
+                    None => continue,
+                    Some((file_name, _)) => file_name,
+                },
+            };
+            let path = some_or_continue!(path.parent())
+                .join(md_file_name)
+                .canonicalize()
+                .expect("failed to canonicalize error explanation file path");
+            match read_to_string(&path) {
+                Ok(content) => {
+                    if !IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str())
+                        && !check_if_error_code_is_test_in_explanation(&content, &err_code)
+                    {
+                        errors.push(format!(
+                            "`{}` doesn't use its own error code in compile_fail example",
+                            path.display(),
+                        ));
                     }
-                    Err(e) => {
-                        eprintln!("Couldn't read `{}`: {}", path.display(), e);
+                    if check_error_code_explanation(&content, error_codes, err_code) {
+                        errors.push(format!(
+                            "`{}` uses invalid tag `compile-fail` instead of `compile_fail`",
+                            path.display(),
+                        ));
                     }
                 }
+                Err(e) => {
+                    eprintln!("Couldn't read `{}`: {}", path.display(), e);
+                }
             }
         } else if reached_no_explanation && s.starts_with('E') {
-            if let Some(err_code) = s.splitn(2, ',').next() {
-                let err_code = err_code.to_owned();
-                if !error_codes.contains_key(&err_code) {
-                    // this check should *never* fail!
-                    error_codes.insert(err_code, false);
-                }
+            let err_code = match s.split_once(',') {
+                None => s,
+                Some((err_code, _)) => err_code,
+            }
+            .to_string();
+            if !error_codes.contains_key(&err_code) {
+                // this check should *never* fail!
+                error_codes.insert(err_code, false);
             }
         } else if s == ";" {
             reached_no_explanation = true;
@@ -137,12 +151,15 @@ fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap<String, boo
     for line in f.lines() {
         let s = line.trim();
         if s.starts_with("error[E") || s.starts_with("warning[E") {
-            if let Some(err_code) = s.splitn(2, ']').next() {
-                if let Some(err_code) = err_code.splitn(2, '[').nth(1) {
-                    let nb = error_codes.entry(err_code.to_owned()).or_insert(false);
-                    *nb = true;
-                }
-            }
+            let err_code = match s.split_once(']') {
+                None => continue,
+                Some((err_code, _)) => match err_code.split_once('[') {
+                    None => continue,
+                    Some((_, err_code)) => err_code,
+                },
+            };
+            let nb = error_codes.entry(err_code.to_owned()).or_insert(false);
+            *nb = true;
         }
     }
 }
diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs
index 1cf0d24e26f..aad57cacbb4 100644
--- a/src/tools/tidy/src/extdeps.rs
+++ b/src/tools/tidy/src/extdeps.rs
@@ -23,12 +23,11 @@ pub fn check(root: &Path, bad: &mut bool) {
         }
 
         // Extract source value.
-        let source = line.splitn(2, '=').nth(1).unwrap().trim();
+        let source = line.split_once('=').unwrap().1.trim();
 
         // Ensure source is allowed.
         if !ALLOWED_SOURCES.contains(&&*source) {
-            println!("invalid source: {}", source);
-            *bad = true;
+            tidy_error!(bad, "invalid source: {}", source);
         }
     }
 }
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index d8029ea04f0..384a291a777 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -85,11 +85,7 @@ pub fn check(
     assert!(!lib_features.is_empty());
 
     super::walk_many(
-        &[
-            &src_path.join("test/ui"),
-            &src_path.join("test/ui-fulldeps"),
-            &src_path.join("test/compile-fail"),
-        ],
+        &[&src_path.join("test/ui"), &src_path.join("test/ui-fulldeps")],
         &mut |path| super::filter_dirs(path),
         &mut |entry, contents| {
             let file = entry.path();
@@ -112,6 +108,7 @@ pub fn check(
                 let gate_test_str = "gate-test-";
 
                 let feature_name = match line.find(gate_test_str) {
+                    // NB: the `splitn` always succeeds, even if the delimiter is not present.
                     Some(i) => line[i + gate_test_str.len()..].splitn(2, ' ').next().unwrap(),
                     None => continue,
                 };
@@ -329,7 +326,6 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features
             let issue_str = parts.next().unwrap().trim();
             let tracking_issue = if issue_str.starts_with("None") {
                 if level == Status::Unstable && !next_feature_omits_tracking_issue {
-                    *bad = true;
                     tidy_error!(
                         bad,
                         "{}:{}: no tracking issue for feature {}",
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index cc4c43f0468..d282d240d82 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -3,6 +3,8 @@
 //! This library contains the tidy lints and exposes it
 //! to be used by tools.
 
+#![feature(str_split_once)]
+
 use std::fs::File;
 use std::io::Read;
 use walkdir::{DirEntry, WalkDir};
@@ -26,6 +28,10 @@ macro_rules! t {
 }
 
 macro_rules! tidy_error {
+    ($bad:expr, $fmt:expr) => ({
+        *$bad = true;
+        eprintln!("tidy error: {}", $fmt);
+    });
     ($bad:expr, $fmt:expr, $($arg:tt)*) => ({
         *$bad = true;
         eprint!("tidy error: ");
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index e1525f8e1bf..080e1631624 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -35,9 +35,12 @@ fn main() {
 
     // Checks that only make sense for the std libs.
     pal::check(&library_path, &mut bad);
-    unit_tests::check(&library_path, &mut bad);
 
     // Checks that need to be done for both the compiler and std libraries.
+    unit_tests::check(&src_path, &mut bad);
+    unit_tests::check(&compiler_path, &mut bad);
+    unit_tests::check(&library_path, &mut bad);
+
     bins::check(&src_path, &output_directory, &mut bad);
     bins::check(&compiler_path, &output_directory, &mut bad);
     bins::check(&library_path, &output_directory, &mut bad);
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 47b328dae47..d8d2b449fee 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -1,9 +1,51 @@
-//! Tidy check to ensure that there are no stray `.stderr` files in UI test directories.
+//! Tidy check to ensure below in UI test directories:
+//! - the number of entries in each directory must be less than `ENTRY_LIMIT`
+//! - there are no stray `.stderr` files
 
 use std::fs;
 use std::path::Path;
 
+const ENTRY_LIMIT: usize = 1000;
+// FIXME: The following limits should be reduced eventually.
+const ROOT_ENTRY_LIMIT: usize = 1580;
+const ISSUES_ENTRY_LIMIT: usize = 2830;
+
+fn check_entries(path: &Path, bad: &mut bool) {
+    let dirs = walkdir::WalkDir::new(&path.join("test/ui"))
+        .into_iter()
+        .filter_entry(|e| e.file_type().is_dir());
+    for dir in dirs {
+        if let Ok(dir) = dir {
+            let dir_path = dir.path();
+
+            // Use special values for these dirs.
+            let is_root = path.join("test/ui") == dir_path;
+            let is_issues_dir = path.join("test/ui/issues") == dir_path;
+            let limit = if is_root {
+                ROOT_ENTRY_LIMIT
+            } else if is_issues_dir {
+                ISSUES_ENTRY_LIMIT
+            } else {
+                ENTRY_LIMIT
+            };
+
+            let count = std::fs::read_dir(dir_path).unwrap().count();
+            if count >= limit {
+                tidy_error!(
+                    bad,
+                    "following path contains more than {} entries, \
+                    you should move the test to some relevant subdirectory (current: {}): {}",
+                    limit,
+                    count,
+                    dir_path.display()
+                );
+            }
+        }
+    }
+}
+
 pub fn check(path: &Path, bad: &mut bool) {
+    check_entries(&path, bad);
     for path in &[&path.join("test/ui"), &path.join("test/ui-fulldeps")] {
         super::walk_no_read(path, &mut |_| false, &mut |entry| {
             let file_path = entry.path();
@@ -19,23 +61,18 @@ pub fn check(path: &Path, bad: &mut bool) {
                     //
                     // For now, just make sure that there is a corresponding
                     // `$testname.rs` file.
-                    let testname = file_path
-                        .file_name()
-                        .unwrap()
-                        .to_str()
-                        .unwrap()
-                        .splitn(2, '.')
-                        .next()
-                        .unwrap();
+                    //
+                    // NB: We do not use file_stem() as some file names have multiple `.`s and we
+                    // must strip all of them.
+                    let testname =
+                        file_path.file_name().unwrap().to_str().unwrap().split_once('.').unwrap().0;
                     if !file_path.with_file_name(testname).with_extension("rs").exists() {
-                        println!("Stray file with UI testing output: {:?}", file_path);
-                        *bad = true;
+                        tidy_error!(bad, "Stray file with UI testing output: {:?}", file_path);
                     }
 
                     if let Ok(metadata) = fs::metadata(file_path) {
                         if metadata.len() == 0 {
-                            println!("Empty file with UI testing output: {:?}", file_path);
-                            *bad = true;
+                            tidy_error!(bad, "Empty file with UI testing output: {:?}", file_path);
                         }
                     }
                 }
diff --git a/src/tools/x/README.md b/src/tools/x/README.md
index 3b3cf2847c2..80bf02e8a0e 100644
--- a/src/tools/x/README.md
+++ b/src/tools/x/README.md
@@ -1,3 +1,10 @@
 # x
 
 `x` invokes `x.py` from any subdirectory.
+
+To install, run the following commands:
+
+```
+$ cd rust/src/tools/x/
+$ cargo install --path .
+```
diff --git a/src/version b/src/version
index 5a5c7211dc6..ba0a719118c 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.50.0
+1.51.0